Implemented #4, #5 and #6 (#14)

* initial changes: added host and pool parameters

* backup

* clones only within the same host

* added some debug-output

* minor fixes

* vm experiments

* added datastore to realocation spec

* added datastore parameter; fixed copying between hosts

* removed debug-output

* changed dependencies
This commit is contained in:
Elizaveta Tretyakova 2017-05-31 11:38:50 +03:00 committed by GitHub
parent ca41b34285
commit 0b17912c07
3 changed files with 66 additions and 142 deletions

View File

@ -19,15 +19,19 @@ type Config struct {
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
Template string `mapstructure:"template"`
VMName string `mapstructure:"vm_name"`
FolderName string `mapstructure:"folder_name"`
DCName string `mapstructure:"dc_name"`
// Location
Template string `mapstructure:"template"`
VMName string `mapstructure:"vm_name"`
FolderName string `mapstructure:"folder_name"`
DCName string `mapstructure:"dc_name"`
Host string `mapstructure:"host"`
ResourcePool string `mapstructure:"resource_pool"`
Datastore string `mapstructure:"datastore"`
// Hardware
Cpus string `mapstructure:"cpus"`
ShutdownCommand string `mapstructure:"shutdown_command"`
Ram string `mapstructure:"RAM"`
//TODO: add more options
ctx interpolate.Context
}
@ -64,6 +68,9 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
if c.VMName == "" {
errs = packer.MultiErrorAppend(errs, fmt.Errorf("Target VM name required"))
}
if c.Host == "" {
errs = packer.MultiErrorAppend(errs, fmt.Errorf("Target host required"))
}
// Verify numeric parameters if present
if c.Cpus != "" {
@ -79,6 +86,9 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
// Warnings
var warnings []string
if c.Datastore == "" {
warnings = append(warnings, "Datastore is not specified, will try to find a default one")
}
if len(errs.Errors) > 0 {
return nil, warnings, errs

101
glide.lock generated
View File

@ -1,101 +0,0 @@
hash: 9caf4a309ee0ce30e273ceb77d66b9b49090765e1f0dcbe6e05ce0da88b1435f
updated: 2017-05-16T08:15:30.457888159+03:00
imports:
- name: github.com/Azure/go-ntlmssp
version: 29affced641074a59483ed003b5ef73a8bd3593c
- name: github.com/dylanmei/iso8601
version: 2075bf119b58e5576c6ed9f867b8f3d17f2e54d4
- name: github.com/hashicorp/errwrap
version: 7554cd9344cec97297fa6649b055a8c98c2a1e55
- name: github.com/hashicorp/go-multierror
version: ed905158d87462226a13fe39ddf685ea65f1c11f
- name: github.com/hashicorp/go-version
version: 03c5bf6be031b6dd45afec16b1cf94fc8938bc77
- name: github.com/hashicorp/packer
version: 45a48132d0c455f777163538002aeb8784b64e50
subpackages:
- common
- common/ssh
- common/uuid
- communicator/none
- communicator/ssh
- communicator/winrm
- helper/communicator
- helper/config
- packer
- packer/plugin
- packer/rpc
- template
- template/interpolate
- name: github.com/hashicorp/yamux
version: d1caa6c97c9fc1cc9e83bbe34d0603f9ff0ce8bd
- name: github.com/kr/fs
version: 2788f0dbd16903de03cb8186e5c7d97b69ad387b
- name: github.com/masterzen/azure-sdk-for-go
version: ee4f0065d00cd12b542f18f5bc45799e88163b12
subpackages:
- core/http
- core/tls
- name: github.com/masterzen/simplexml
version: 4572e39b1ab9fe03ee513ce6fc7e289e98482190
subpackages:
- dom
- name: github.com/masterzen/winrm
version: acf371f6aff113fc0104a61cd72db45a7c27d310
subpackages:
- soap
- name: github.com/masterzen/xmlpath
version: 13f4951698adc0fa9c1dda3e275d489a24201161
- name: github.com/mitchellh/go-fs
version: 7bae45d9a684750e82b97ff320c82556614e621b
subpackages:
- fat
- name: github.com/mitchellh/iochan
version: 87b45ffd0e9581375c491fef3d32130bb15c5bd7
- name: github.com/mitchellh/mapstructure
version: cc8532a8e9a55ea36402aa21efdf403a60d34096
- name: github.com/mitchellh/multistep
version: 391576a156a54cfbb4cf5d5eda40cf6ffa3e3a4d
- name: github.com/mitchellh/reflectwalk
version: 8d802ff4ae93611b807597f639c19f76074df5c6
- name: github.com/nu7hatch/gouuid
version: 179d4d0c4d8d407a32af483c2354df1d2c91e6c3
- name: github.com/packer-community/winrmcp
version: c804d432b8b7fa77896f43cc426134348c3fd19e
subpackages:
- winrmcp
- name: github.com/pkg/errors
version: c605e284fe17294bda444b34710735b29d1a9d90
- name: github.com/pkg/sftp
version: a5f8514e29e90a859e93871b1582e5c81f466f82
- name: github.com/ugorji/go
version: 708a42d246822952f38190a8d8c4e6b16a0e600c
subpackages:
- codec
- name: github.com/vmware/govmomi
version: 9bfdc5ce62c0585b48b154cc460f8664dcd124c3
subpackages:
- find
- list
- object
- property
- session
- task
- vim25
- vim25/debug
- vim25/methods
- vim25/mo
- vim25/progress
- vim25/soap
- vim25/types
- vim25/xml
- name: golang.org/x/crypto
version: ab89591268e0c8b748cbe4047b00197516011af5
subpackages:
- curve25519
- ed25519
- ed25519/internal/edwards25519
- md4
- ssh
- ssh/agent
testImports: []

View File

@ -13,11 +13,13 @@ import (
)
type CloneParameters struct {
client *govmomi.Client
folder *object.Folder
vmSrc *object.VirtualMachine
ctx context.Context
vmName string
client *govmomi.Client
folder *object.Folder
resourcePool *object.ResourcePool
datastore *object.Datastore
vmSrc *object.VirtualMachine
ctx context.Context
vmName string
}
type StepCloneVM struct{
@ -35,31 +37,56 @@ func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction {
state.Put("error", err)
return multistep.ActionHalt
}
finder, ctx, err := createFinder(ctx, client, s.config.DCName)
// Set up finder
finder := find.NewFinder(client.Client, false)
dc, err := finder.DatacenterOrDefault(ctx, s.config.DCName)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
finder.SetDatacenter(dc)
// Get folder
folder, err := finder.FolderOrDefault(ctx, s.config.FolderName)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
// Get resource pool
pool, err := finder.ResourcePoolOrDefault(ctx, fmt.Sprintf("/%v/host/%v/Resources/%v", dc.Name(), s.config.Host, s.config.ResourcePool))
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
// Get datastore
var datastore *object.Datastore = nil
if s.config.Datastore != "" {
datastore, err = finder.Datastore(ctx, s.config.Datastore)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
}
// Get source VM
vmSrc, err := finder.VirtualMachine(ctx, s.config.Template)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
cloneParameters := CloneParameters{
client: client,
folder: folder,
vmSrc: vmSrc,
ctx: ctx,
vmName: s.config.VMName,
}
vm, err := cloneVM(&cloneParameters)
vm, err := cloneVM(&CloneParameters{
client: client,
folder: folder,
resourcePool: pool,
datastore: datastore,
vmSrc: vmSrc,
ctx: ctx,
vmName: s.config.VMName,
})
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
@ -102,9 +129,17 @@ func (s *StepCloneVM) Cleanup(state multistep.StateBag) {
func cloneVM(params *CloneParameters) (vm *object.VirtualMachine, err error) {
vm = nil
err = nil
poolRef := params.resourcePool.Reference()
// Creating specs for cloning
var relocateSpec types.VirtualMachineRelocateSpec
relocateSpec := types.VirtualMachineRelocateSpec{
Pool: &(poolRef),
}
if params.datastore != nil {
datastoreRef := params.datastore.Reference()
relocateSpec.Datastore = &datastoreRef
}
cloneSpec := types.VirtualMachineCloneSpec{
Location: relocateSpec,
PowerOn: false,
@ -145,23 +180,3 @@ func createClient(URL, username, password string) (*govmomi.Client, context.Cont
return client, ctx, nil
}
func createFinder(ctx context.Context, client *govmomi.Client, dcName string) (*find.Finder, context.Context, error) {
// Create a finder to search for a vm with the specified name
finder := find.NewFinder(client.Client, false)
// Need to specify the datacenter
if dcName == "" {
dc, err := finder.DefaultDatacenter(ctx)
if err != nil {
return nil, nil, err
}
finder.SetDatacenter(dc)
} else {
dc, err := finder.Datacenter(ctx, dcName)
if err != nil {
return nil, nil, err
}
finder.SetDatacenter(dc)
}
return finder, ctx, nil
}