diff --git a/builder/vmware/builder.go b/builder/vmware/builder.go index d8a8f27b6..413619f1e 100644 --- a/builder/vmware/builder.go +++ b/builder/vmware/builder.go @@ -239,6 +239,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &stepProvision{}, &stepShutdown{}, &stepCleanFiles{}, + &stepCompactDisk{}, } // Setup the state bag diff --git a/builder/vmware/driver.go b/builder/vmware/driver.go index d363aa001..2acf20adf 100644 --- a/builder/vmware/driver.go +++ b/builder/vmware/driver.go @@ -12,6 +12,9 @@ import ( // A driver is able to talk to VMware, control virtual machines, etc. type Driver interface { + // CompactDisk compacts a virtual disk. + CompactDisk(string) error + // CreateDisk creates a virtual disk with the given size. CreateDisk(string, string) error @@ -40,6 +43,20 @@ type Fusion5Driver struct { AppPath string } +func (d *Fusion5Driver) CompactDisk(diskPath string) error { + defragCmd := exec.Command(d.vdiskManagerPath(), "-d", diskPath) + if _, _, err := d.runAndLog(defragCmd); err != nil { + return err + } + + shrinkCmd := exec.Command(d.vdiskManagerPath(), "-k", diskPath) + if _, _, err := d.runAndLog(shrinkCmd); err != nil { + return err + } + + return nil +} + func (d *Fusion5Driver) CreateDisk(output string, size string) error { cmd := exec.Command(d.vdiskManagerPath(), "-c", "-s", size, "-a", "lsilogic", "-t", "1", output) if _, _, err := d.runAndLog(cmd); err != nil { diff --git a/builder/vmware/step_compact_disk.go b/builder/vmware/step_compact_disk.go new file mode 100644 index 000000000..1f0f49c76 --- /dev/null +++ b/builder/vmware/step_compact_disk.go @@ -0,0 +1,35 @@ +package vmware + +import ( + "fmt" + "github.com/mitchellh/multistep" + "github.com/mitchellh/packer/packer" +) + +// This step compacts the virtual disk for the VM. +// +// Uses: +// driver Driver +// ui packer.Ui +// +// Produces: +// +type stepCompactDisk struct{} + +func (stepCompactDisk) Run(state map[string]interface{}) multistep.StepAction { + driver := state["driver"].(Driver) + ui := state["ui"].(packer.Ui) + full_disk_path := state["full_disk_path"].(string) + + ui.Say("Compacting the disk image") + if err := driver.CompactDisk(full_disk_path); err != nil { + err := fmt.Errorf("Error compacting disk: %s", err) + state["error"] = err + ui.Error(err.Error()) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (stepCompactDisk) Cleanup(map[string]interface{}) {} diff --git a/builder/vmware/step_create_disk.go b/builder/vmware/step_create_disk.go index 7624224d0..e3fdc9272 100644 --- a/builder/vmware/step_create_disk.go +++ b/builder/vmware/step_create_disk.go @@ -24,8 +24,9 @@ func (stepCreateDisk) Run(state map[string]interface{}) multistep.StepAction { ui := state["ui"].(packer.Ui) ui.Say("Creating virtual machine disk") - output := filepath.Join(config.OutputDir, config.DiskName+".vmdk") - if err := driver.CreateDisk(output, fmt.Sprintf("%dM", config.DiskSize)); err != nil { + full_disk_path := filepath.Join(config.OutputDir, config.DiskName+".vmdk") + state["full_disk_path"] = full_disk_path + if err := driver.CreateDisk(full_disk_path, fmt.Sprintf("%dM", config.DiskSize)); err != nil { err := fmt.Errorf("Error creating disk: %s", err) state["error"] = err ui.Error(err.Error())