This patch: - refactors firecracker.py to better handle error scenarios - adds ability to use external networking bridge through -b parameter (see scripts/setup-external-bridge.sh) - adds ability to specify custom location of kernel and image files
Signed-off-by: Waldemar Kozaczuk <[email protected]> --- scripts/firecracker.py | 64 ++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/scripts/firecracker.py b/scripts/firecracker.py index 825dd0c3..657956ea 100755 --- a/scripts/firecracker.py +++ b/scripts/firecracker.py @@ -103,17 +103,29 @@ def print_time(msg): print("%s: %s" % (now.isoformat(), msg)) -def setup_tap_interface(tap_interface_name, tap_ip): +def setup_tap_interface(tap_interface_name, tap_ip, bridge_name): # Setup tun tap interface if does not exist - tuntap_interfaces = subprocess.check_output(["ip", 'tuntap']) + # sudo ip link delete fc_tap0 - this deletes the tap device + tuntap_interfaces = subprocess.check_output(['ip', 'tuntap']) if tuntap_interfaces.find(tap_interface_name) < 0: - print("The tap interface %s not found!. Needs to set it up" % tap_interface_name) + print("The tap interface %s not found -> needs to set it up!" % tap_interface_name) + # Check if the bridge exists if user specified it + if bridge_name: + bridges = subprocess.check_output(['brctl', 'show']) + if bridges.find(bridge_name) < 0: + print("The bridge %s does not exist per brctl. Please create one!" % bridge_name) + exit(-1) + subprocess.call(['sudo', 'ip', 'tuntap', 'add', 'dev', tap_interface_name, 'mode', 'tap']) - subprocess.call(['sudo', 'sysctl', '-w', 'net.ipv4.conf.%s.proxy_arp=1' % tap_interface_name]) - subprocess.call(['sudo', 'sysctl', '-w', 'net.ipv6.conf.%s.disable_ipv6=1' % tap_interface_name]) - subprocess.call(['sudo', 'ip', 'addr', 'add', '%s/30' % tap_ip, 'dev', tap_interface_name]) + subprocess.call(['sudo', 'sysctl', '-q', '-w', 'net.ipv4.conf.%s.proxy_arp=1' % tap_interface_name]) + subprocess.call(['sudo', 'sysctl', '-q', '-w', 'net.ipv6.conf.%s.disable_ipv6=1' % tap_interface_name]) subprocess.call(['sudo', 'ip', 'link', 'set', 'dev', tap_interface_name, 'up']) + if bridge_name: + subprocess.call(['sudo', 'brctl', 'addif', bridge_name, tap_interface_name]) + else: + subprocess.call(['sudo', 'ip', 'addr', 'add', '%s/30' % tap_ip, 'dev', tap_interface_name]) + def find_firecracker(dirname): firecracker_path = os.path.join(dirname, '../.firecracker/firecracker') @@ -148,9 +160,9 @@ def find_firecracker(dirname): return firecracker_path -def disk_path(dirname): - qcow_disk_path = os.path.join(dirname, '../build/release/usr.img') - raw_disk_path = os.path.join(dirname, '../build/release/usr.raw') +def disk_path(qcow_disk_path): + dot_pos = qcow_disk_path.rfind('.') + raw_disk_path = qcow_disk_path[0:dot_pos] + '.raw' # Firecracker is not able to use disk image files in QCOW format # so we have to convert usr.img to raw format if the raw disk is missing @@ -196,13 +208,30 @@ def main(options): firecracker = start_firecracker(firecracker_path, socket_path) # Prepare arguments we are going to pass when creating VM instance - kernel_path = os.path.join(dirname, '../build/release/loader-stripped.elf') - raw_disk_path = disk_path(dirname) + kernel_path = options.kernel + if not kernel_path: + kernel_path = os.path.join(dirname, '../build/release/loader-stripped.elf') + + qemu_disk_path = options.image + if not qemu_disk_path: + qemu_disk_path = os.path.join(dirname, '../build/release/usr.img') + raw_disk_path = disk_path(qemu_disk_path) cmdline = options.execute if not cmdline: with open(os.path.join(dirname, '../build/release/cmdline'), 'r') as f: cmdline = f.read() + cmdline = "--nopci %s" % cmdline + + if options.networking: + tap_ip = '172.16.0.1' + setup_tap_interface('fc_tap0', tap_ip, options.bridge) + if not options.bridge: + client_ip = '172.16.0.2' + cmdline = '--ip=eth0,%s,255.255.255.252 --defaultgw=%s %s' % (client_ip, tap_ip, cmdline) + + if options.verbose: + cmdline = '--verbose ' + cmdline # Create API client and make API calls client = ApiClient(socket_path.replace("/", "%2F")) @@ -223,15 +252,8 @@ def main(options): client.add_disk(raw_disk_path) print_time("Added disk") - cmdline = "--nopci %s" % cmdline if options.networking: - tap_ip = '172.16.0.1' - setup_tap_interface('fc_tap0', tap_ip) client.add_network_interface('eth0', 'fc_tap0') - client_ip = '172.16.0.2' - cmdline = '--ip=eth0,%s,255.255.255.252 --defaultgw=%s %s' % (client_ip, tap_ip, cmdline) - if options.verbose: - cmdline = '--verbose ' + cmdline client.create_instance(kernel_path, cmdline) print_time("Created OSv VM with cmdline: %s" % cmdline) @@ -263,8 +285,14 @@ if __name__ == "__main__": help="specify memory: ex. 1G, 2G, ...") parser.add_argument("-e", "--execute", action="store", default=None, metavar="CMD", help="overwrite command line") + parser.add_argument("-i", "--image", action="store", default=None, metavar="CMD", + help="path to disk image file. defaults to ../build/release/usr.img") + parser.add_argument("-k", "--kernel", action="store", default=None, metavar="CMD", + help="path to kernel loader file. defaults to ../build/release/loader-stripped.elf") parser.add_argument("-n", "--networking", action="store_true", help="needs root to setup tap networking first time") + parser.add_argument("-b", "--bridge", action="store", default=None, + help="bridge name for tap networking") parser.add_argument("-V", "--verbose", action="store_true", help="pass --verbose to OSv, to display more debugging information on the console") -- 2.19.1 -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
