fix issue where -force is not working with vsphere builders (#9039)

* add better error support to check if vm exists use path.Join so that it looks up the VM correctly turn off VM if it is still running

* fix the vsphere-clone also

* add a common precleanvm to the driver to dedupe iso and clone logic, reduce the if nesting
This commit is contained in:
jhawk28 2020-04-23 08:07:07 -04:00 committed by GitHub
parent e0d2f4fd69
commit c43a52aafe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 27 deletions

View File

@ -6,6 +6,7 @@ package clone
import ( import (
"context" "context"
"fmt" "fmt"
"path"
"github.com/hashicorp/packer/builder/vsphere/common" "github.com/hashicorp/packer/builder/vsphere/common"
"github.com/hashicorp/packer/builder/vsphere/driver" "github.com/hashicorp/packer/builder/vsphere/driver"
@ -49,19 +50,12 @@ type StepCloneVM struct {
func (s *StepCloneVM) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { func (s *StepCloneVM) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(*driver.Driver) d := state.Get("driver").(*driver.Driver)
vmPath := fmt.Sprintf("%s/%s", s.Location.Folder, s.Location.VMName) vmPath := path.Join(s.Location.Folder, s.Location.VMName)
vm, err := d.FindVM(vmPath) err := d.PreCleanVM(ui, vmPath, s.Force)
if s.Force == false && err == nil {
state.Put("error", fmt.Errorf("%s already exists, you can use -force flag to destroy it", vmPath))
return multistep.ActionHalt
} else if s.Force == true && err == nil {
ui.Say(fmt.Sprintf("the vm/template %s already exists, but deleting it due to -force flag", vmPath))
err := vm.Destroy()
if err != nil { if err != nil {
state.Put("error", fmt.Errorf("error destroying %s: %v", vmPath, err)) state.Put("error", err)
} return multistep.ActionHalt
} }
ui.Say("Cloning VM...") ui.Say("Cloning VM...")
@ -71,7 +65,7 @@ func (s *StepCloneVM) Run(ctx context.Context, state multistep.StateBag) multist
return multistep.ActionHalt return multistep.ActionHalt
} }
vm, err = template.Clone(ctx, &driver.CloneConfig{ vm, err := template.Clone(ctx, &driver.CloneConfig{
Name: s.Location.VMName, Name: s.Location.VMName,
Folder: s.Location.Folder, Folder: s.Location.Folder,
Cluster: s.Location.Cluster, Cluster: s.Location.Cluster,

View File

@ -8,12 +8,13 @@ import (
"strings" "strings"
"time" "time"
"github.com/vmware/govmomi/property" "github.com/hashicorp/packer/packer"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/nfc" "github.com/vmware/govmomi/nfc"
"github.com/vmware/govmomi/ovf"
"github.com/vmware/govmomi/object" "github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/ovf"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types" "github.com/vmware/govmomi/vim25/types"
) )
@ -99,6 +100,31 @@ func (d *Driver) FindVM(name string) (*VirtualMachine, error) {
}, nil }, nil
} }
func (d *Driver) PreCleanVM(ui packer.Ui, vmPath string, force bool) error {
vm, err := d.FindVM(vmPath)
if err != nil {
if _, ok := err.(*find.NotFoundError); !ok {
return fmt.Errorf("error looking up old vm: %v", err)
}
}
if force && vm != nil {
ui.Say(fmt.Sprintf("the vm/template %s already exists, but deleting it due to -force flag", vmPath))
// power off just in case it is still on
vm.PowerOff()
err := vm.Destroy()
if err != nil {
return fmt.Errorf("error destroying %s: %v", vmPath, err)
}
}
if !force && vm != nil {
return fmt.Errorf("%s already exists, you can use -force flag to destroy it: %v", vmPath, err)
}
return nil
}
func (d *Driver) CreateVM(config *CreateConfig) (*VirtualMachine, error) { func (d *Driver) CreateVM(config *CreateConfig) (*VirtualMachine, error) {
createSpec := types.VirtualMachineConfigSpec{ createSpec := types.VirtualMachineConfigSpec{
Name: config.Name, Name: config.Name,

View File

@ -6,6 +6,7 @@ package iso
import ( import (
"context" "context"
"fmt" "fmt"
"path"
"github.com/hashicorp/packer/builder/vsphere/common" "github.com/hashicorp/packer/builder/vsphere/common"
"github.com/hashicorp/packer/builder/vsphere/driver" "github.com/hashicorp/packer/builder/vsphere/driver"
@ -131,19 +132,12 @@ type StepCreateVM struct {
func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(*driver.Driver) d := state.Get("driver").(*driver.Driver)
vmPath := fmt.Sprintf("%s/%s", s.Location.Folder, s.Location.VMName) vmPath := path.Join(s.Location.Folder, s.Location.VMName)
vm, err := d.FindVM(vmPath) err := d.PreCleanVM(ui, vmPath, s.Force)
if s.Force == false && err == nil {
state.Put("error", fmt.Errorf("%s already exists, you can use -force flag to destroy it: %v", vmPath, err))
return multistep.ActionHalt
} else if s.Force == true && err == nil {
ui.Say(fmt.Sprintf("the vm/template %s already exists, but deleting it due to -force flag", vmPath))
err := vm.Destroy()
if err != nil { if err != nil {
state.Put("error", fmt.Errorf("error destroying %s: %v", vmPath, err)) state.Put("error", err)
} return multistep.ActionHalt
} }
ui.Say("Creating VM...") ui.Say("Creating VM...")
@ -181,7 +175,7 @@ func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multiste
}) })
} }
vm, err = d.CreateVM(&driver.CreateConfig{ vm, err := d.CreateVM(&driver.CreateConfig{
DiskControllerType: s.Config.DiskControllerType, DiskControllerType: s.Config.DiskControllerType,
Storage: disks, Storage: disks,
Annotation: s.Config.Notes, Annotation: s.Config.Notes,