From 02e5f705897a2fc9f8e4a941fb5f6bb30a30c060 Mon Sep 17 00:00:00 2001 From: Brice Figureau Date: Fri, 27 Jul 2018 19:30:25 +0200 Subject: [PATCH] Allow to specify more than one networking adapter for vbox Note: this patch introduces an incompatibility in the `linuxkit run vbox` arguments. It wasn't impossible to specify more than one network adapter to the `linuxkit run vbox` command. This patch allows to specify more than one `-networking` argument to specify different network adapters. For instance: ~~~sh linuxkit run vbox -networking type=nat -networking type=hostonly,adapter=vboxnet0 ~~~ will setup the VM with 2 NICs. It is also possible to get rid of the `type` argument. Signed-off-by: Brice Figureau --- docs/platform-vbox.md | 17 ++++++-- src/cmd/linuxkit/run_vbox.go | 81 ++++++++++++++++++++++++++++-------- 2 files changed, 76 insertions(+), 22 deletions(-) diff --git a/docs/platform-vbox.md b/docs/platform-vbox.md index 4b1fb86ca..f5f6ce12f 100644 --- a/docs/platform-vbox.md +++ b/docs/platform-vbox.md @@ -20,11 +20,20 @@ stdio, providing interactive access to the VM. ## Disks The Virtualbox backend support configuring a persistent disk using the -standard `linuxkit` `-disk` syntax. Multiple disks are +standard `linuxkit` `-disk` syntax. Multiple disks are supported and can be created in `raw` format; other formats that VirtualBox -supports can be attached +supports can be attached. Note that additional drives are attached to the +SATA Controller, unlike the VM disk which is on the IDE Controller. ## Networking -You can select the networking mode, which defaults to the standard `nat`, but -some networking modes may require additional configuration. +You can select the networking mode, which defaults to the standard `nat`, by using the +`-networking` command-line option. Some networking modes (`hostonly`, `bridge`) will require +the additional `adapter` parameter to the `-networking` option: + +~~~ +-networking hostonly,adapter=vboxnet0 +~~~ + +You can specify more than one `-networking` option to setup multiple adapters. It is +recommended to setup the first adapter as `nat`. diff --git a/src/cmd/linuxkit/run_vbox.go b/src/cmd/linuxkit/run_vbox.go index 70d2fdeac..5e04cbe47 100644 --- a/src/cmd/linuxkit/run_vbox.go +++ b/src/cmd/linuxkit/run_vbox.go @@ -17,6 +17,43 @@ import ( log "github.com/sirupsen/logrus" ) +// VBNetwork is the config for a Virtual Box network +type VBNetwork struct { + Type string + Adapter string +} + +// VBNetworks is the type for a list of VBNetwork +type VBNetworks []VBNetwork + +func (l *VBNetworks) String() string { + return fmt.Sprint(*l) +} + +// Set is used by flag to configure value from CLI +func (l *VBNetworks) Set(value string) error { + d := VBNetwork{} + s := strings.Split(value, ",") + for _, p := range s { + c := strings.SplitN(p, "=", 2) + switch len(c) { + case 1: + d.Type = c[0] + case 2: + switch c[0] { + case "type": + d.Type = c[1] + case "adapter", "bridgeadapter", "hostadapter": + d.Adapter = c[1] + default: + return fmt.Errorf("Unknown network config: %s", c[0]) + } + } + } + *l = append(*l, d) + return nil +} + func runVbox(args []string) { invoked := filepath.Base(os.Args[0]) flags := flag.NewFlagSet("vbox", flag.ExitOnError) @@ -51,8 +88,8 @@ func runVbox(args []string) { uefiBoot := flags.Bool("uefi", false, "Use UEFI boot") // networking - networking := flags.String("networking", "nat", "Networking mode. null|nat|bridged|intnet|hostonly|generic|natnetwork[]") - bridgeadapter := flags.String("bridgeadapter", "", "Bridge adapter interface to use if networking mode is bridged") + var networks VBNetworks + flags.Var(&networks, "networking", "Network config, may be repeated. [type=](null|nat|bridged|intnet|hostonly|generic|natnetwork[])[,[bridge|host]adapter=]") if err := flags.Parse(args); err != nil { log.Fatal("Unable to parse args") @@ -201,25 +238,33 @@ func runVbox(args []string) { } } - _, out, err = manage(vboxmanage, "modifyvm", name, "--nictype1", "virtio") - if err != nil { - log.Fatalf("modifyvm --nictype error: %v\n%s", err, out) - } - - _, out, err = manage(vboxmanage, "modifyvm", name, "--nic1", *networking) - if err != nil { - log.Fatalf("modifyvm --nic error: %v\n%s", err, out) - } - if *networking == "bridged" { - _, out, err = manage(vboxmanage, "modifyvm", name, "--bridgeadapter1", *bridgeadapter) + for i, d := range networks { + nic := i + 1 + _, out, err = manage(vboxmanage, "modifyvm", name, fmt.Sprintf("--nictype%d", nic), "virtio") if err != nil { - log.Fatalf("modifyvm --bridgeadapter error: %v\n%s", err, out) + log.Fatalf("modifyvm --nictype error: %v\n%s", err, out) } - } - _, out, err = manage(vboxmanage, "modifyvm", name, "--cableconnected1", "on") - if err != nil { - log.Fatalf("modifyvm --cableconnected error: %v\n%s", err, out) + _, out, err = manage(vboxmanage, "modifyvm", name, fmt.Sprintf("--nic%d", nic), d.Type) + if err != nil { + log.Fatalf("modifyvm --nic error: %v\n%s", err, out) + } + if d.Type == "hostonly" { + _, out, err = manage(vboxmanage, "modifyvm", name, fmt.Sprintf("--hostonlyadapter%d", nic), d.Adapter) + if err != nil { + log.Fatalf("modifyvm --hostonlyadapter error: %v\n%s", err, out) + } + } else if d.Type == "bridged" { + _, out, err = manage(vboxmanage, "modifyvm", name, fmt.Sprintf("--bridgeadapter%d", nic), d.Adapter) + if err != nil { + log.Fatalf("modifyvm --bridgeadapter error: %v\n%s", err, out) + } + } + + _, out, err = manage(vboxmanage, "modifyvm", name, fmt.Sprintf("--cableconnected%d", nic), "on") + if err != nil { + log.Fatalf("modifyvm --cableconnected error: %v\n%s", err, out) + } } // create socket