extract vSphere driver

This commit is contained in:
Michael Kuzmin 2017-07-02 06:46:38 +03:00
parent 9f93e93c92
commit 1e747c8c93
9 changed files with 78 additions and 64 deletions

View File

@ -10,7 +10,6 @@ import (
"github.com/hashicorp/packer/helper/communicator"
gossh "golang.org/x/crypto/ssh"
"github.com/hashicorp/packer/communicator/ssh"
"context"
"github.com/vmware/govmomi/object"
)
@ -33,7 +32,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
state := new(multistep.BasicStateBag)
state.Put("hook", hook)
state.Put("ui", ui)
state.Put("ctx", context.TODO())
steps := []multistep.Step{
&StepConnect{

46
driver.go Normal file
View File

@ -0,0 +1,46 @@
package main
import (
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/find"
"context"
"net/url"
"fmt"
"github.com/vmware/govmomi/object"
)
type Driver struct {
ctx context.Context
client *govmomi.Client
datacenter *object.Datacenter
finder *find.Finder
}
func NewDriverVSphere(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
}
vcenter_url.User = url.UserPassword(config.Username, config.Password)
client, err := govmomi.NewClient(ctx, vcenter_url, config.InsecureConnection)
if err != nil {
return Driver{}, err
}
finder := find.NewFinder(client.Client, false)
datacenter, err := finder.DatacenterOrDefault(ctx, config.Datacenter)
if err != nil {
return Driver{}, err
}
finder.SetDatacenter(datacenter)
d := Driver{
ctx: ctx,
client: client,
datacenter: datacenter,
finder: finder,
}
return d, nil
}

View File

@ -6,7 +6,6 @@ import (
"github.com/vmware/govmomi/vim25/types"
"github.com/vmware/govmomi/object"
"github.com/hashicorp/packer/packer"
"github.com/vmware/govmomi/find"
"fmt"
"github.com/vmware/govmomi/vim25/mo"
"errors"
@ -49,39 +48,37 @@ type CloneParameters struct {
}
type StepCloneVM struct {
config *CloneConfig
config *CloneConfig
}
func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction {
ctx := state.Get("ctx").(context.Context)
finder := state.Get("finder").(*find.Finder)
datacenter := state.Get("datacenter").(*object.Datacenter)
d := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
vmSrc, err := finder.VirtualMachine(ctx, s.config.Template)
vmSrc, err := d.finder.VirtualMachine(d.ctx, s.config.Template)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
state.Put("vmSrc", vmSrc)
ui.Say("start cloning...")
ui.Say("Cloning VM...")
folder, err := finder.FolderOrDefault(ctx, fmt.Sprintf("/%v/vm/%v", datacenter.Name(), s.config.FolderName))
folder, err := d.finder.FolderOrDefault(d.ctx, fmt.Sprintf("/%v/vm/%v", d.datacenter.Name(), s.config.FolderName))
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
pool, err := finder.ResourcePoolOrDefault(ctx, fmt.Sprintf("/%v/host/%v/Resources/%v", datacenter.Name(), s.config.Host, s.config.ResourcePool))
pool, err := d.finder.ResourcePoolOrDefault(d.ctx, fmt.Sprintf("/%v/host/%v/Resources/%v", d.datacenter.Name(), s.config.Host, s.config.ResourcePool))
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
var datastore *object.Datastore = nil
var datastore *object.Datastore
if s.config.Datastore != "" {
datastore, err = finder.Datastore(ctx, s.config.Datastore)
datastore, err = d.finder.Datastore(d.ctx, s.config.Datastore)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
@ -89,7 +86,7 @@ func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction {
}
vm, err := cloneVM(&CloneParameters{
ctx: ctx,
ctx: d.ctx,
vmSrc: vmSrc,
vmName: s.config.VMName,
folder: folder,
@ -114,17 +111,17 @@ func (s *StepCloneVM) Cleanup(state multistep.StateBag) {
}
if vm, ok := state.GetOk("vm"); ok {
ctx := state.Get("ctx").(context.Context)
d := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
ui.Say("Destroying VM...")
task, err := vm.(*object.VirtualMachine).Destroy(ctx)
task, err := vm.(*object.VirtualMachine).Destroy(d.ctx)
if err != nil {
ui.Error(err.Error())
return
}
_, err = task.WaitForResult(ctx, nil)
_, err = task.WaitForResult(d.ctx, nil)
if err != nil {
ui.Error(err.Error())
return

View File

@ -2,11 +2,7 @@ package main
import (
"github.com/mitchellh/multistep"
"context"
"fmt"
"net/url"
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/find"
)
type ConnectConfig struct {
@ -38,30 +34,12 @@ type StepConnect struct {
}
func (s *StepConnect) Run(state multistep.StateBag) multistep.StepAction {
ctx := state.Get("ctx").(context.Context)
vcenter_url, err := url.Parse(fmt.Sprintf("https://%v/sdk", s.config.VCenterServer))
driver, err := NewDriverVSphere(s.config)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
vcenter_url.User = url.UserPassword(s.config.Username, s.config.Password)
client, err := govmomi.NewClient(ctx, vcenter_url, s.config.InsecureConnection)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
state.Put("client", client)
finder := find.NewFinder(client.Client, false)
datacenter, err := finder.DatacenterOrDefault(ctx, s.config.Datacenter)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
finder.SetDatacenter(datacenter)
state.Put("finder", finder)
state.Put("datacenter", datacenter)
state.Put("driver", driver)
return multistep.ActionContinue
}

View File

@ -4,7 +4,6 @@ import (
"github.com/mitchellh/multistep"
"github.com/hashicorp/packer/packer"
"github.com/vmware/govmomi/vim25/types"
"context"
"github.com/vmware/govmomi/object"
"fmt"
)
@ -33,8 +32,8 @@ type StepConfigureHardware struct {
}
func (s *StepConfigureHardware) Run(state multistep.StateBag) multistep.StepAction {
d := state.Get("driver").(Driver)
vm := state.Get("vm").(*object.VirtualMachine)
ctx := state.Get("ctx").(context.Context)
ui := state.Get("ui").(packer.Ui)
if *s.config != (HardwareConfig{}) {
@ -55,12 +54,12 @@ func (s *StepConfigureHardware) Run(state multistep.StateBag) multistep.StepActi
confSpec.MemoryReservationLockedToMax = &s.config.RAMReserveAll
task, err := vm.Reconfigure(ctx, confSpec)
task, err := vm.Reconfigure(d.ctx, confSpec)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
_, err = task.WaitForResult(ctx, nil)
_, err = task.WaitForResult(d.ctx, nil)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt

View File

@ -4,7 +4,6 @@ import (
"github.com/mitchellh/multistep"
"github.com/hashicorp/packer/packer"
"github.com/vmware/govmomi/object"
"context"
"fmt"
"github.com/vmware/govmomi/vim25/types"
)
@ -16,22 +15,22 @@ type StepRun struct{
func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
vm := state.Get("vm").(*object.VirtualMachine)
ctx := state.Get("ctx").(context.Context)
d := state.Get("driver").(Driver)
ui.Say("VM power on...")
task, err := vm.PowerOn(ctx)
task, err := vm.PowerOn(d.ctx)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
_, err = task.WaitForResult(ctx, nil)
_, err = task.WaitForResult(d.ctx, nil)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
ui.Say("VM waiting for IP...")
ip, err := vm.WaitForIP(ctx)
ip, err := vm.WaitForIP(d.ctx)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
@ -48,18 +47,18 @@ func (s *StepRun) Cleanup(state multistep.StateBag) {
if cancelled || halted {
vm := state.Get("vm").(*object.VirtualMachine)
ctx := state.Get("ctx").(context.Context)
d := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
if state, err := vm.PowerState(ctx); state != types.VirtualMachinePowerStatePoweredOff && err == nil {
if state, err := vm.PowerState(d.ctx); state != types.VirtualMachinePowerStatePoweredOff && err == nil {
ui.Say("shutting down VM...")
task, err := vm.PowerOff(ctx)
task, err := vm.PowerOff(d.ctx)
if err != nil {
ui.Error(err.Error())
return
}
_, err = task.WaitForResult(ctx, nil)
_, err = task.WaitForResult(d.ctx, nil)
if err != nil {
ui.Error(err.Error())
return

View File

@ -4,7 +4,6 @@ import (
"github.com/mitchellh/multistep"
"github.com/hashicorp/packer/packer"
"github.com/vmware/govmomi/object"
"context"
"fmt"
"log"
"time"
@ -44,7 +43,7 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
comm := state.Get("communicator").(packer.Communicator)
ui := state.Get("ui").(packer.Ui)
vm := state.Get("vm").(*object.VirtualMachine)
ctx := state.Get("ctx").(context.Context)
d := state.Get("driver").(Driver)
ui.Say("Shut down VM...")
@ -65,7 +64,7 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
} else {
ui.Say("Forcibly halting virtual machine...")
err := vm.ShutdownGuest(ctx)
err := vm.ShutdownGuest(d.ctx)
if err != nil {
state.Put("error", fmt.Errorf("Cannot shut down VM: %v", err))
return multistep.ActionHalt
@ -76,7 +75,7 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
log.Printf("Waiting max %s for shutdown to complete", s.config.Timeout)
shutdownTimer := time.After(s.config.Timeout)
for {
powerState, err := vm.PowerState(ctx)
powerState, err := vm.PowerState(d.ctx)
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"
"context"
"github.com/vmware/govmomi/object"
)
@ -14,12 +13,12 @@ type StepCreateSnapshot struct{
func (s *StepCreateSnapshot) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
vm := state.Get("vm").(*object.VirtualMachine)
ctx := state.Get("ctx").(context.Context)
d := state.Get("driver").(Driver)
if s.createSnapshot {
ui.Say("creating snapshot...")
_, err := vm.CreateSnapshot(ctx, "packer_snapshot", "", true, true)
_, err := vm.CreateSnapshot(d.ctx, "packer_snapshot", "", true, true)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt

View File

@ -4,7 +4,6 @@ import (
"github.com/mitchellh/multistep"
"github.com/hashicorp/packer/packer"
"github.com/vmware/govmomi/object"
"context"
)
type StepConvertToTemplate struct{
@ -14,12 +13,12 @@ type StepConvertToTemplate struct{
func (s *StepConvertToTemplate) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
vm := state.Get("vm").(*object.VirtualMachine)
ctx := state.Get("ctx").(context.Context)
d := state.Get("driver").(Driver)
// Turning into template if needed
if s.ConvertToTemplate {
ui.Say("turning into template...")
err := vm.MarkAsTemplate(ctx)
err := vm.MarkAsTemplate(d.ctx)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt