@@ -103,17 +103,29 @@ def print_time(msg):
103103 print ("%s: %s" % (now .isoformat (), msg ))
104104
105105
106- def setup_tap_interface (tap_interface_name , tap_ip ):
106+ def setup_tap_interface (tap_interface_name , tap_ip , bridge_name ):
107107 # Setup tun tap interface if does not exist
108- tuntap_interfaces = subprocess .check_output (["ip" , 'tuntap' ])
108+ # sudo ip link delete fc_tap0 - this deletes the tap device
109+ tuntap_interfaces = subprocess .check_output (['ip' , 'tuntap' ])
109110 if tuntap_interfaces .find (tap_interface_name ) < 0 :
110- print ("The tap interface %s not found!. Needs to set it up" % tap_interface_name )
111+ print ("The tap interface %s not found -> needs to set it up!" % tap_interface_name )
112+ # Check if the bridge exists if user specified it
113+ if bridge_name :
114+ bridges = subprocess .check_output (['brctl' , 'show' ])
115+ if bridges .find (bridge_name ) < 0 :
116+ print ("The bridge %s does not exist per brctl. Please create one!" % bridge_name )
117+ exit (- 1 )
118+
111119 subprocess .call (['sudo' , 'ip' , 'tuntap' , 'add' , 'dev' , tap_interface_name , 'mode' , 'tap' ])
112- subprocess .call (['sudo' , 'sysctl' , '-w' , 'net.ipv4.conf.%s.proxy_arp=1' % tap_interface_name ])
113- subprocess .call (['sudo' , 'sysctl' , '-w' , 'net.ipv6.conf.%s.disable_ipv6=1' % tap_interface_name ])
114- subprocess .call (['sudo' , 'ip' , 'addr' , 'add' , '%s/30' % tap_ip , 'dev' , tap_interface_name ])
120+ subprocess .call (['sudo' , 'sysctl' , '-q' , '-w' , 'net.ipv4.conf.%s.proxy_arp=1' % tap_interface_name ])
121+ subprocess .call (['sudo' , 'sysctl' , '-q' , '-w' , 'net.ipv6.conf.%s.disable_ipv6=1' % tap_interface_name ])
115122 subprocess .call (['sudo' , 'ip' , 'link' , 'set' , 'dev' , tap_interface_name , 'up' ])
116123
124+ if bridge_name :
125+ subprocess .call (['sudo' , 'brctl' , 'addif' , bridge_name , tap_interface_name ])
126+ else :
127+ subprocess .call (['sudo' , 'ip' , 'addr' , 'add' , '%s/30' % tap_ip , 'dev' , tap_interface_name ])
128+
117129
118130def find_firecracker (dirname ):
119131 firecracker_path = os .path .join (dirname , '../.firecracker/firecracker' )
@@ -148,9 +160,9 @@ def find_firecracker(dirname):
148160 return firecracker_path
149161
150162
151- def disk_path (dirname ):
152- qcow_disk_path = os . path . join ( dirname , '../build/release/usr.img ' )
153- raw_disk_path = os . path . join ( dirname , '../build/release/usr. raw')
163+ def disk_path (qcow_disk_path ):
164+ dot_pos = qcow_disk_path . rfind ( '. ' )
165+ raw_disk_path = qcow_disk_path [ 0 : dot_pos ] + '. raw'
154166
155167 # Firecracker is not able to use disk image files in QCOW format
156168 # so we have to convert usr.img to raw format if the raw disk is missing
@@ -196,13 +208,30 @@ def main(options):
196208 firecracker = start_firecracker (firecracker_path , socket_path )
197209
198210 # Prepare arguments we are going to pass when creating VM instance
199- kernel_path = os .path .join (dirname , '../build/release/loader-stripped.elf' )
200- raw_disk_path = disk_path (dirname )
211+ kernel_path = options .kernel
212+ if not kernel_path :
213+ kernel_path = os .path .join (dirname , '../build/release/loader-stripped.elf' )
214+
215+ qemu_disk_path = options .image
216+ if not qemu_disk_path :
217+ qemu_disk_path = os .path .join (dirname , '../build/release/usr.img' )
218+ raw_disk_path = disk_path (qemu_disk_path )
201219
202220 cmdline = options .execute
203221 if not cmdline :
204222 with open (os .path .join (dirname , '../build/release/cmdline' ), 'r' ) as f :
205223 cmdline = f .read ()
224+ cmdline = "--nopci %s" % cmdline
225+
226+ if options .networking :
227+ tap_ip = '172.16.0.1'
228+ setup_tap_interface ('fc_tap0' , tap_ip , options .bridge )
229+ if not options .bridge :
230+ client_ip = '172.16.0.2'
231+ cmdline = '--ip=eth0,%s,255.255.255.252 --defaultgw=%s %s' % (client_ip , tap_ip , cmdline )
232+
233+ if options .verbose :
234+ cmdline = '--verbose ' + cmdline
206235
207236 # Create API client and make API calls
208237 client = ApiClient (socket_path .replace ("/" , "%2F" ))
@@ -223,15 +252,8 @@ def main(options):
223252 client .add_disk (raw_disk_path )
224253 print_time ("Added disk" )
225254
226- cmdline = "--nopci %s" % cmdline
227255 if options .networking :
228- tap_ip = '172.16.0.1'
229- setup_tap_interface ('fc_tap0' , tap_ip )
230256 client .add_network_interface ('eth0' , 'fc_tap0' )
231- client_ip = '172.16.0.2'
232- cmdline = '--ip=eth0,%s,255.255.255.252 --defaultgw=%s %s' % (client_ip , tap_ip , cmdline )
233- if options .verbose :
234- cmdline = '--verbose ' + cmdline
235257
236258 client .create_instance (kernel_path , cmdline )
237259 print_time ("Created OSv VM with cmdline: %s" % cmdline )
@@ -263,8 +285,14 @@ def main(options):
263285 help = "specify memory: ex. 1G, 2G, ..." )
264286 parser .add_argument ("-e" , "--execute" , action = "store" , default = None , metavar = "CMD" ,
265287 help = "overwrite command line" )
288+ parser .add_argument ("-i" , "--image" , action = "store" , default = None , metavar = "CMD" ,
289+ help = "path to disk image file. defaults to ../build/release/usr.img" )
290+ parser .add_argument ("-k" , "--kernel" , action = "store" , default = None , metavar = "CMD" ,
291+ help = "path to kernel loader file. defaults to ../build/release/loader-stripped.elf" )
266292 parser .add_argument ("-n" , "--networking" , action = "store_true" ,
267293 help = "needs root to setup tap networking first time" )
294+ parser .add_argument ("-b" , "--bridge" , action = "store" , default = None ,
295+ help = "bridge name for tap networking" )
268296 parser .add_argument ("-V" , "--verbose" , action = "store_true" ,
269297 help = "pass --verbose to OSv, to display more debugging information on the console" )
270298
0 commit comments