Fix for Support selection of datastore for dynamic provisioning in vSphere
This commit is contained in:
committed by
Ritesh H Shukla
parent
b201ac2f8f
commit
12f75f0b86
212
vendor/github.com/vmware/govmomi/object/virtual_machine.go
generated
vendored
212
vendor/github.com/vmware/govmomi/object/virtual_machine.go
generated
vendored
@@ -17,15 +17,17 @@ limitations under the License.
|
||||
package object
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"path"
|
||||
|
||||
"github.com/vmware/govmomi/property"
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -227,9 +229,12 @@ func (v VirtualMachine) WaitForIP(ctx context.Context) (string, error) {
|
||||
|
||||
// WaitForNetIP waits for the VM guest.net property to report an IP address for all VM NICs.
|
||||
// Only consider IPv4 addresses if the v4 param is true.
|
||||
// By default, wait for all NICs to get an IP address, unless 1 or more device is given.
|
||||
// A device can be specified by the MAC address or the device name, e.g. "ethernet-0".
|
||||
// Returns a map with MAC address as the key and IP address list as the value.
|
||||
func (v VirtualMachine) WaitForNetIP(ctx context.Context, v4 bool) (map[string][]string, error) {
|
||||
func (v VirtualMachine) WaitForNetIP(ctx context.Context, v4 bool, device ...string) (map[string][]string, error) {
|
||||
macs := make(map[string][]string)
|
||||
eths := make(map[string]string)
|
||||
|
||||
p := property.DefaultCollector(v.c)
|
||||
|
||||
@@ -240,14 +245,15 @@ func (v VirtualMachine) WaitForNetIP(ctx context.Context, v4 bool) (map[string][
|
||||
continue
|
||||
}
|
||||
|
||||
devices := c.Val.(types.ArrayOfVirtualDevice).VirtualDevice
|
||||
for _, device := range devices {
|
||||
if nic, ok := device.(types.BaseVirtualEthernetCard); ok {
|
||||
devices := VirtualDeviceList(c.Val.(types.ArrayOfVirtualDevice).VirtualDevice)
|
||||
for _, d := range devices {
|
||||
if nic, ok := d.(types.BaseVirtualEthernetCard); ok {
|
||||
mac := nic.GetVirtualEthernetCard().MacAddress
|
||||
if mac == "" {
|
||||
return false
|
||||
}
|
||||
macs[mac] = nil
|
||||
eths[devices.Name(d)] = mac
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,6 +261,17 @@ func (v VirtualMachine) WaitForNetIP(ctx context.Context, v4 bool) (map[string][
|
||||
return true
|
||||
})
|
||||
|
||||
if len(device) != 0 {
|
||||
// Only wait for specific NIC(s)
|
||||
macs = make(map[string][]string)
|
||||
for _, mac := range device {
|
||||
if eth, ok := eths[mac]; ok {
|
||||
mac = eth // device name, e.g. "ethernet-0"
|
||||
}
|
||||
macs[mac] = nil
|
||||
}
|
||||
}
|
||||
|
||||
err = property.Wait(ctx, p, v.Reference(), []string{"guest.net"}, func(pc []types.PropertyChange) bool {
|
||||
for _, c := range pc {
|
||||
if c.Op != types.PropertyChangeOpAssign {
|
||||
@@ -300,18 +317,28 @@ func (v VirtualMachine) WaitForNetIP(ctx context.Context, v4 bool) (map[string][
|
||||
func (v VirtualMachine) Device(ctx context.Context) (VirtualDeviceList, error) {
|
||||
var o mo.VirtualMachine
|
||||
|
||||
err := v.Properties(ctx, v.Reference(), []string{"config.hardware.device"}, &o)
|
||||
err := v.Properties(ctx, v.Reference(), []string{"config.hardware.device", "summary.runtime.connectionState"}, &o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Quoting the SDK doc:
|
||||
// The virtual machine configuration is not guaranteed to be available.
|
||||
// For example, the configuration information would be unavailable if the server
|
||||
// is unable to access the virtual machine files on disk, and is often also unavailable
|
||||
// during the initial phases of virtual machine creation.
|
||||
if o.Config == nil {
|
||||
return nil, fmt.Errorf("%s Config is not available, connectionState=%s",
|
||||
v.Reference(), o.Summary.Runtime.ConnectionState)
|
||||
}
|
||||
|
||||
return VirtualDeviceList(o.Config.Hardware.Device), nil
|
||||
}
|
||||
|
||||
func (v VirtualMachine) HostSystem(ctx context.Context) (*HostSystem, error) {
|
||||
var o mo.VirtualMachine
|
||||
|
||||
err := v.Properties(ctx, v.Reference(), []string{"summary"}, &o)
|
||||
err := v.Properties(ctx, v.Reference(), []string{"summary.runtime.host"}, &o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -470,24 +497,102 @@ func (v VirtualMachine) RemoveAllSnapshot(ctx context.Context, consolidate *bool
|
||||
return NewTask(v.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
// RevertToSnapshot reverts to a named snapshot
|
||||
func (v VirtualMachine) RevertToSnapshot(ctx context.Context, name string, suppressPowerOn bool) (*Task, error) {
|
||||
type snapshotMap map[string][]Reference
|
||||
|
||||
func (m snapshotMap) add(parent string, tree []types.VirtualMachineSnapshotTree) {
|
||||
for i, st := range tree {
|
||||
sname := st.Name
|
||||
names := []string{sname, st.Snapshot.Value}
|
||||
|
||||
if parent != "" {
|
||||
sname = path.Join(parent, sname)
|
||||
// Add full path as an option to resolve duplicate names
|
||||
names = append(names, sname)
|
||||
}
|
||||
|
||||
for _, name := range names {
|
||||
m[name] = append(m[name], &tree[i].Snapshot)
|
||||
}
|
||||
|
||||
m.add(sname, st.ChildSnapshotList)
|
||||
}
|
||||
}
|
||||
|
||||
// findSnapshot supports snapshot lookup by name, where name can be:
|
||||
// 1) snapshot ManagedObjectReference.Value (unique)
|
||||
// 2) snapshot name (may not be unique)
|
||||
// 3) snapshot tree path (may not be unique)
|
||||
func (v VirtualMachine) findSnapshot(ctx context.Context, name string) (Reference, error) {
|
||||
var o mo.VirtualMachine
|
||||
|
||||
err := v.Properties(ctx, v.Reference(), []string{"snapshot"}, &o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
snapshotTree := o.Snapshot.RootSnapshotList
|
||||
if len(snapshotTree) < 1 {
|
||||
if o.Snapshot == nil || len(o.Snapshot.RootSnapshotList) == 0 {
|
||||
return nil, errors.New("No snapshots for this VM")
|
||||
}
|
||||
|
||||
snapshot, err := traverseSnapshotInTree(snapshotTree, name)
|
||||
m := make(snapshotMap)
|
||||
m.add("", o.Snapshot.RootSnapshotList)
|
||||
|
||||
s := m[name]
|
||||
switch len(s) {
|
||||
case 0:
|
||||
return nil, fmt.Errorf("snapshot %q not found", name)
|
||||
case 1:
|
||||
return s[0], nil
|
||||
default:
|
||||
return nil, fmt.Errorf("%q resolves to %d snapshots", name, len(s))
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveSnapshot removes a named snapshot
|
||||
func (v VirtualMachine) RemoveSnapshot(ctx context.Context, name string, removeChildren bool, consolidate *bool) (*Task, error) {
|
||||
snapshot, err := v.findSnapshot(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := types.RemoveSnapshot_Task{
|
||||
This: snapshot.Reference(),
|
||||
RemoveChildren: removeChildren,
|
||||
Consolidate: consolidate,
|
||||
}
|
||||
|
||||
res, err := methods.RemoveSnapshot_Task(ctx, v.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewTask(v.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
// RevertToCurrentSnapshot reverts to the current snapshot
|
||||
func (v VirtualMachine) RevertToCurrentSnapshot(ctx context.Context, suppressPowerOn bool) (*Task, error) {
|
||||
req := types.RevertToCurrentSnapshot_Task{
|
||||
This: v.Reference(),
|
||||
SuppressPowerOn: types.NewBool(suppressPowerOn),
|
||||
}
|
||||
|
||||
res, err := methods.RevertToCurrentSnapshot_Task(ctx, v.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewTask(v.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
// RevertToSnapshot reverts to a named snapshot
|
||||
func (v VirtualMachine) RevertToSnapshot(ctx context.Context, name string, suppressPowerOn bool) (*Task, error) {
|
||||
snapshot, err := v.findSnapshot(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := types.RevertToSnapshot_Task{
|
||||
This: snapshot,
|
||||
This: snapshot.Reference(),
|
||||
SuppressPowerOn: types.NewBool(suppressPowerOn),
|
||||
}
|
||||
|
||||
@@ -499,32 +604,6 @@ func (v VirtualMachine) RevertToSnapshot(ctx context.Context, name string, suppr
|
||||
return NewTask(v.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
// traverseSnapshotInTree is a recursive function that will traverse a snapshot tree to find a given snapshot
|
||||
func traverseSnapshotInTree(tree []types.VirtualMachineSnapshotTree, name string) (types.ManagedObjectReference, error) {
|
||||
var o types.ManagedObjectReference
|
||||
if tree == nil {
|
||||
return o, errors.New("Snapshot tree is empty")
|
||||
}
|
||||
for _, s := range tree {
|
||||
if s.Name == name {
|
||||
o = s.Snapshot
|
||||
break
|
||||
} else {
|
||||
childTree := s.ChildSnapshotList
|
||||
var err error
|
||||
o, err = traverseSnapshotInTree(childTree, name)
|
||||
if err != nil {
|
||||
return o, err
|
||||
}
|
||||
}
|
||||
}
|
||||
if o.Value == "" {
|
||||
return o, errors.New("Snapshot not found")
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// IsToolsRunning returns true if VMware Tools is currently running in the guest OS, and false otherwise.
|
||||
func (v VirtualMachine) IsToolsRunning(ctx context.Context) (bool, error) {
|
||||
var o mo.VirtualMachine
|
||||
@@ -591,3 +670,58 @@ func (v VirtualMachine) MarkAsVirtualMachine(ctx context.Context, pool ResourceP
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v VirtualMachine) Migrate(ctx context.Context, pool *ResourcePool, host *HostSystem, priority types.VirtualMachineMovePriority, state types.VirtualMachinePowerState) (*Task, error) {
|
||||
req := types.MigrateVM_Task{
|
||||
This: v.Reference(),
|
||||
Priority: priority,
|
||||
State: state,
|
||||
}
|
||||
|
||||
if pool != nil {
|
||||
ref := pool.Reference()
|
||||
req.Pool = &ref
|
||||
}
|
||||
|
||||
if host != nil {
|
||||
ref := host.Reference()
|
||||
req.Host = &ref
|
||||
}
|
||||
|
||||
res, err := methods.MigrateVM_Task(ctx, v.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewTask(v.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
func (v VirtualMachine) Unregister(ctx context.Context) error {
|
||||
req := types.UnregisterVM{
|
||||
This: v.Reference(),
|
||||
}
|
||||
|
||||
_, err := methods.UnregisterVM(ctx, v.Client(), &req)
|
||||
return err
|
||||
}
|
||||
|
||||
// QueryEnvironmentBrowser is a helper to get the environmentBrowser property.
|
||||
func (v VirtualMachine) QueryConfigTarget(ctx context.Context) (*types.ConfigTarget, error) {
|
||||
var vm mo.VirtualMachine
|
||||
|
||||
err := v.Properties(ctx, v.Reference(), []string{"environmentBrowser"}, &vm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := types.QueryConfigTarget{
|
||||
This: vm.EnvironmentBrowser,
|
||||
}
|
||||
|
||||
res, err := methods.QueryConfigTarget(ctx, v.Client(), &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Returnval, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user