From d05a601d00b9dc3301562d4c1f60c4362d034b07 Mon Sep 17 00:00:00 2001 From: Conrad Jones Date: Sun, 17 Jun 2018 01:38:42 +0100 Subject: [PATCH] Add support to vmware-vmx builder for linked clones. --- builder/qemu/step_run.go | 4 ++++ builder/vmware/common/driver.go | 2 +- builder/vmware/common/driver_fusion5.go | 2 +- builder/vmware/common/driver_fusion6.go | 2 +- builder/vmware/common/driver_mock.go | 4 +++- builder/vmware/common/driver_player5.go | 2 +- builder/vmware/common/driver_player6.go | 2 +- builder/vmware/common/driver_workstation10.go | 12 ++++++++++-- builder/vmware/common/driver_workstation9.go | 2 +- builder/vmware/iso/driver_esx5.go | 2 +- builder/vmware/vmx/builder.go | 1 + builder/vmware/vmx/config.go | 1 + builder/vmware/vmx/step_clone_vmx.go | 3 ++- website/source/docs/builders/vmware-vmx.html.md.erb | 3 +++ 14 files changed, 31 insertions(+), 11 deletions(-) diff --git a/builder/qemu/step_run.go b/builder/qemu/step_run.go index c524d5514..9769e7cd7 100644 --- a/builder/qemu/step_run.go +++ b/builder/qemu/step_run.go @@ -41,6 +41,7 @@ func (s *stepRun) Run(_ context.Context, state multistep.StateBag) multistep.Ste return multistep.ActionHalt } + ui.Message(fmt.Sprintf("command:=%s", command)) if err := driver.Qemu(command...); err != nil { err := fmt.Errorf("Error launching VM: %s", err) ui.Error(err.Error()) @@ -104,6 +105,9 @@ func getCommandArgs(bootDrive string, state multistep.StateBag) ([]string, error } else { driveArgs = append(driveArgs, fmt.Sprintf("file=%s,if=%s,cache=%s,format=%s", imgPath, config.DiskInterface, config.DiskCache, config.Format)) } + + ui.Message(fmt.Sprintf("config.NetDevice:=%s", config.NetDevice)) + deviceArgs = append(deviceArgs, fmt.Sprintf("%s,netdev=user.0", config.NetDevice)) if config.Headless == true { diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index 8ceb393ff..98b75faf5 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -23,7 +23,7 @@ type Driver interface { // Clone clones the VMX and the disk to the destination path. The // destination is a path to the VMX file. The disk will be copied // to that same directory. - Clone(dst string, src string) error + Clone(dst string, src string, cloneType bool) error // CompactDisk compacts a virtual disk. CompactDisk(string) error diff --git a/builder/vmware/common/driver_fusion5.go b/builder/vmware/common/driver_fusion5.go index 63211f99a..2599604b9 100644 --- a/builder/vmware/common/driver_fusion5.go +++ b/builder/vmware/common/driver_fusion5.go @@ -24,7 +24,7 @@ type Fusion5Driver struct { SSHConfig *SSHConfig } -func (d *Fusion5Driver) Clone(dst, src string) error { +func (d *Fusion5Driver) Clone(dst, src string, linked bool) error { return errors.New("Cloning is not supported with Fusion 5. Please use Fusion 6+.") } diff --git a/builder/vmware/common/driver_fusion6.go b/builder/vmware/common/driver_fusion6.go index 002d4227a..9e84ce3db 100644 --- a/builder/vmware/common/driver_fusion6.go +++ b/builder/vmware/common/driver_fusion6.go @@ -18,7 +18,7 @@ type Fusion6Driver struct { Fusion5Driver } -func (d *Fusion6Driver) Clone(dst, src string) error { +func (d *Fusion6Driver) Clone(dst, src string, linked bool) error { cmd := exec.Command(d.vmrunPath(), "-T", "fusion", "clone", src, dst, diff --git a/builder/vmware/common/driver_mock.go b/builder/vmware/common/driver_mock.go index 8c540913e..019b688fc 100644 --- a/builder/vmware/common/driver_mock.go +++ b/builder/vmware/common/driver_mock.go @@ -13,6 +13,7 @@ type DriverMock struct { CloneCalled bool CloneDst string CloneSrc string + Linked bool CloneErr error CompactDiskCalled bool @@ -107,10 +108,11 @@ func (m NetworkMapperMock) DeviceIntoName(device string) (string, error) { return "", nil } -func (d *DriverMock) Clone(dst string, src string) error { +func (d *DriverMock) Clone(dst string, src string, linked bool) error { d.CloneCalled = true d.CloneDst = dst d.CloneSrc = src + d.Linked = linked return d.CloneErr } diff --git a/builder/vmware/common/driver_player5.go b/builder/vmware/common/driver_player5.go index 5f492e6be..ccb1de2c2 100644 --- a/builder/vmware/common/driver_player5.go +++ b/builder/vmware/common/driver_player5.go @@ -25,7 +25,7 @@ type Player5Driver struct { SSHConfig *SSHConfig } -func (d *Player5Driver) Clone(dst, src string) error { +func (d *Player5Driver) Clone(dst, src string, linked bool) error { return errors.New("Cloning is not supported with VMWare Player version 5. Please use VMWare Player version 6, or greater.") } diff --git a/builder/vmware/common/driver_player6.go b/builder/vmware/common/driver_player6.go index 1ccb84b85..f0d57e51d 100644 --- a/builder/vmware/common/driver_player6.go +++ b/builder/vmware/common/driver_player6.go @@ -13,7 +13,7 @@ type Player6Driver struct { Player5Driver } -func (d *Player6Driver) Clone(dst, src string) error { +func (d *Player6Driver) Clone(dst, src string, linked bool) error { // TODO(rasa) check if running player+, not just player cmd := exec.Command(d.Player5Driver.VmrunPath, diff --git a/builder/vmware/common/driver_workstation10.go b/builder/vmware/common/driver_workstation10.go index 471fce37d..070df50c2 100644 --- a/builder/vmware/common/driver_workstation10.go +++ b/builder/vmware/common/driver_workstation10.go @@ -13,11 +13,19 @@ type Workstation10Driver struct { Workstation9Driver } -func (d *Workstation10Driver) Clone(dst, src string) error { +func (d *Workstation10Driver) Clone(dst, src string, linked bool) error { + + var cloneType string + if linked { + cloneType = "linked" + } else { + cloneType = "full" + } + cmd := exec.Command(d.Workstation9Driver.VmrunPath, "-T", "ws", "clone", src, dst, - "full") + cloneType) if _, _, err := runAndLog(cmd); err != nil { return err diff --git a/builder/vmware/common/driver_workstation9.go b/builder/vmware/common/driver_workstation9.go index 8186ac83f..50bf77f34 100644 --- a/builder/vmware/common/driver_workstation9.go +++ b/builder/vmware/common/driver_workstation9.go @@ -24,7 +24,7 @@ type Workstation9Driver struct { SSHConfig *SSHConfig } -func (d *Workstation9Driver) Clone(dst, src string) error { +func (d *Workstation9Driver) Clone(dst, src string, linked bool) error { return errors.New("Cloning is not supported with VMware WS version 9. Please use VMware WS version 10, or greater.") } diff --git a/builder/vmware/iso/driver_esx5.go b/builder/vmware/iso/driver_esx5.go index c31d8da95..b3eb8c078 100644 --- a/builder/vmware/iso/driver_esx5.go +++ b/builder/vmware/iso/driver_esx5.go @@ -41,7 +41,7 @@ type ESX5Driver struct { vmId string } -func (d *ESX5Driver) Clone(dst, src string) error { +func (d *ESX5Driver) Clone(dst, src string, linked bool) error { return errors.New("Cloning is not supported with the ESX driver.") } diff --git a/builder/vmware/vmx/builder.go b/builder/vmware/vmx/builder.go index 130c533d7..dbb74b7a1 100644 --- a/builder/vmware/vmx/builder.go +++ b/builder/vmware/vmx/builder.go @@ -69,6 +69,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe OutputDir: b.config.OutputDir, Path: b.config.SourcePath, VMName: b.config.VMName, + Linked: b.config.Linked, }, &vmwcommon.StepConfigureVMX{ CustomData: b.config.VMXData, diff --git a/builder/vmware/vmx/config.go b/builder/vmware/vmx/config.go index 0fb9993aa..1e32ac7b7 100644 --- a/builder/vmware/vmx/config.go +++ b/builder/vmware/vmx/config.go @@ -26,6 +26,7 @@ type Config struct { vmwcommon.ToolsConfig `mapstructure:",squash"` vmwcommon.VMXConfig `mapstructure:",squash"` + Linked bool `mapstructure:"linked"` RemoteType string `mapstructure:"remote_type"` SkipCompaction bool `mapstructure:"skip_compaction"` SourcePath string `mapstructure:"source_path"` diff --git a/builder/vmware/vmx/step_clone_vmx.go b/builder/vmware/vmx/step_clone_vmx.go index 9eebc0096..55c24d2a7 100644 --- a/builder/vmware/vmx/step_clone_vmx.go +++ b/builder/vmware/vmx/step_clone_vmx.go @@ -17,6 +17,7 @@ type StepCloneVMX struct { OutputDir string Path string VMName string + Linked bool } type vmxAdapter struct { @@ -64,7 +65,7 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste ui.Say("Cloning source VM...") log.Printf("Cloning from: %s", s.Path) log.Printf("Cloning to: %s", vmxPath) - if err := driver.Clone(vmxPath, s.Path); err != nil { + if err := driver.Clone(vmxPath, s.Path, s.Linked); err != nil { state.Put("error", err) return multistep.ActionHalt } diff --git a/website/source/docs/builders/vmware-vmx.html.md.erb b/website/source/docs/builders/vmware-vmx.html.md.erb index 90880cb54..03c144de9 100644 --- a/website/source/docs/builders/vmware-vmx.html.md.erb +++ b/website/source/docs/builders/vmware-vmx.html.md.erb @@ -137,6 +137,9 @@ builder. doesn't shut down in this time, it is an error. By default, the timeout is `5m` or five minutes. +- `linked` (boolean) - Virtual machine is created a linked clone. + Defaults to `false`. + - `skip_compaction` (boolean) - VMware-created disks are defragmented and compacted at the end of the build process using `vmware-vdiskmanager`. In certain rare cases, this might actually end up making the resulting disks