Code cleanup

This commit is contained in:
Michael Kuzmin 2017-07-02 23:29:50 +03:00
parent cadc320b72
commit 41744c3bcc
12 changed files with 72 additions and 98 deletions

View File

@ -48,8 +48,8 @@ Connection:
* `insecure_connection` - do not validate server's TLS certificate. `false` by default.
* `datacenter` - required if there are several datacenters.
Destination:
* `template` - [**mandatory**] name of source VM.
Location:
* `template` - [**mandatory**] name of source VM. Path is optional.
* `vm_name` - [**mandatory**] name of target VM.
* `folder` - VM folder where target VM is created.
* `host` - [**mandatory**] vSphere host where target VM is created.
@ -93,7 +93,7 @@ Post-processing:
"insecure_connection": true,
"datacenter": "dc1",
"template": "ubuntu",
"template": "folder/ubuntu",
"folder": "folder1/folder2",
"vm_name": "vm-1",
"host": "esxi-1.domain.com",

View File

@ -8,8 +8,8 @@ import (
const BuilderId = "jetbrains.vsphere"
type Artifact struct {
VMName string
Conn *object.VirtualMachine
Name string
VM *object.VirtualMachine
}
func (a *Artifact) BuilderId() string {
@ -21,11 +21,11 @@ func (a *Artifact) Files() []string {
}
func (a *Artifact) Id() string {
return a.VMName
return a.Name
}
func (a *Artifact) String() string {
return a.VMName
return a.Name
}
func (a *Artifact) State(name string) interface{} {
@ -34,14 +34,10 @@ func (a *Artifact) State(name string) interface{} {
func (a *Artifact) Destroy() error {
ctx := context.TODO()
task, err := a.Conn.Destroy(ctx)
task, err := a.VM.Destroy(ctx)
if err != nil {
return err
}
_, err = task.WaitForResult(ctx, nil)
if err != nil {
return err
}
return nil
return err
}

View File

@ -2,7 +2,6 @@ package main
import (
"errors"
"log"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/packer"
@ -93,15 +92,14 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
}
artifact := &Artifact{
VMName: b.config.VMName,
Conn: state.Get("vm").(*object.VirtualMachine),
Name: b.config.VMName,
VM: state.Get("vm").(*object.VirtualMachine),
}
return artifact, nil
}
func (b *Builder) Cancel() {
if b.runner != nil {
log.Println("Cancelling the step runner...")
b.runner.Cancel()
}
}

View File

@ -7,12 +7,10 @@ import (
func TestMinimalConfig(t *testing.T) {
_, warns, errs := NewConfig(minimalConfig())
testConfigOk(t, warns, errs)
}
func TestMandatoryParameters(t *testing.T) {
params := []string{"vcenter_server", "username", "password", "template", "vm_name", "host"}
for _, param := range params {
raw := minimalConfig()

View File

@ -16,27 +16,27 @@ import (
type Driver struct {
ctx context.Context
client *govmomi.Client
datacenter *object.Datacenter
finder *find.Finder
datacenter *object.Datacenter
}
func NewDriverVSphere(config *ConnectConfig) (Driver, error) {
func NewDriver(config *ConnectConfig) (*Driver, error) {
ctx := context.TODO()
vcenter_url, err := url.Parse(fmt.Sprintf("https://%v/sdk", config.VCenterServer))
if err != nil {
return Driver{}, err
return nil, err
}
vcenter_url.User = url.UserPassword(config.Username, config.Password)
client, err := govmomi.NewClient(ctx, vcenter_url, config.InsecureConnection)
if err != nil {
return Driver{}, err
return nil, err
}
finder := find.NewFinder(client.Client, false)
datacenter, err := finder.DatacenterOrDefault(ctx, config.Datacenter)
if err != nil {
return Driver{}, err
return nil, err
}
finder.SetDatacenter(datacenter)
@ -46,66 +46,58 @@ func NewDriverVSphere(config *ConnectConfig) (Driver, error) {
datacenter: datacenter,
finder: finder,
}
return d, nil
return &d, nil
}
func (d *Driver) cloneVM(config *CloneConfig) (*object.VirtualMachine, error) {
vmSrc, err := d.finder.VirtualMachine(d.ctx, config.Template)
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.FolderName))
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
var datastore *object.Datastore
if config.Datastore != "" {
datastore, err = d.finder.Datastore(d.ctx, config.Datastore)
datastore, err := d.finder.Datastore(d.ctx, config.Datastore)
if err != nil {
return nil, err
}
}
// Creating specs for cloning
relocateSpec := types.VirtualMachineRelocateSpec{
Pool: &(poolRef),
}
if datastore != nil {
datastoreRef := datastore.Reference()
relocateSpec.Datastore = &datastoreRef
}
if config.LinkedClone == true {
relocateSpec.DiskMoveType = "createNewChildDiskBacking"
}
cloneSpec := types.VirtualMachineCloneSpec{
Location: relocateSpec,
PowerOn: false,
}
var cloneSpec types.VirtualMachineCloneSpec
cloneSpec.Location = relocateSpec
cloneSpec.PowerOn = false
if config.LinkedClone == true {
var vmImage mo.VirtualMachine
err = vmSrc.Properties(d.ctx, vmSrc.Reference(), []string{"snapshot"}, &vmImage)
cloneSpec.Location.DiskMoveType = "createNewChildDiskBacking"
var tpl mo.VirtualMachine
err = template.Properties(d.ctx, template.Reference(), []string{"snapshot"}, &tpl)
if err != nil {
err = fmt.Errorf("Error reading base VM properties: %s", err)
return nil, err
}
if vmImage.Snapshot == nil {
err = errors.New("`linked_clone=true`, but image VM has no snapshots")
if tpl.Snapshot == nil {
err = errors.New("`linked_clone=true`, but template has no snapshots")
return nil, err
}
cloneSpec.Snapshot = vmImage.Snapshot.CurrentSnapshot
cloneSpec.Snapshot = tpl.Snapshot.CurrentSnapshot
}
// Cloning itself
task, err := vmSrc.Clone(d.ctx, folder, config.VMName, cloneSpec)
task, err := template.Clone(d.ctx, folder, config.VMName, cloneSpec)
if err != nil {
return nil, err
}
@ -115,23 +107,20 @@ func (d *Driver) cloneVM(config *CloneConfig) (*object.VirtualMachine, error) {
return nil, err
}
vm := object.NewVirtualMachine(vmSrc.Client(), info.Result.(types.ManagedObjectReference))
vm := object.NewVirtualMachine(d.client.Client, info.Result.(types.ManagedObjectReference))
return vm, nil
}
func (d *Driver) destroyVM(vm *object.VirtualMachine) error {
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)
if err != nil {
return err
}
return nil
return err
}
func (d *Driver) configureVM(vm *object.VirtualMachine, config *HardwareConfig) error {
func (d *Driver) ConfigureVM(vm *object.VirtualMachine, config *HardwareConfig) error {
var confSpec types.VirtualMachineConfigSpec
confSpec.NumCPUs = config.CPUs
confSpec.MemoryMB = config.RAM
@ -152,23 +141,16 @@ func (d *Driver) configureVM(vm *object.VirtualMachine, config *HardwareConfig)
return err
}
_, err = task.WaitForResult(d.ctx, nil)
if err != nil {
return err
}
return nil
return err
}
func (d *Driver) powerOn(vm *object.VirtualMachine) error {
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)
if err != nil {
return err
}
return nil
return err
}
func (d *Driver) WaitForIP(vm *object.VirtualMachine) (string, error) {
@ -179,7 +161,7 @@ func (d *Driver) WaitForIP(vm *object.VirtualMachine) (string, error) {
return ip, nil
}
func (d *Driver) powerOff(vm *object.VirtualMachine) error {
func (d *Driver) PowerOff(vm *object.VirtualMachine) error {
state, err := vm.PowerState(d.ctx)
if err != nil {
return err

View File

@ -9,8 +9,8 @@ import (
type CloneConfig struct {
Template string `mapstructure:"template"`
FolderName string `mapstructure:"folder"`
VMName string `mapstructure:"vm_name"`
Folder string `mapstructure:"folder"`
Host string `mapstructure:"host"`
ResourcePool string `mapstructure:"resource_pool"`
Datastore string `mapstructure:"datastore"`
@ -38,12 +38,12 @@ type StepCloneVM struct {
}
func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction {
d := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(*Driver)
ui.Say("Cloning VM...")
vm, err := d.cloneVM(s.config)
vm, err := d.CloneVM(s.config)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
@ -61,12 +61,12 @@ func (s *StepCloneVM) Cleanup(state multistep.StateBag) {
}
if vm, ok := state.GetOk("vm"); ok {
d := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(*Driver)
ui.Say("Destroying VM...")
err := d.destroyVM(vm.(*object.VirtualMachine))
err := d.DestroyVM(vm.(*object.VirtualMachine))
if err != nil {
ui.Error(err.Error())
}

View File

@ -7,10 +7,10 @@ import (
type ConnectConfig struct {
VCenterServer string `mapstructure:"vcenter_server"`
Datacenter string `mapstructure:"datacenter"`
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
InsecureConnection bool `mapstructure:"insecure_connection"`
Datacenter string `mapstructure:"datacenter"`
}
func (c *ConnectConfig) Prepare() []error {
@ -34,7 +34,7 @@ type StepConnect struct {
}
func (s *StepConnect) Run(state multistep.StateBag) multistep.StepAction {
driver, err := NewDriverVSphere(s.config)
driver, err := NewDriver(s.config)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt

View File

@ -31,14 +31,14 @@ type StepConfigureHardware struct {
}
func (s *StepConfigureHardware) Run(state multistep.StateBag) multistep.StepAction {
d := state.Get("driver").(Driver)
vm := state.Get("vm").(*object.VirtualMachine)
ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(*Driver)
vm := state.Get("vm").(*object.VirtualMachine)
if *s.config != (HardwareConfig{}) {
ui.Say("Customizing hardware parameters...")
err := d.configureVM(vm, s.config)
err := d.ConfigureVM(vm, s.config)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt

View File

@ -8,16 +8,15 @@ import (
)
type StepRun struct {
// TODO: add boot time to provide a proper timeout during cleanup
}
func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction {
d := state.Get("driver").(Driver)
vm := state.Get("vm").(*object.VirtualMachine)
ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(*Driver)
vm := state.Get("vm").(*object.VirtualMachine)
ui.Say("Power on VM...")
err := d.powerOn(vm)
err := d.PowerOn(vm)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
@ -38,17 +37,17 @@ func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction {
func (s *StepRun) Cleanup(state multistep.StateBag) {
_, cancelled := state.GetOk(multistep.StateCancelled)
_, halted := state.GetOk(multistep.StateHalted)
if !cancelled && !halted {
return
}
if cancelled || halted {
d := state.Get("driver").(Driver)
vm := state.Get("vm").(*object.VirtualMachine)
ui := state.Get("ui").(packer.Ui)
ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(*Driver)
vm := state.Get("vm").(*object.VirtualMachine)
ui.Say("Power off VM...")
err := d.powerOff(vm)
if err != nil {
ui.Error(err.Error())
return
}
ui.Say("Power off VM...")
err := d.PowerOff(vm)
if err != nil {
ui.Error(err.Error())
}
}

View File

@ -40,7 +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)
d := state.Get("driver").(*Driver)
vm := state.Get("vm").(*object.VirtualMachine)
if s.config.Command != "" {
@ -53,7 +53,8 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
Stdout: &stdout,
Stderr: &stderr,
}
if err := comm.Start(cmd); err != nil {
err := comm.Start(cmd)
if err != nil {
state.Put("error", fmt.Errorf("Failed to send shutdown command: %s", err))
return multistep.ActionHalt
}

View File

@ -12,7 +12,7 @@ type StepCreateSnapshot struct{
func (s *StepCreateSnapshot) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(Driver)
d := state.Get("driver").(*Driver)
vm := state.Get("vm").(*object.VirtualMachine)
if s.createSnapshot {

View File

@ -12,7 +12,7 @@ type StepConvertToTemplate struct{
func (s *StepConvertToTemplate) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
d := state.Get("driver").(Driver)
d := state.Get("driver").(*Driver)
vm := state.Get("vm").(*object.VirtualMachine)
if s.ConvertToTemplate {