Refactor vSphere driver

This commit is contained in:
Michael Kuzmin 2017-08-24 03:06:50 +03:00
parent 8d75c273a9
commit e8d8fd6205
15 changed files with 367 additions and 298 deletions

View File

@ -1,15 +1,14 @@
package main
import (
"github.com/vmware/govmomi/object"
"context"
"github.com/jetbrains-infra/packer-builder-vsphere/driver"
)
const BuilderId = "jetbrains.vsphere"
type Artifact struct {
Name string
VM *object.VirtualMachine
VM *driver.VirtualMachine
}
func (a *Artifact) BuilderId() string {
@ -33,11 +32,9 @@ func (a *Artifact) State(name string) interface{} {
}
func (a *Artifact) Destroy() error {
ctx := context.TODO()
task, err := a.VM.Destroy(ctx)
err := a.VM.Destroy()
if err != nil {
return err
}
_, err = task.WaitForResult(ctx, nil)
return err
return nil
}

View File

@ -9,7 +9,7 @@ import (
"github.com/hashicorp/packer/helper/communicator"
gossh "golang.org/x/crypto/ssh"
"github.com/hashicorp/packer/communicator/ssh"
"github.com/vmware/govmomi/object"
"github.com/jetbrains-infra/packer-builder-vsphere/driver"
)
type Builder struct {
@ -93,7 +93,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
artifact := &Artifact{
Name: b.config.VMName,
VM: state.Get("vm").(*object.VirtualMachine),
VM: state.Get("vm").(*driver.VirtualMachine),
}
return artifact, nil
}

View File

@ -7,7 +7,6 @@ import (
"github.com/hashicorp/packer/packer"
"encoding/json"
"math/rand"
"github.com/vmware/govmomi/object"
"github.com/jetbrains-infra/packer-builder-vsphere/driver"
)
@ -42,7 +41,7 @@ func checkDefault(t *testing.T, name string, host string) builderT.TestCheckFunc
d := testConn(t)
vm := getVM(t, d, artifacts)
vmInfo, err := d.VMInfo(vm, "name", "parent", "runtime.host", "resourcePool", "layoutEx.disk")
vmInfo, err := vm.Info("name", "parent", "runtime.host", "resourcePool", "layoutEx.disk")
if err != nil {
t.Fatalf("Cannot read VM properties: %v", err)
}
@ -52,7 +51,7 @@ func checkDefault(t *testing.T, name string, host string) builderT.TestCheckFunc
}
f := d.NewFolder(vmInfo.Parent)
folderPath, err := d.GetFolderPath(f)
folderPath, err := f.Path()
if err != nil {
t.Fatalf("Cannot read folder name: %v", err)
}
@ -61,7 +60,7 @@ func checkDefault(t *testing.T, name string, host string) builderT.TestCheckFunc
}
h := d.NewHost(vmInfo.Runtime.Host)
hostInfo, err := d.HostInfo(h, "name")
hostInfo, err := h.Info("name")
if err != nil {
t.Fatal("Cannot read host properties: ", err)
}
@ -71,7 +70,7 @@ func checkDefault(t *testing.T, name string, host string) builderT.TestCheckFunc
}
p := d.NewResourcePool(vmInfo.ResourcePool)
poolPath, err := d.GetResourcePoolPath(p)
poolPath, err := p.Path()
if err != nil {
t.Fatalf("Cannot read resource pool name: %v", err)
}
@ -132,13 +131,13 @@ func checkFolder(t *testing.T, folder string) builderT.TestCheckFunc {
d := testConn(t)
vm := getVM(t, d, artifacts)
vmInfo, err := d.VMInfo(vm, "parent")
vmInfo, err := vm.Info("parent")
if err != nil {
t.Fatalf("Cannot read VM properties: %v", err)
}
f := d.NewFolder(vmInfo.Parent)
path, err := d.GetFolderPath(f)
path, err := f.Path()
if err != nil {
t.Fatalf("Cannot read folder name: %v", err)
}
@ -170,13 +169,13 @@ func checkResourcePool(t *testing.T, pool string) builderT.TestCheckFunc {
d := testConn(t)
vm := getVM(t, d, artifacts)
vmInfo, err := d.VMInfo(vm, "resourcePool")
vmInfo, err := vm.Info("resourcePool")
if err != nil {
t.Fatalf("Cannot read VM properties: %v", err)
}
p := d.NewResourcePool(vmInfo.ResourcePool)
path, err := d.GetResourcePoolPath(p)
path, err := p.Path()
if err != nil {
t.Fatalf("Cannot read resource pool name: %v", err)
}
@ -207,7 +206,7 @@ func checkLinkedClone(t *testing.T) builderT.TestCheckFunc {
d := testConn(t)
vm := getVM(t, d, artifacts)
vmInfo, err := d.VMInfo(vm, "layoutEx.disk")
vmInfo, err := vm.Info("layoutEx.disk")
if err != nil {
t.Fatalf("Cannot read VM properties: %v", err)
}
@ -239,7 +238,7 @@ func checkSnapshot(t *testing.T) builderT.TestCheckFunc {
d := testConn(t)
vm := getVM(t, d, artifacts)
vmInfo, err := d.VMInfo(vm, "layoutEx.disk")
vmInfo, err := vm.Info("layoutEx.disk")
if err != nil {
t.Fatalf("Cannot read VM properties: %v", err)
}
@ -273,7 +272,7 @@ func checkTemplate(t *testing.T) builderT.TestCheckFunc {
d := testConn(t)
vm := getVM(t, d, artifacts)
vmInfo, err := d.VMInfo(vm, "config.template")
vmInfo, err := vm.Info("config.template")
if err != nil {
t.Fatalf("Cannot read VM properties: %v", err)
}
@ -315,7 +314,7 @@ func testConn(t *testing.T) *driver.Driver {
return d
}
func getVM(t *testing.T, d *driver.Driver, artifacts []packer.Artifact) *object.VirtualMachine {
func getVM(t *testing.T, d *driver.Driver, artifacts []packer.Artifact) *driver.VirtualMachine {
artifactRaw := artifacts[0]
artifact, _ := artifactRaw.(*Artifact)

21
driver/datastore.go Normal file
View File

@ -0,0 +1,21 @@
package driver
import (
"github.com/vmware/govmomi/object"
)
type Datastore struct {
ds *object.Datastore
driver *Driver
}
func (d *Driver) FindDatastore(name string) (*Datastore, error) {
ds, err := d.finder.Datastore(d.ctx, name)
if err != nil {
return nil, err
}
return &Datastore{
ds: ds,
driver: d,
}, nil
}

View File

@ -7,9 +7,6 @@ import (
"net/url"
"fmt"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"
"github.com/vmware/govmomi/vim25/mo"
"errors"
"time"
"github.com/vmware/govmomi/session"
"github.com/vmware/govmomi/vim25/soap"
@ -31,25 +28,6 @@ type ConnectConfig struct {
Datacenter string
}
type CloneConfig struct {
Template string
VMName string
Folder string
Host string
ResourcePool string
Datastore string
LinkedClone bool
}
type HardwareConfig struct {
CPUs int32
CPUReservation int64
CPULimit int64
RAM int64
RAMReservation int64
RAMReserveAll bool
}
func NewDriver(config *ConnectConfig) (*Driver, error) {
ctx := context.TODO()
@ -92,174 +70,3 @@ func NewDriver(config *ConnectConfig) (*Driver, error) {
}
return &d, nil
}
func (d *Driver) CloneVM(config *CloneConfig) (*object.VirtualMachine, error) {
template, err := d.finder.VirtualMachine(d.ctx, config.Template)
if err != nil {
return nil, err
}
folder, err := d.finder.FolderOrDefault(d.ctx, fmt.Sprintf("/%v/vm/%v", d.datacenter.Name(), config.Folder))
if err != nil {
return nil, err
}
var relocateSpec types.VirtualMachineRelocateSpec
pool, err := d.finder.ResourcePoolOrDefault(d.ctx, fmt.Sprintf("/%v/host/%v/Resources/%v", d.datacenter.Name(), config.Host, config.ResourcePool))
if err != nil {
return nil, err
}
poolRef := pool.Reference()
relocateSpec.Pool = &poolRef
if config.Datastore != "" {
datastore, err := d.finder.Datastore(d.ctx, config.Datastore)
if err != nil {
return nil, err
}
datastoreRef := datastore.Reference()
relocateSpec.Datastore = &datastoreRef
}
var cloneSpec types.VirtualMachineCloneSpec
cloneSpec.Location = relocateSpec
cloneSpec.PowerOn = false
if config.LinkedClone == true {
cloneSpec.Location.DiskMoveType = "createNewChildDiskBacking"
var tpl mo.VirtualMachine
err = template.Properties(d.ctx, template.Reference(), []string{"snapshot"}, &tpl)
if err != nil {
return nil, err
}
if tpl.Snapshot == nil {
err = errors.New("`linked_clone=true`, but template has no snapshots")
return nil, err
}
cloneSpec.Snapshot = tpl.Snapshot.CurrentSnapshot
}
task, err := template.Clone(d.ctx, folder, config.VMName, cloneSpec)
if err != nil {
return nil, err
}
info, err := task.WaitForResult(d.ctx, nil)
if err != nil {
return nil, err
}
vm := object.NewVirtualMachine(d.client.Client, info.Result.(types.ManagedObjectReference))
return vm, nil
}
func (d *Driver) DestroyVM(vm *object.VirtualMachine) error {
task, err := vm.Destroy(d.ctx)
if err != nil {
return err
}
_, err = task.WaitForResult(d.ctx, nil)
return err
}
func (d *Driver) ConfigureVM(vm *object.VirtualMachine, config *HardwareConfig) error {
var confSpec types.VirtualMachineConfigSpec
confSpec.NumCPUs = config.CPUs
confSpec.MemoryMB = config.RAM
var cpuSpec types.ResourceAllocationInfo
cpuSpec.Reservation = config.CPUReservation
cpuSpec.Limit = config.CPULimit
confSpec.CpuAllocation = &cpuSpec
var ramSpec types.ResourceAllocationInfo
ramSpec.Reservation = config.RAMReservation
confSpec.MemoryAllocation = &ramSpec
confSpec.MemoryReservationLockedToMax = &config.RAMReserveAll
task, err := vm.Reconfigure(d.ctx, confSpec)
if err != nil {
return err
}
_, err = task.WaitForResult(d.ctx, nil)
return err
}
func (d *Driver) PowerOn(vm *object.VirtualMachine) error {
task, err := vm.PowerOn(d.ctx)
if err != nil {
return err
}
_, err = task.WaitForResult(d.ctx, nil)
return err
}
func (d *Driver) WaitForIP(vm *object.VirtualMachine) (string, error) {
ip, err := vm.WaitForIP(d.ctx)
if err != nil {
return "", err
}
return ip, nil
}
func (d *Driver) PowerOff(vm *object.VirtualMachine) error {
state, err := vm.PowerState(d.ctx)
if err != nil {
return err
}
if state == types.VirtualMachinePowerStatePoweredOff {
return nil
}
task, err := vm.PowerOff(d.ctx)
if err != nil {
return err
}
_, err = task.WaitForResult(d.ctx, nil)
return err
}
func (d *Driver) StartShutdown(vm *object.VirtualMachine) error {
err := vm.ShutdownGuest(d.ctx)
return err
}
func (d *Driver) WaitForShutdown(vm *object.VirtualMachine, timeout time.Duration) error {
shutdownTimer := time.After(timeout)
for {
powerState, err := vm.PowerState(d.ctx)
if err != nil {
return err
}
if powerState == "poweredOff" {
break
}
select {
case <-shutdownTimer:
err := errors.New("Timeout while waiting for machine to shut down.")
return err
default:
time.Sleep(1 * time.Second)
}
}
return nil
}
func (d *Driver) CreateSnapshot(vm *object.VirtualMachine) error {
task, err := vm.CreateSnapshot(d.ctx, "Created by Packer", "", false, false)
if err != nil {
return err
}
_, err = task.WaitForResult(d.ctx, nil)
return err
}
func (d *Driver) ConvertToTemplate(vm *object.VirtualMachine) error {
err := vm.MarkAsTemplate(d.ctx)
return err
}

View File

@ -7,42 +7,61 @@ import (
"fmt"
)
func (d *Driver) NewFolder(ref *types.ManagedObjectReference) *object.Folder {
return object.NewFolder(d.client.Client, *ref)
type Folder struct {
driver *Driver
folder *object.Folder
}
func (d *Driver) FolderInfo(folder *object.Folder, params ...string) (*mo.Folder, error) {
func (d *Driver) NewFolder(ref *types.ManagedObjectReference) *Folder {
return &Folder{
folder: object.NewFolder(d.client.Client, *ref),
driver: d,
}
}
func (d *Driver) FindFolder(name string) (*Folder, error) {
f, err := d.finder.Folder(d.ctx, fmt.Sprintf("/%v/vm/%v", d.datacenter.Name(), name))
if err != nil {
return nil, err
}
return &Folder{
folder: f,
driver: d,
}, nil
}
func (f *Folder) Info(params ...string) (*mo.Folder, error) {
var p []string
if len(params) == 0 {
p = []string{"*"}
} else {
p = params
}
var folderInfo mo.Folder
err := folder.Properties(d.ctx, folder.Reference(), p, &folderInfo)
var info mo.Folder
err := f.folder.Properties(f.driver.ctx, f.folder.Reference(), p, &info)
if err != nil {
return nil, err
}
return &folderInfo, nil
return &info, nil
}
func (d *Driver) GetFolderPath(folder *object.Folder) (string, error) {
f, err := d.FolderInfo(folder, "name", "parent")
func (f *Folder) Path() (string, error) {
info, err := f.Info("name", "parent")
if err != nil {
return "", err
}
if f.Parent.Type == "Datacenter" {
if info.Parent.Type == "Datacenter" {
return "", nil
} else {
parent := d.NewFolder(f.Parent)
parentPath, err := d.GetFolderPath(parent)
parent := f.driver.NewFolder(info.Parent)
path, err := parent.Path()
if err != nil {
return "", err
}
if parentPath == "" {
return f.Name, nil
if path == "" {
return info.Name, nil
} else {
return fmt.Sprintf("%v/%v", parentPath, f.Name), nil
return fmt.Sprintf("%v/%v", path, info.Name), nil
}
}
}

View File

@ -2,25 +2,33 @@ package driver
import (
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"github.com/vmware/govmomi/vim25/mo"
)
func (d *Driver) NewHost(ref *types.ManagedObjectReference) *object.HostSystem {
return object.NewHostSystem(d.client.Client, *ref)
type Host struct {
driver *Driver
host *object.HostSystem
}
func (d *Driver) HostInfo(host *object.HostSystem, params ...string) (*mo.HostSystem, error){
func (d *Driver) NewHost(ref *types.ManagedObjectReference) *Host {
return &Host{
host: object.NewHostSystem(d.client.Client, *ref),
driver: d,
}
}
func (h *Host) Info(params ...string) (*mo.HostSystem, error){
var p []string
if len(params) == 0 {
p = []string{"*"}
} else {
p = params
}
var hostInfo mo.HostSystem
err := host.Properties(d.ctx, host.Reference(), p, &hostInfo)
var info mo.HostSystem
err := h.host.Properties(h.driver.ctx, h.host.Reference(), p, &info)
if err != nil {
return nil, err
}
return &hostInfo, nil
return &info, nil
}

View File

@ -2,47 +2,66 @@ package driver
import (
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"github.com/vmware/govmomi/vim25/mo"
"fmt"
)
func (d *Driver) NewResourcePool(ref *types.ManagedObjectReference) *object.ResourcePool {
return object.NewResourcePool(d.client.Client, *ref)
type ResourcePool struct {
pool *object.ResourcePool
driver *Driver
}
func (d *Driver) ResourcePoolInfo(host *object.ResourcePool, params ...string) (*mo.ResourcePool, error){
var p []string
if len(params) == 0 {
p = []string{"*"}
} else {
p = params
func (d *Driver) NewResourcePool(ref *types.ManagedObjectReference) *ResourcePool {
return &ResourcePool{
pool: object.NewResourcePool(d.client.Client, *ref),
driver: d,
}
var poolInfo mo.ResourcePool
err := host.Properties(d.ctx, host.Reference(), p, &poolInfo)
}
func (d *Driver) FindResourcePool(host string, name string) (*ResourcePool, error) {
p, err := d.finder.ResourcePool(d.ctx, fmt.Sprintf("/%v/host/%v/Resources/%v", d.datacenter.Name(), host, name))
if err != nil {
return nil, err
}
return &poolInfo, nil
return &ResourcePool{
pool: p,
driver: d,
}, nil
}
func (d *Driver) GetResourcePoolPath(pool *object.ResourcePool) (string, error) {
f, err := d.ResourcePoolInfo(pool, "name", "parent")
func (p *ResourcePool) Info(params ...string) (*mo.ResourcePool, error) {
var params2 []string
if len(params) == 0 {
params2 = []string{"*"}
} else {
params2 = params
}
var info mo.ResourcePool
err := p.pool.Properties(p.driver.ctx, p.pool.Reference(), params2, &info)
if err != nil {
return nil, err
}
return &info, nil
}
func (p *ResourcePool) Path() (string, error) {
poolInfo, err := p.Info("name", "parent")
if err != nil {
return "", err
}
if f.Parent.Type == "ComputeResource" {
if poolInfo.Parent.Type == "ComputeResource" {
return "", nil
} else {
parent := d.NewResourcePool(f.Parent)
parentPath, err := d.GetResourcePoolPath(parent)
parent := p.driver.NewResourcePool(poolInfo.Parent)
parentPath, err := parent.Path()
if err != nil {
return "", err
}
if parentPath == "" {
return f.Name, nil
return poolInfo.Name, nil
} else {
return fmt.Sprintf("%v/%v", parentPath, f.Name), nil
return fmt.Sprintf("%v/%v", parentPath, poolInfo.Name), nil
}
}
}

View File

@ -3,23 +3,229 @@ package driver
import (
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"errors"
"time"
)
func (d *Driver) FindVM(name string) (*object.VirtualMachine, error) {
return d.finder.VirtualMachine(d.ctx, name)
type VirtualMachine struct {
vm *object.VirtualMachine
driver *Driver
}
func (d *Driver) VMInfo(vm *object.VirtualMachine, params ...string) (*mo.VirtualMachine, error){
type CloneConfig struct {
Name string
Folder string
Host string
ResourcePool string
Datastore string
LinkedClone bool
}
type HardwareConfig struct {
CPUs int32
CPUReservation int64
CPULimit int64
RAM int64
RAMReservation int64
RAMReserveAll bool
}
func (d *Driver) NewVM(ref *types.ManagedObjectReference) *VirtualMachine {
return &VirtualMachine{
vm: object.NewVirtualMachine(d.client.Client, *ref),
driver: d,
}
}
func (d *Driver) FindVM(name string) (*VirtualMachine, error) {
vm, err := d.finder.VirtualMachine(d.ctx, name)
if err != nil {
return nil, err
}
return &VirtualMachine{
vm: vm,
driver: d,
}, nil
}
func (vm *VirtualMachine) Info(params ...string) (*mo.VirtualMachine, error) {
var p []string
if len(params) == 0 {
p = []string{"*"}
} else {
p = params
}
var vmInfo mo.VirtualMachine
err := vm.Properties(d.ctx, vm.Reference(), p, &vmInfo)
var info mo.VirtualMachine
err := vm.vm.Properties(vm.driver.ctx, vm.vm.Reference(), p, &info)
if err != nil {
return nil, err
}
return &vmInfo, nil
return &info, nil
}
func (template *VirtualMachine) Clone(config *CloneConfig) (*VirtualMachine, error) {
folder, err := template.driver.FindFolder(config.Folder)
if err != nil {
return nil, err
}
var relocateSpec types.VirtualMachineRelocateSpec
pool, err := template.driver.FindResourcePool(config.Host, config.ResourcePool)
if err != nil {
return nil, err
}
poolRef := pool.pool.Reference()
relocateSpec.Pool = &poolRef
if config.Datastore != "" {
datastore, err := template.driver.FindDatastore(config.Datastore)
if err != nil {
return nil, err
}
datastoreRef := datastore.ds.Reference()
relocateSpec.Datastore = &datastoreRef
}
var cloneSpec types.VirtualMachineCloneSpec
cloneSpec.Location = relocateSpec
cloneSpec.PowerOn = false
if config.LinkedClone == true {
cloneSpec.Location.DiskMoveType = "createNewChildDiskBacking"
tpl, err := template.Info("snapshot")
if err != nil {
return nil, err
}
if tpl.Snapshot == nil {
err = errors.New("`linked_clone=true`, but template has no snapshots")
return nil, err
}
cloneSpec.Snapshot = tpl.Snapshot.CurrentSnapshot
}
task, err := template.vm.Clone(template.driver.ctx, folder.folder, config.Name, cloneSpec)
if err != nil {
return nil, err
}
info, err := task.WaitForResult(template.driver.ctx, nil)
if err != nil {
return nil, err
}
ref := info.Result.(types.ManagedObjectReference)
vm := template.driver.NewVM(&ref)
return vm, nil
}
func (vm *VirtualMachine) Destroy() error {
task, err := vm.vm.Destroy(vm.driver.ctx)
if err != nil {
return err
}
_, err = task.WaitForResult(vm.driver.ctx, nil)
return err
}
func (vm *VirtualMachine) Configure(config *HardwareConfig) error {
var confSpec types.VirtualMachineConfigSpec
confSpec.NumCPUs = config.CPUs
confSpec.MemoryMB = config.RAM
var cpuSpec types.ResourceAllocationInfo
cpuSpec.Reservation = config.CPUReservation
cpuSpec.Limit = config.CPULimit
confSpec.CpuAllocation = &cpuSpec
var ramSpec types.ResourceAllocationInfo
ramSpec.Reservation = config.RAMReservation
confSpec.MemoryAllocation = &ramSpec
confSpec.MemoryReservationLockedToMax = &config.RAMReserveAll
task, err := vm.vm.Reconfigure(vm.driver.ctx, confSpec)
if err != nil {
return err
}
_, err = task.WaitForResult(vm.driver.ctx, nil)
return err
}
func (vm *VirtualMachine) PowerOn() error {
task, err := vm.vm.PowerOn(vm.driver.ctx)
if err != nil {
return err
}
_, err = task.WaitForResult(vm.driver.ctx, nil)
return err
}
func (vm *VirtualMachine) WaitForIP() (string, error) {
ip, err := vm.vm.WaitForIP(vm.driver.ctx)
if err != nil {
return "", err
}
return ip, nil
}
func (vm *VirtualMachine) PowerOff() error {
state, err := vm.vm.PowerState(vm.driver.ctx)
if err != nil {
return err
}
if state == types.VirtualMachinePowerStatePoweredOff {
return nil
}
task, err := vm.vm.PowerOff(vm.driver.ctx)
if err != nil {
return err
}
_, err = task.WaitForResult(vm.driver.ctx, nil)
return err
}
func (vm *VirtualMachine) StartShutdown() error {
err := vm.vm.ShutdownGuest(vm.driver.ctx)
return err
}
func (vm *VirtualMachine) WaitForShutdown(timeout time.Duration) error {
shutdownTimer := time.After(timeout)
for {
powerState, err := vm.vm.PowerState(vm.driver.ctx)
if err != nil {
return err
}
if powerState == "poweredOff" {
break
}
select {
case <-shutdownTimer:
err := errors.New("Timeout while waiting for machine to shut down.")
return err
default:
time.Sleep(1 * time.Second)
}
}
return nil
}
func (vm *VirtualMachine) CreateSnapshot(name string) error {
task, err := vm.vm.CreateSnapshot(vm.driver.ctx, name, "", false, false)
if err != nil {
return err
}
_, err = task.WaitForResult(vm.driver.ctx, nil)
return err
}
func (vm *VirtualMachine) ConvertToTemplate() error {
err := vm.vm.MarkAsTemplate(vm.driver.ctx)
return err
}

View File

@ -2,7 +2,6 @@ package main
import (
"github.com/mitchellh/multistep"
"github.com/vmware/govmomi/object"
"github.com/hashicorp/packer/packer"
"fmt"
"github.com/jetbrains-infra/packer-builder-vsphere/driver"
@ -44,9 +43,14 @@ func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction {
ui.Say("Cloning VM...")
vm, err := d.CloneVM(&driver.CloneConfig{
Template: s.config.Template,
VMName: s.config.VMName,
template, err := d.FindVM(s.config.Template)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
vm, err := template.Clone(&driver.CloneConfig{
Name: s.config.VMName,
Folder: s.config.Folder,
Host: s.config.Host,
ResourcePool: s.config.ResourcePool,
@ -69,15 +73,13 @@ func (s *StepCloneVM) Cleanup(state multistep.StateBag) {
return
}
if vm, ok := state.GetOk("vm"); ok {
ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(*driver.Driver)
ui := state.Get("ui").(packer.Ui)
vm := state.Get("vm").(*driver.VirtualMachine)
ui.Say("Destroying VM...")
ui.Say("Destroying VM...")
err := d.DestroyVM(vm.(*object.VirtualMachine))
if err != nil {
ui.Error(err.Error())
}
err := vm.Destroy()
if err != nil {
ui.Error(err.Error())
}
}

View File

@ -3,7 +3,6 @@ package main
import (
"github.com/mitchellh/multistep"
"github.com/hashicorp/packer/packer"
"github.com/vmware/govmomi/object"
"fmt"
"github.com/jetbrains-infra/packer-builder-vsphere/driver"
)
@ -33,13 +32,12 @@ type StepConfigureHardware struct {
func (s *StepConfigureHardware) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(*driver.Driver)
vm := state.Get("vm").(*object.VirtualMachine)
vm := state.Get("vm").(*driver.VirtualMachine)
if *s.config != (HardwareConfig{}) {
ui.Say("Customizing hardware parameters...")
err := d.ConfigureVM(vm, &driver.HardwareConfig{
err := vm.Configure(&driver.HardwareConfig{
CPUs: s.config.CPUs,
CPUReservation: s.config.CPUReservation,
CPULimit: s.config.CPULimit,

View File

@ -3,7 +3,6 @@ package main
import (
"github.com/mitchellh/multistep"
"github.com/hashicorp/packer/packer"
"github.com/vmware/govmomi/object"
"fmt"
"github.com/jetbrains-infra/packer-builder-vsphere/driver"
)
@ -13,18 +12,18 @@ type StepRun struct {
func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(*driver.Driver)
vm := state.Get("vm").(*object.VirtualMachine)
vm := state.Get("vm").(*driver.VirtualMachine)
ui.Say("Power on VM...")
err := d.PowerOn(vm)
err := vm.PowerOn()
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
ui.Say("Waiting for IP...")
ip, err := d.WaitForIP(vm)
ip, err := vm.WaitForIP()
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
@ -43,11 +42,11 @@ func (s *StepRun) Cleanup(state multistep.StateBag) {
}
ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(*driver.Driver)
vm := state.Get("vm").(*object.VirtualMachine)
vm := state.Get("vm").(*driver.VirtualMachine)
ui.Say("Power off VM...")
err := d.PowerOff(vm)
err := vm.PowerOff()
if err != nil {
ui.Error(err.Error())
}

View File

@ -3,7 +3,6 @@ package main
import (
"github.com/mitchellh/multistep"
"github.com/hashicorp/packer/packer"
"github.com/vmware/govmomi/object"
"fmt"
"log"
"time"
@ -41,8 +40,7 @@ type StepShutdown struct {
func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
comm := state.Get("communicator").(packer.Communicator)
d := state.Get("driver").(*driver.Driver)
vm := state.Get("vm").(*object.VirtualMachine)
vm := state.Get("vm").(*driver.VirtualMachine)
if s.config.Command != "" {
ui.Say("Executing shutdown command...")
@ -62,7 +60,7 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
} else {
ui.Say("Shut down VM...")
err := d.StartShutdown(vm)
err := vm.StartShutdown()
if err != nil {
state.Put("error", fmt.Errorf("Cannot shut down VM: %v", err))
return multistep.ActionHalt
@ -70,7 +68,7 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
}
log.Printf("Waiting max %s for shutdown to complete", s.config.Timeout)
err := d.WaitForShutdown(vm, s.config.Timeout)
err := vm.WaitForShutdown(s.config.Timeout)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt

View File

@ -3,7 +3,6 @@ package main
import (
"github.com/mitchellh/multistep"
"github.com/hashicorp/packer/packer"
"github.com/vmware/govmomi/object"
"github.com/jetbrains-infra/packer-builder-vsphere/driver"
)
@ -13,13 +12,12 @@ type StepCreateSnapshot struct{
func (s *StepCreateSnapshot) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(*driver.Driver)
vm := state.Get("vm").(*object.VirtualMachine)
vm := state.Get("vm").(*driver.VirtualMachine)
if s.createSnapshot {
ui.Say("Creating snapshot...")
err := d.CreateSnapshot(vm)
err := vm.CreateSnapshot("Created by Packer")
if err != nil {
state.Put("error", err)
return multistep.ActionHalt

View File

@ -3,7 +3,6 @@ package main
import (
"github.com/mitchellh/multistep"
"github.com/hashicorp/packer/packer"
"github.com/vmware/govmomi/object"
"github.com/jetbrains-infra/packer-builder-vsphere/driver"
)
@ -13,12 +12,11 @@ type StepConvertToTemplate struct{
func (s *StepConvertToTemplate) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(*driver.Driver)
vm := state.Get("vm").(*object.VirtualMachine)
vm := state.Get("vm").(*driver.VirtualMachine)
if s.ConvertToTemplate {
ui.Say("Convert VM into template...")
err := d.ConvertToTemplate(vm)
err := vm.ConvertToTemplate()
if err != nil {
state.Put("error", err)
return multistep.ActionHalt