extract vSphere driver
This commit is contained in:
parent
9f93e93c92
commit
1e747c8c93
|
@ -10,7 +10,6 @@ import (
|
||||||
"github.com/hashicorp/packer/helper/communicator"
|
"github.com/hashicorp/packer/helper/communicator"
|
||||||
gossh "golang.org/x/crypto/ssh"
|
gossh "golang.org/x/crypto/ssh"
|
||||||
"github.com/hashicorp/packer/communicator/ssh"
|
"github.com/hashicorp/packer/communicator/ssh"
|
||||||
"context"
|
|
||||||
"github.com/vmware/govmomi/object"
|
"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 := new(multistep.BasicStateBag)
|
||||||
state.Put("hook", hook)
|
state.Put("hook", hook)
|
||||||
state.Put("ui", ui)
|
state.Put("ui", ui)
|
||||||
state.Put("ctx", context.TODO())
|
|
||||||
|
|
||||||
steps := []multistep.Step{
|
steps := []multistep.Step{
|
||||||
&StepConnect{
|
&StepConnect{
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"github.com/vmware/govmomi/vim25/types"
|
"github.com/vmware/govmomi/vim25/types"
|
||||||
"github.com/vmware/govmomi/object"
|
"github.com/vmware/govmomi/object"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/vmware/govmomi/find"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/vmware/govmomi/vim25/mo"
|
"github.com/vmware/govmomi/vim25/mo"
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -49,39 +48,37 @@ type CloneParameters struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type StepCloneVM struct {
|
type StepCloneVM struct {
|
||||||
config *CloneConfig
|
config *CloneConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction {
|
func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
ctx := state.Get("ctx").(context.Context)
|
d := state.Get("driver").(Driver)
|
||||||
finder := state.Get("finder").(*find.Finder)
|
|
||||||
datacenter := state.Get("datacenter").(*object.Datacenter)
|
|
||||||
ui := state.Get("ui").(packer.Ui)
|
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 {
|
if err != nil {
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
state.Put("vmSrc", vmSrc)
|
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 {
|
if err != nil {
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
return multistep.ActionHalt
|
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 {
|
if err != nil {
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
|
|
||||||
var datastore *object.Datastore = nil
|
var datastore *object.Datastore
|
||||||
if s.config.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 {
|
if err != nil {
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
|
@ -89,7 +86,7 @@ func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
vm, err := cloneVM(&CloneParameters{
|
vm, err := cloneVM(&CloneParameters{
|
||||||
ctx: ctx,
|
ctx: d.ctx,
|
||||||
vmSrc: vmSrc,
|
vmSrc: vmSrc,
|
||||||
vmName: s.config.VMName,
|
vmName: s.config.VMName,
|
||||||
folder: folder,
|
folder: folder,
|
||||||
|
@ -114,17 +111,17 @@ func (s *StepCloneVM) Cleanup(state multistep.StateBag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if vm, ok := state.GetOk("vm"); ok {
|
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 := state.Get("ui").(packer.Ui)
|
||||||
|
|
||||||
ui.Say("Destroying VM...")
|
ui.Say("Destroying VM...")
|
||||||
|
|
||||||
task, err := vm.(*object.VirtualMachine).Destroy(ctx)
|
task, err := vm.(*object.VirtualMachine).Destroy(d.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ui.Error(err.Error())
|
ui.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = task.WaitForResult(ctx, nil)
|
_, err = task.WaitForResult(d.ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ui.Error(err.Error())
|
ui.Error(err.Error())
|
||||||
return
|
return
|
||||||
|
|
|
@ -2,11 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
|
||||||
"github.com/vmware/govmomi"
|
|
||||||
"github.com/vmware/govmomi/find"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConnectConfig struct {
|
type ConnectConfig struct {
|
||||||
|
@ -38,30 +34,12 @@ type StepConnect struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StepConnect) Run(state multistep.StateBag) multistep.StepAction {
|
func (s *StepConnect) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
ctx := state.Get("ctx").(context.Context)
|
driver, err := NewDriverVSphere(s.config)
|
||||||
|
|
||||||
vcenter_url, err := url.Parse(fmt.Sprintf("https://%v/sdk", s.config.VCenterServer))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
vcenter_url.User = url.UserPassword(s.config.Username, s.config.Password)
|
state.Put("driver", driver)
|
||||||
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)
|
|
||||||
|
|
||||||
return multistep.ActionContinue
|
return multistep.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/vmware/govmomi/vim25/types"
|
"github.com/vmware/govmomi/vim25/types"
|
||||||
"context"
|
|
||||||
"github.com/vmware/govmomi/object"
|
"github.com/vmware/govmomi/object"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
@ -33,8 +32,8 @@ type StepConfigureHardware struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StepConfigureHardware) Run(state multistep.StateBag) multistep.StepAction {
|
func (s *StepConfigureHardware) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
|
d := state.Get("driver").(Driver)
|
||||||
vm := state.Get("vm").(*object.VirtualMachine)
|
vm := state.Get("vm").(*object.VirtualMachine)
|
||||||
ctx := state.Get("ctx").(context.Context)
|
|
||||||
ui := state.Get("ui").(packer.Ui)
|
ui := state.Get("ui").(packer.Ui)
|
||||||
|
|
||||||
if *s.config != (HardwareConfig{}) {
|
if *s.config != (HardwareConfig{}) {
|
||||||
|
@ -55,12 +54,12 @@ func (s *StepConfigureHardware) Run(state multistep.StateBag) multistep.StepActi
|
||||||
|
|
||||||
confSpec.MemoryReservationLockedToMax = &s.config.RAMReserveAll
|
confSpec.MemoryReservationLockedToMax = &s.config.RAMReserveAll
|
||||||
|
|
||||||
task, err := vm.Reconfigure(ctx, confSpec)
|
task, err := vm.Reconfigure(d.ctx, confSpec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
_, err = task.WaitForResult(ctx, nil)
|
_, err = task.WaitForResult(d.ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
|
|
17
step_run.go
17
step_run.go
|
@ -4,7 +4,6 @@ import (
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/vmware/govmomi/object"
|
"github.com/vmware/govmomi/object"
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/vmware/govmomi/vim25/types"
|
"github.com/vmware/govmomi/vim25/types"
|
||||||
)
|
)
|
||||||
|
@ -16,22 +15,22 @@ type StepRun struct{
|
||||||
func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction {
|
func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
ui := state.Get("ui").(packer.Ui)
|
ui := state.Get("ui").(packer.Ui)
|
||||||
vm := state.Get("vm").(*object.VirtualMachine)
|
vm := state.Get("vm").(*object.VirtualMachine)
|
||||||
ctx := state.Get("ctx").(context.Context)
|
d := state.Get("driver").(Driver)
|
||||||
|
|
||||||
ui.Say("VM power on...")
|
ui.Say("VM power on...")
|
||||||
task, err := vm.PowerOn(ctx)
|
task, err := vm.PowerOn(d.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
_, err = task.WaitForResult(ctx, nil)
|
_, err = task.WaitForResult(d.ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.Say("VM waiting for IP...")
|
ui.Say("VM waiting for IP...")
|
||||||
ip, err := vm.WaitForIP(ctx)
|
ip, err := vm.WaitForIP(d.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
|
@ -48,18 +47,18 @@ func (s *StepRun) Cleanup(state multistep.StateBag) {
|
||||||
|
|
||||||
if cancelled || halted {
|
if cancelled || halted {
|
||||||
vm := state.Get("vm").(*object.VirtualMachine)
|
vm := state.Get("vm").(*object.VirtualMachine)
|
||||||
ctx := state.Get("ctx").(context.Context)
|
d := state.Get("driver").(Driver)
|
||||||
ui := state.Get("ui").(packer.Ui)
|
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...")
|
ui.Say("shutting down VM...")
|
||||||
|
|
||||||
task, err := vm.PowerOff(ctx)
|
task, err := vm.PowerOff(d.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ui.Error(err.Error())
|
ui.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = task.WaitForResult(ctx, nil)
|
_, err = task.WaitForResult(d.ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ui.Error(err.Error())
|
ui.Error(err.Error())
|
||||||
return
|
return
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/vmware/govmomi/object"
|
"github.com/vmware/govmomi/object"
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
@ -44,7 +43,7 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
comm := state.Get("communicator").(packer.Communicator)
|
comm := state.Get("communicator").(packer.Communicator)
|
||||||
ui := state.Get("ui").(packer.Ui)
|
ui := state.Get("ui").(packer.Ui)
|
||||||
vm := state.Get("vm").(*object.VirtualMachine)
|
vm := state.Get("vm").(*object.VirtualMachine)
|
||||||
ctx := state.Get("ctx").(context.Context)
|
d := state.Get("driver").(Driver)
|
||||||
|
|
||||||
ui.Say("Shut down VM...")
|
ui.Say("Shut down VM...")
|
||||||
|
|
||||||
|
@ -65,7 +64,7 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
} else {
|
} else {
|
||||||
ui.Say("Forcibly halting virtual machine...")
|
ui.Say("Forcibly halting virtual machine...")
|
||||||
|
|
||||||
err := vm.ShutdownGuest(ctx)
|
err := vm.ShutdownGuest(d.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state.Put("error", fmt.Errorf("Cannot shut down VM: %v", err))
|
state.Put("error", fmt.Errorf("Cannot shut down VM: %v", err))
|
||||||
return multistep.ActionHalt
|
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)
|
log.Printf("Waiting max %s for shutdown to complete", s.config.Timeout)
|
||||||
shutdownTimer := time.After(s.config.Timeout)
|
shutdownTimer := time.After(s.config.Timeout)
|
||||||
for {
|
for {
|
||||||
powerState, err := vm.PowerState(ctx)
|
powerState, err := vm.PowerState(d.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
|
|
|
@ -3,7 +3,6 @@ package main
|
||||||
import (
|
import (
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"context"
|
|
||||||
"github.com/vmware/govmomi/object"
|
"github.com/vmware/govmomi/object"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -14,12 +13,12 @@ type StepCreateSnapshot struct{
|
||||||
func (s *StepCreateSnapshot) Run(state multistep.StateBag) multistep.StepAction {
|
func (s *StepCreateSnapshot) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
ui := state.Get("ui").(packer.Ui)
|
ui := state.Get("ui").(packer.Ui)
|
||||||
vm := state.Get("vm").(*object.VirtualMachine)
|
vm := state.Get("vm").(*object.VirtualMachine)
|
||||||
ctx := state.Get("ctx").(context.Context)
|
d := state.Get("driver").(Driver)
|
||||||
|
|
||||||
if s.createSnapshot {
|
if s.createSnapshot {
|
||||||
ui.Say("creating snapshot...")
|
ui.Say("creating snapshot...")
|
||||||
|
|
||||||
_, err := vm.CreateSnapshot(ctx, "packer_snapshot", "", true, true)
|
_, err := vm.CreateSnapshot(d.ctx, "packer_snapshot", "", true, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/vmware/govmomi/object"
|
"github.com/vmware/govmomi/object"
|
||||||
"context"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type StepConvertToTemplate struct{
|
type StepConvertToTemplate struct{
|
||||||
|
@ -14,12 +13,12 @@ type StepConvertToTemplate struct{
|
||||||
func (s *StepConvertToTemplate) Run(state multistep.StateBag) multistep.StepAction {
|
func (s *StepConvertToTemplate) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
ui := state.Get("ui").(packer.Ui)
|
ui := state.Get("ui").(packer.Ui)
|
||||||
vm := state.Get("vm").(*object.VirtualMachine)
|
vm := state.Get("vm").(*object.VirtualMachine)
|
||||||
ctx := state.Get("ctx").(context.Context)
|
d := state.Get("driver").(Driver)
|
||||||
|
|
||||||
// Turning into template if needed
|
// Turning into template if needed
|
||||||
if s.ConvertToTemplate {
|
if s.ConvertToTemplate {
|
||||||
ui.Say("turning into template...")
|
ui.Say("turning into template...")
|
||||||
err := vm.MarkAsTemplate(ctx)
|
err := vm.MarkAsTemplate(d.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
|
|
Loading…
Reference in New Issue