Merge pull request #3148 from masterzen/fix/3140-vbox-multiple-disks

Enhance `run vbox` to support multiple disks and network adapters
This commit is contained in:
Justin Cormack 2018-08-02 11:26:02 +01:00 committed by GitHub
commit ccf7ac8081
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 84 additions and 23 deletions

View File

@ -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`.

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")
@ -171,6 +208,13 @@ func runVbox(args []string) {
}
}
if len(disks) > 0 {
_, out, err = manage(vboxmanage, "storagectl", name, "--name", "SATA", "--add", "sata")
if err != nil {
log.Fatalf("storagectl error: %v\n%s", err, out)
}
}
for i, d := range disks {
id := strconv.Itoa(i)
if d.Size != 0 && d.Format == "" {
@ -188,31 +232,39 @@ func runVbox(args []string) {
log.Fatalf("Cannot create disk: %v", err)
}
}
_, out, err = manage(vboxmanage, "storageattach", name, "--storagectl", "IDE Controller", "--port", "2", "--device", id, "--type", "hdd", "--medium", d.Path)
_, out, err = manage(vboxmanage, "storageattach", name, "--storagectl", "SATA", "--port", "0", "--device", id, "--type", "hdd", "--medium", d.Path)
if err != nil {
log.Fatalf("storageattach error: %v\n%s", err, out)
}
}
_, 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