Skip to content

Commit

Permalink
govc: Add feature to read file contents for ExtraConfig
Browse files Browse the repository at this point in the history
Closes: #2488
  • Loading branch information
Okeanos committed Oct 1, 2021
1 parent 66669ef commit b5426eb
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 5 deletions.
3 changes: 3 additions & 0 deletions govc/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4962,6 +4962,8 @@ Examples:
# Enable both cpu and memory hotplug on a guest:
govc vm.change -vm $vm -cpu-hot-add-enabled -memory-hot-add-enabled
govc vm.change -vm $vm -e guestinfo.vmname $vm
# Read the contents of a file and use them as ExtraConfig value
govc vm.change -vm $vm -f guestinfo.data="$(realpath .)/vmdata.config"
# Read the variable set above inside the guest:
vmware-rpctool "info-get guestinfo.vmname"
govc vm.change -vm $vm -latency high
Expand All @@ -4976,6 +4978,7 @@ Options:
-cpu.reservation=<nil> CPU reservation in MHz
-cpu.shares= CPU shares level or number
-e=[] ExtraConfig. <key>=<value>
-f=[] ExtraConfig. <key>=<absolute file path>
-g= Guest OS
-latency= Latency sensitivity (low|normal|high)
-m=0 Size in MB of memory
Expand Down
26 changes: 26 additions & 0 deletions govc/test/vm.bats
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ load test_helper
assert_line "Memory: 1024MB"
assert_line "CPU: 2 vCPU(s)"

# test extraConfig
run govc vm.change -e "guestinfo.a=1" -e "guestinfo.b=2" -vm $id
assert_success

Expand All @@ -150,6 +151,18 @@ load test_helper
assert_line "guestinfo.a: 1"
assert_line "guestinfo.b: 2"

# test extraConfigFile
run govc vm.change -f "guestinfo.c=this_is_not_an_existing.file" -vm $id
assert_failure

echo -n "3" > "$BATS_TMPDIR/extraConfigFile.conf"
run govc vm.change -f "guestinfo.d=$BATS_TMPDIR/extraConfigFile.conf" -vm $id
assert_success

run govc vm.info -e $id
assert_success
assert_line "guestinfo.d: 3"

run govc vm.change -sync-time-with-host=false -vm $id
assert_success

Expand Down Expand Up @@ -419,6 +432,19 @@ load test_helper
assert_success
refute_line "guestinfo.a: 2"

# test extraConfigFile
run govc vm.change -f "guestinfo.b=this_is_not_an_existing.file" -vm $id
assert_failure
echo -n "3" > "$BATS_TMPDIR/extraConfigFile.conf"
run govc vm.change -f "guestinfo.b=$BATS_TMPDIR/extraConfigFile.conf" -vm $id
assert_success
run govc vm.info -e $id
assert_success
assert_line "guestinfo.b: 3"
run govc vm.change -f "guestinfo.b=" -vm $id
assert_success
refute_line "guestinfo.b: 3"

# test optional bool Config
run govc vm.change -nested-hv-enabled=true -vm "$id"
assert_success
Expand Down
38 changes: 33 additions & 5 deletions govc/vm/change.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"flag"
"fmt"
"io/ioutil"
"reflect"
"strings"

Expand All @@ -43,13 +44,39 @@ func (e *extraConfig) Set(v string) error {
return nil
}

type extraConfigFile []types.BaseOptionValue

func (e *extraConfigFile) String() string {
return fmt.Sprintf("%v", *e)
}

func (e *extraConfigFile) Set(v string) error {
r := strings.SplitN(v, "=", 2)
if len(r) < 2 {
return fmt.Errorf("failed to parse extraConfigFile: %s", v)
}

var fileContents = ""
if len(r[1]) > 0 {
contents, err := ioutil.ReadFile(r[1])
if err != nil {
return fmt.Errorf("failed to parse extraConfigFile '%s': %w", v, err)
}
fileContents = string(contents)
}

*e = append(*e, &types.OptionValue{Key: r[0], Value: fileContents})
return nil
}

type change struct {
*flags.VirtualMachineFlag
*flags.ResourceAllocationFlag

types.VirtualMachineConfigSpec
extraConfig extraConfig
Latency string
extraConfig extraConfig
extraConfigFile extraConfigFile
Latency string
}

func init() {
Expand Down Expand Up @@ -119,6 +146,7 @@ func (cmd *change) Register(ctx context.Context, f *flag.FlagSet) {
f.StringVar(&cmd.Annotation, "annotation", "", "VM description")
f.StringVar(&cmd.Uuid, "uuid", "", "BIOS UUID")
f.Var(&cmd.extraConfig, "e", "ExtraConfig. <key>=<value>")
f.Var(&cmd.extraConfigFile, "f", "ExtraConfig. <key>=<absolute path to file>")

f.Var(flags.NewOptionalBool(&cmd.NestedHVEnabled), "nested-hv-enabled", "Enable nested hardware-assisted virtualization")
cmd.Tools = &types.ToolsConfigInfo{}
Expand All @@ -140,6 +168,8 @@ Examples:
# Enable both cpu and memory hotplug on a guest:
govc vm.change -vm $vm -cpu-hot-add-enabled -memory-hot-add-enabled
govc vm.change -vm $vm -e guestinfo.vmname $vm
# Read the contents of a file and use them as ExtraConfig value
govc vm.change -vm $vm -f guestinfo.data="$(realpath .)/vmdata.config"
# Read the variable set above inside the guest:
vmware-rpctool "info-get guestinfo.vmname"
govc vm.change -vm $vm -latency high
Expand All @@ -164,9 +194,7 @@ func (cmd *change) Run(ctx context.Context, f *flag.FlagSet) error {
return flag.ErrHelp
}

if len(cmd.extraConfig) > 0 {
cmd.VirtualMachineConfigSpec.ExtraConfig = cmd.extraConfig
}
cmd.VirtualMachineConfigSpec.ExtraConfig = append(cmd.extraConfig, cmd.extraConfigFile...)

setAllocation(&cmd.CpuAllocation)
setAllocation(&cmd.MemoryAllocation)
Expand Down

0 comments on commit b5426eb

Please sign in to comment.