@@ -103,17 +103,29 @@ def print_time(msg):
103
103
print ("%s: %s" % (now .isoformat (), msg ))
104
104
105
105
106
- def setup_tap_interface (tap_interface_name , tap_ip ):
106
+ def setup_tap_interface (tap_interface_name , tap_ip , bridge_name ):
107
107
# 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' ])
109
110
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
+
111
119
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 ])
115
122
subprocess .call (['sudo' , 'ip' , 'link' , 'set' , 'dev' , tap_interface_name , 'up' ])
116
123
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
+
117
129
118
130
def find_firecracker (dirname ):
119
131
firecracker_path = os .path .join (dirname , '../.firecracker/firecracker' )
@@ -148,9 +160,9 @@ def find_firecracker(dirname):
148
160
return firecracker_path
149
161
150
162
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'
154
166
155
167
# Firecracker is not able to use disk image files in QCOW format
156
168
# so we have to convert usr.img to raw format if the raw disk is missing
@@ -196,13 +208,30 @@ def main(options):
196
208
firecracker = start_firecracker (firecracker_path , socket_path )
197
209
198
210
# 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 )
201
219
202
220
cmdline = options .execute
203
221
if not cmdline :
204
222
with open (os .path .join (dirname , '../build/release/cmdline' ), 'r' ) as f :
205
223
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
206
235
207
236
# Create API client and make API calls
208
237
client = ApiClient (socket_path .replace ("/" , "%2F" ))
@@ -223,15 +252,8 @@ def main(options):
223
252
client .add_disk (raw_disk_path )
224
253
print_time ("Added disk" )
225
254
226
- cmdline = "--nopci %s" % cmdline
227
255
if options .networking :
228
- tap_ip = '172.16.0.1'
229
- setup_tap_interface ('fc_tap0' , tap_ip )
230
256
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
235
257
236
258
client .create_instance (kernel_path , cmdline )
237
259
print_time ("Created OSv VM with cmdline: %s" % cmdline )
@@ -263,8 +285,14 @@ def main(options):
263
285
help = "specify memory: ex. 1G, 2G, ..." )
264
286
parser .add_argument ("-e" , "--execute" , action = "store" , default = None , metavar = "CMD" ,
265
287
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" )
266
292
parser .add_argument ("-n" , "--networking" , action = "store_true" ,
267
293
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" )
268
296
parser .add_argument ("-V" , "--verbose" , action = "store_true" ,
269
297
help = "pass --verbose to OSv, to display more debugging information on the console" )
270
298
0 commit comments