Blame vendor/github.com/vmware/govmomi/govc/vm/change.go

Packit 63bb0d
/*
Packit 63bb0d
Copyright (c) 2015-2017 VMware, Inc. All Rights Reserved.
Packit 63bb0d
Packit 63bb0d
Licensed under the Apache License, Version 2.0 (the "License");
Packit 63bb0d
you may not use this file except in compliance with the License.
Packit 63bb0d
You may obtain a copy of the License at
Packit 63bb0d
Packit 63bb0d
    http://www.apache.org/licenses/LICENSE-2.0
Packit 63bb0d
Packit 63bb0d
Unless required by applicable law or agreed to in writing, software
Packit 63bb0d
distributed under the License is distributed on an "AS IS" BASIS,
Packit 63bb0d
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 63bb0d
See the License for the specific language governing permissions and
Packit 63bb0d
limitations under the License.
Packit 63bb0d
*/
Packit 63bb0d
Packit 63bb0d
package vm
Packit 63bb0d
Packit 63bb0d
import (
Packit 63bb0d
	"context"
Packit 63bb0d
	"flag"
Packit 63bb0d
	"fmt"
Packit 63bb0d
	"reflect"
Packit 63bb0d
	"strings"
Packit 63bb0d
Packit 63bb0d
	"github.com/vmware/govmomi/govc/cli"
Packit 63bb0d
	"github.com/vmware/govmomi/govc/flags"
Packit 63bb0d
	"github.com/vmware/govmomi/vim25/types"
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
type extraConfig []types.BaseOptionValue
Packit 63bb0d
Packit 63bb0d
func (e *extraConfig) String() string {
Packit 63bb0d
	return fmt.Sprintf("%v", *e)
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (e *extraConfig) Set(v string) error {
Packit 63bb0d
	r := strings.SplitN(v, "=", 2)
Packit 63bb0d
	if len(r) < 2 {
Packit 63bb0d
		return fmt.Errorf("failed to parse extraConfig: %s", v)
Packit 63bb0d
	}
Packit 63bb0d
	*e = append(*e, &types.OptionValue{Key: r[0], Value: r[1]})
Packit 63bb0d
	return nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
type change struct {
Packit 63bb0d
	*flags.VirtualMachineFlag
Packit 63bb0d
	*flags.ResourceAllocationFlag
Packit 63bb0d
Packit 63bb0d
	types.VirtualMachineConfigSpec
Packit 63bb0d
	extraConfig extraConfig
Packit 63bb0d
	Latency     string
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func init() {
Packit 63bb0d
	cli.Register("vm.change", &change{})
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
var latencyLevels = []string{
Packit 63bb0d
	string(types.LatencySensitivitySensitivityLevelLow),
Packit 63bb0d
	string(types.LatencySensitivitySensitivityLevelNormal),
Packit 63bb0d
	string(types.LatencySensitivitySensitivityLevelHigh),
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// setLatency validates latency level if set
Packit 63bb0d
func (cmd *change) setLatency() error {
Packit 63bb0d
	if cmd.Latency == "" {
Packit 63bb0d
		return nil
Packit 63bb0d
	}
Packit 63bb0d
	for _, l := range latencyLevels {
Packit 63bb0d
		if l == cmd.Latency {
Packit 63bb0d
			cmd.LatencySensitivity = &types.LatencySensitivity{
Packit 63bb0d
				Level: types.LatencySensitivitySensitivityLevel(cmd.Latency),
Packit 63bb0d
			}
Packit 63bb0d
			return nil
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
	return fmt.Errorf("latency must be one of: %s", strings.Join(latencyLevels, "|"))
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// setAllocation sets *info=nil if none of the fields have been set.
Packit 63bb0d
// We need non-nil fields for use with flag.FlagSet, but we want the
Packit 63bb0d
// VirtualMachineConfigSpec fields to be nil if none of the related flags were given.
Packit 63bb0d
func setAllocation(info **types.ResourceAllocationInfo) {
Packit 63bb0d
	r := *info
Packit 63bb0d
Packit 63bb0d
	if r.Shares.Level == "" {
Packit 63bb0d
		r.Shares = nil
Packit 63bb0d
	} else {
Packit 63bb0d
		return
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if r.Limit != nil {
Packit 63bb0d
		return
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if r.Reservation != nil {
Packit 63bb0d
		return
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	*info = nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (cmd *change) Register(ctx context.Context, f *flag.FlagSet) {
Packit 63bb0d
	cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
Packit 63bb0d
	cmd.VirtualMachineFlag.Register(ctx, f)
Packit 63bb0d
Packit 63bb0d
	cmd.CpuAllocation = &types.ResourceAllocationInfo{Shares: new(types.SharesInfo)}
Packit 63bb0d
	cmd.MemoryAllocation = &types.ResourceAllocationInfo{Shares: new(types.SharesInfo)}
Packit 63bb0d
	cmd.ResourceAllocationFlag = flags.NewResourceAllocationFlag(cmd.CpuAllocation, cmd.MemoryAllocation)
Packit 63bb0d
	cmd.ResourceAllocationFlag.ExpandableReservation = false
Packit 63bb0d
	cmd.ResourceAllocationFlag.Register(ctx, f)
Packit 63bb0d
Packit 63bb0d
	f.Int64Var(&cmd.MemoryMB, "m", 0, "Size in MB of memory")
Packit 63bb0d
	f.Var(flags.NewInt32(&cmd.NumCPUs), "c", "Number of CPUs")
Packit 63bb0d
	f.StringVar(&cmd.GuestId, "g", "", "Guest OS")
Packit 63bb0d
	f.StringVar(&cmd.Name, "name", "", "Display name")
Packit 63bb0d
	f.StringVar(&cmd.Latency, "latency", "", fmt.Sprintf("Latency sensitivity (%s)", strings.Join(latencyLevels, "|")))
Packit 63bb0d
	f.StringVar(&cmd.Annotation, "annotation", "", "VM description")
Packit 63bb0d
	f.StringVar(&cmd.Uuid, "uuid", "", "BIOS UUID")
Packit 63bb0d
	f.Var(&cmd.extraConfig, "e", "ExtraConfig. <key>=<value>")
Packit 63bb0d
Packit 63bb0d
	f.Var(flags.NewOptionalBool(&cmd.NestedHVEnabled), "nested-hv-enabled", "Enable nested hardware-assisted virtualization")
Packit 63bb0d
	cmd.Tools = &types.ToolsConfigInfo{}
Packit 63bb0d
	f.Var(flags.NewOptionalBool(&cmd.Tools.SyncTimeWithHost), "sync-time-with-host", "Enable SyncTimeWithHost")
Packit 63bb0d
	f.Var(flags.NewOptionalBool(&cmd.VPMCEnabled), "vpmc-enabled", "Enable CPU performance counters")
Packit 63bb0d
	f.Var(flags.NewOptionalBool(&cmd.MemoryHotAddEnabled), "memory-hot-add-enabled", "Enable memory hot add")
Packit 63bb0d
	f.Var(flags.NewOptionalBool(&cmd.MemoryReservationLockedToMax), "memory-pin", "Reserve all guest memory")
Packit 63bb0d
	f.Var(flags.NewOptionalBool(&cmd.CpuHotAddEnabled), "cpu-hot-add-enabled", "Enable CPU hot add")
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (cmd *change) Description() string {
Packit 63bb0d
	return `Change VM configuration.
Packit 63bb0d
Packit 63bb0d
To add ExtraConfig variables that can read within the guest, use the 'guestinfo.' prefix.
Packit 63bb0d
Packit 63bb0d
Examples:
Packit 63bb0d
  govc vm.change -vm $vm -mem.reservation 2048
Packit 63bb0d
  govc vm.change -vm $vm -e smc.present=TRUE -e ich7m.present=TRUE
Packit 63bb0d
  # Enable both cpu and memory hotplug on a guest:
Packit 63bb0d
  govc vm.change -vm $vm -cpu-hot-add-enabled -memory-hot-add-enabled
Packit 63bb0d
  govc vm.change -vm $vm -e guestinfo.vmname $vm
Packit 63bb0d
  # Read the variable set above inside the guest:
Packit 63bb0d
  vmware-rpctool "info-get guestinfo.vmname"
Packit 63bb0d
  govc vm.change -vm $vm -latency high
Packit 63bb0d
  govc vm.change -vm $vm -latency normal
Packit 63bb0d
  govc vm.change -vm $vm -uuid 4139c345-7186-4924-a842-36b69a24159b`
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (cmd *change) Process(ctx context.Context) error {
Packit 63bb0d
	if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
Packit 63bb0d
		return err
Packit 63bb0d
	}
Packit 63bb0d
	return nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (cmd *change) Run(ctx context.Context, f *flag.FlagSet) error {
Packit 63bb0d
	vm, err := cmd.VirtualMachine()
Packit 63bb0d
	if err != nil {
Packit 63bb0d
		return err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if vm == nil {
Packit 63bb0d
		return flag.ErrHelp
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if len(cmd.extraConfig) > 0 {
Packit 63bb0d
		cmd.VirtualMachineConfigSpec.ExtraConfig = cmd.extraConfig
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	setAllocation(&cmd.CpuAllocation)
Packit 63bb0d
	setAllocation(&cmd.MemoryAllocation)
Packit 63bb0d
	if reflect.DeepEqual(cmd.Tools, new(types.ToolsConfigInfo)) {
Packit 63bb0d
		cmd.Tools = nil // no flags set, avoid sending <tools/> in the request
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if err = cmd.setLatency(); err != nil {
Packit 63bb0d
		return err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	task, err := vm.Reconfigure(ctx, cmd.VirtualMachineConfigSpec)
Packit 63bb0d
	if err != nil {
Packit 63bb0d
		return err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return task.Wait(ctx)
Packit 63bb0d
}