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 <brice@daysofwonder.com>
This commit is contained in:
Brice Figureau 2018-07-27 19:30:25 +02:00
parent f1f128c6dd
commit 02e5f70589
2 changed files with 76 additions and 22 deletions

View File

@ -22,9 +22,18 @@ stdio, providing interactive access to the VM.
The Virtualbox backend support configuring a persistent disk using the
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`.

View File

@ -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[<devicename>]")
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[<devicename>])[,[bridge|host]adapter=<interface>]")
if err := flags.Parse(args); err != nil {
log.Fatal("Unable to parse args")
@ -201,26 +238,34 @@ func runVbox(args []string) {
}
}
_, out, err = manage(vboxmanage, "modifyvm", name, "--nictype1", "virtio")
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 --nictype error: %v\n%s", err, out)
}
_, out, err = manage(vboxmanage, "modifyvm", name, "--nic1", *networking)
_, 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 *networking == "bridged" {
_, out, err = manage(vboxmanage, "modifyvm", name, "--bridgeadapter1", *bridgeadapter)
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, "--cableconnected1", "on")
_, 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
_ = os.Remove(consolePath)