diff --git a/cmds.go b/cmds.go index ddfaa1e..5723b9a 100644 --- a/cmds.go +++ b/cmds.go @@ -121,10 +121,18 @@ func cmdInit() int { return 1 } - if err := makeDiskImage(diskImg, B2D.DiskSize); err != nil { - logf("Failed to create disk image %q: %s", diskImg, err) - return 1 - } + if B2D.VMDK != "" { + logf("Using %v as base VMDK", B2D.VMDK) + if err := copyDiskImage(diskImg, B2D.VMDK); err != nil { + logf("Failed to copy disk image %v from %v: %s", diskImg, B2D.VMDK, err) + return 1 + } + } else { + if err := makeDiskImage(diskImg, B2D.DiskSize); err != nil { + logf("Failed to create disk image %q: %s", diskImg, err) + return 1 + } + } } if err := m.AttachStorage("SATA", vbx.StorageMedium{Port: 1, Device: 0, DriveType: vbx.DriveHDD, Medium: diskImg}); err != nil { diff --git a/config.go b/config.go index 25c859a..2b6ea9b 100644 --- a/config.go +++ b/config.go @@ -28,6 +28,7 @@ var B2D struct { VM string // virtual machine name Dir string // boot2docker directory ISO string // boot2docker ISO image path + VMDK string // base VMDK to use as persistent disk DiskSize uint // VM disk image size (MB) Memory uint // VM memory size (MB) @@ -106,6 +107,7 @@ func config() (*flag.FlagSet, error) { flags.StringVar(&B2D.VM, "vm", "boot2docker-vm", "virtual machine name.") flags.StringVarP(&B2D.Dir, "dir", "d", dir, "boot2docker config directory.") flags.StringVar(&B2D.ISO, "iso", filepath.Join(dir, "boot2docker.iso"), "path to boot2docker ISO image.") + flags.StringVar(&B2D.VMDK, "basevmdk", "", "Path to VMDK to use as base for persistent partition") vbm := "VBoxManage" if p := os.Getenv("VBOX_INSTALL_PATH"); p != "" && runtime.GOOS == "windows" { vbm = filepath.Join(p, "VBoxManage.exe") diff --git a/vbm.go b/vbm.go index 794b06f..962132f 100644 --- a/vbm.go +++ b/vbm.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "io" "os" "path/filepath" @@ -66,6 +67,33 @@ func getHostOnlyNetworkInterface() (string, error) { return hostonlyNet.Name, nil } +// Copy disk image from given source path to destination +func copyDiskImage(dst, src string) (err error) { + // Open source disk image + srcImg, err := os.Open(src) + if err != nil { + return err + } + closeSrcImg := func() { + if ee := srcImg.Close(); ee != nil { + err = ee + } + } + defer closeSrcImg() + dstImg, err := os.Create(dst) + if err != nil { + return err + } + closeDstImg := func() { + if ee := dstImg.Close(); ee != nil { + err = ee + } + } + defer closeDstImg() + _, err = io.Copy(dstImg, srcImg) + return err +} + // Make a boot2docker VM disk image with the given size (in MB). func makeDiskImage(dest string, size uint) error { // Create the dest dir.