|
|
|
|
@ -4,17 +4,18 @@ import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
"path"
|
|
|
|
|
"regexp"
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"github.com/hashicorp/packer/packer"
|
|
|
|
|
"github.com/mitchellh/multistep"
|
|
|
|
|
"github.com/vmware/govmomi"
|
|
|
|
|
"github.com/vmware/govmomi/object"
|
|
|
|
|
"github.com/vmware/govmomi/vim25/types"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type stepMarkAsTemplate struct {
|
|
|
|
|
VMName string
|
|
|
|
|
Source string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction {
|
|
|
|
|
@ -32,34 +33,33 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction
|
|
|
|
|
return multistep.ActionHalt
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
host, err := vm.HostSystem(context.Background())
|
|
|
|
|
if err != nil {
|
|
|
|
|
if err := unregisterPreviousVM(cli, folder, s.VMName); err != nil {
|
|
|
|
|
state.Put("error", err)
|
|
|
|
|
ui.Error(err.Error())
|
|
|
|
|
return multistep.ActionHalt
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := vm.Unregister(context.Background()); err != nil {
|
|
|
|
|
path, err := datastorePath(vm, s.VMName)
|
|
|
|
|
if err != nil {
|
|
|
|
|
state.Put("error", err)
|
|
|
|
|
ui.Error(err.Error())
|
|
|
|
|
return multistep.ActionHalt
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
source := strings.Split(s.Source, "/vmfs/volumes/")[1]
|
|
|
|
|
i := strings.Index(source, "/")
|
|
|
|
|
|
|
|
|
|
path := (&object.DatastorePath{
|
|
|
|
|
Datastore: source[:i],
|
|
|
|
|
Path: source[i:],
|
|
|
|
|
}).String()
|
|
|
|
|
host, err := vm.HostSystem(context.Background())
|
|
|
|
|
if err != nil {
|
|
|
|
|
state.Put("error", err)
|
|
|
|
|
ui.Error(err.Error())
|
|
|
|
|
return multistep.ActionHalt
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := unregisterPreviousVM(cli, folder, s.VMName); err != nil {
|
|
|
|
|
if err := vm.Unregister(context.Background()); err != nil {
|
|
|
|
|
state.Put("error", err)
|
|
|
|
|
ui.Error(err.Error())
|
|
|
|
|
return multistep.ActionHalt
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
task, err := folder.RegisterVM(context.Background(), path, s.VMName, true, nil, host)
|
|
|
|
|
task, err := folder.RegisterVM(context.Background(), path.String(), s.VMName, true, nil, host)
|
|
|
|
|
if err != nil {
|
|
|
|
|
state.Put("error", err)
|
|
|
|
|
ui.Error(err.Error())
|
|
|
|
|
@ -75,6 +75,34 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction
|
|
|
|
|
return multistep.ActionContinue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func datastorePath(vm *object.VirtualMachine, name string) (*object.DatastorePath, error) {
|
|
|
|
|
devices, err := vm.Device(context.Background())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
disk := ""
|
|
|
|
|
for _, device := range devices {
|
|
|
|
|
if d, ok := device.(*types.VirtualDisk); ok {
|
|
|
|
|
if b, ok := d.Backing.(types.BaseVirtualDeviceFileBackingInfo); ok {
|
|
|
|
|
disk = b.GetVirtualDeviceFileBackingInfo().FileName
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if disk == "" {
|
|
|
|
|
return nil, fmt.Errorf("disk not found in '%v'", name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
re := regexp.MustCompile("\\[(.*?)\\]")
|
|
|
|
|
|
|
|
|
|
datastore := re.FindStringSubmatch(disk)[1]
|
|
|
|
|
vmx := path.Join("/", path.Dir(strings.Split(disk, " ")[1]), name+".vmx")
|
|
|
|
|
|
|
|
|
|
return &object.DatastorePath{datastore, vmx}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We will use the virtual machine created by vmware-iso builder
|
|
|
|
|
func findRuntimeVM(cli *govmomi.Client, dcPath, name string) (*object.VirtualMachine, error) {
|
|
|
|
|
si := object.NewSearchIndex(cli.Client)
|
|
|
|
|
|