From 76e67c1d24e13ad0c7d0753cbf042b067f7c066c Mon Sep 17 00:00:00 2001 From: Isaac Boehman Date: Fri, 28 Mar 2014 17:17:09 -0400 Subject: [PATCH 1/5] Adds configuration option to specify base disk image to use for persistence Docker-DCO-1.1-Signed-off-by: Isaac Boehman (github: yacn) --- config.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config.go b/config.go index cc698fc..3de6d18 100644 --- a/config.go +++ b/config.go @@ -23,6 +23,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 persistant disk DiskSize uint // VM disk image size (MB) Memory uint // VM memory size (MB) @@ -103,6 +104,7 @@ func config() error { B2D.SSH = profile.Get("", "ssh", "ssh") B2D.VM = profile.Get("", "vm", "boot2docker-vm") B2D.ISO = profile.Get("", "iso", filepath.Join(B2D.Dir, "boot2docker.iso")) + B2D.VMDK = profile.Get("", "basevmdk", "") if diskSize, err := strconv.ParseUint(profile.Get("", "disksize", "20000"), 10, 32); err != nil { return fmt.Errorf("invalid disk image size: %s", err) @@ -141,6 +143,7 @@ func config() error { flag.StringVar(&B2D.SSH, "ssh", B2D.SSH, "Path to SSH client utility") flag.StringVarP(&B2D.Dir, "dir", "d", B2D.Dir, "boot2docker config directory") flag.StringVar(&B2D.ISO, "iso", B2D.ISO, "Path to boot2docker ISO image") + flag.StringVar(&B2D.VMDK, "basevmdk", B2D.VMDK, "Path of VMDK to use as base of persistent partition") flag.UintVarP(&B2D.DiskSize, "disksize", "s", B2D.DiskSize, "boot2docker disk image size (in MB)") flag.UintVarP(&B2D.Memory, "memory", "m", B2D.Memory, "Virtual machine memory size (in MB)") flag.Var(newUint16Value(B2D.SSHPort, &B2D.SSHPort), "sshport", "Host SSH port (forward to port 22 in VM)") From 39d91a02599535bd40492ea615d5eebe14ec2e4d Mon Sep 17 00:00:00 2001 From: Isaac Boehman Date: Fri, 28 Mar 2014 17:17:55 -0400 Subject: [PATCH 2/5] Adds check to cmdInit to see whether or not we need to copy a base disk image Docker-DCO-1.1-Signed-off-by: Isaac Boehman (github: yacn) --- cmds.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/cmds.go b/cmds.go index d7ceb59..bbc4e51 100644 --- a/cmds.go +++ b/cmds.go @@ -209,9 +209,17 @@ 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 len(B2D.VMDK) > 0 { + logf("Using %v as base disk image", 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 + } } } From aee9f0b46221e3d839c4eab0e4048a4bb3a731c9 Mon Sep 17 00:00:00 2001 From: Isaac Boehman Date: Fri, 28 Mar 2014 17:18:12 -0400 Subject: [PATCH 3/5] Adds helper to copy a disk image from destination to source Docker-DCO-1.1-Signed-off-by: Isaac Boehman (github: yacn) --- vbm.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/vbm.go b/vbm.go index b66559c..6b41c9e 100644 --- a/vbm.go +++ b/vbm.go @@ -3,6 +3,7 @@ package main import ( "fmt" "io" + "io/ioutil" "os" "os/exec" "path/filepath" @@ -170,6 +171,18 @@ func basefolder(vm string) string { return filepath.Dir(string(groups[1])) } +// Copy given disk image to destination from source +func copyDiskImage(dest, source string) error { + buf, err := ioutil.ReadFile(source) + if err != nil { + return err + } + if err := ioutil.WriteFile(dest, buf, 0600); err != nil { + return err + } + return nil +} + // Make a boot2docker VM disk image with the given size (in MB). func makeDiskImage(dest string, size uint) error { // Create the dest dir. From 480e8e106b66e63ab48572c084c0bc00f6ac653c Mon Sep 17 00:00:00 2001 From: Isaac Boehman Date: Fri, 28 Mar 2014 19:36:45 -0400 Subject: [PATCH 4/5] made changes more idi-gomatic Docker-DCO-1.1-Signed-off-by: Isaac Boehman (github: yacn) --- cmds.go | 2 +- vbm.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmds.go b/cmds.go index bbc4e51..a4f7cbc 100644 --- a/cmds.go +++ b/cmds.go @@ -209,7 +209,7 @@ func cmdInit() int { return 1 } - if len(B2D.VMDK) > 0 { + if B2D.VMDK != "" { logf("Using %v as base disk image", B2D.VMDK) if err := copyDiskImage(diskImg, B2D.VMDK); err != nil { logf("Failed to copy disk image %v from %v: %s", diskImg, B2D.VMDK, err) diff --git a/vbm.go b/vbm.go index 6b41c9e..863facd 100644 --- a/vbm.go +++ b/vbm.go @@ -172,7 +172,7 @@ func basefolder(vm string) string { } // Copy given disk image to destination from source -func copyDiskImage(dest, source string) error { +func copyDiskImage(dst, src string) error { buf, err := ioutil.ReadFile(source) if err != nil { return err From 01e5758cbe851ba1b21ff29b0927793a34c9df7a Mon Sep 17 00:00:00 2001 From: Isaac Boehman Date: Tue, 1 Apr 2014 11:49:10 -0400 Subject: [PATCH 5/5] Updates copyDiskImage() to copy in chunks Docker-DCO-1.1-Signed-off-by: Isaac Boehman (github: yacn) --- vbm.go | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/vbm.go b/vbm.go index 863facd..82e524b 100644 --- a/vbm.go +++ b/vbm.go @@ -3,7 +3,6 @@ package main import ( "fmt" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -171,15 +170,46 @@ func basefolder(vm string) string { return filepath.Dir(string(groups[1])) } -// Copy given disk image to destination from source +// Copy disk image from given source path to destination func copyDiskImage(dst, src string) error { - buf, err := ioutil.ReadFile(source) + // Open source disk image + srcImg, err := os.Open(src) if err != nil { return err } - if err := ioutil.WriteFile(dest, buf, 0600); err != nil { + defer func() error { + if err := srcImg.Close(); err != nil { + return err + } + return nil + }() + // Create and open destination + dstImg, err := os.Create(dst) + if err != nil { return err } + defer func() error { + if err := dstImg.Close(); err != nil { + return err + } + return nil + }() + // Buffer for chunks that've been read + buf := make([]byte, 1024) + for { + // Read a chunk + bytesRead, err := srcImg.Read(buf) + if err != nil && err != io.EOF { + return err + } + if bytesRead == 0 { + break + } + // Write a chunk + if _, err := dstImg.Write(buf[:bytesRead]); err != nil { + return err + } + } return nil }