From 5b4d52150638665b6378a65b3d579c74718c5bff Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Mon, 5 Dec 2016 22:14:46 -0800 Subject: [PATCH] Add support for file backed serialport devices (#637) --- govc/CHANGELOG.md | 4 ++++ govc/USAGE.md | 10 +++++++++- govc/device/serial/connect.go | 35 +++++++++++++++++++++++++++++++++-- govc/flags/version.go | 2 +- govc/test/boot_order_test.sh | 9 ++++----- govc/test/device.bats | 6 ++++++ object/virtual_device_list.go | 10 ++++++++++ 7 files changed, 67 insertions(+), 9 deletions(-) diff --git a/govc/CHANGELOG.md b/govc/CHANGELOG.md index 4e314edab..0a635faa7 100644 --- a/govc/CHANGELOG.md +++ b/govc/CHANGELOG.md @@ -1,5 +1,9 @@ # changelog +### unreleased + +* Add support for file backed serialport devices + ### 0.12.0 (2016-12-01) * Add optional '-host' flag to datastore download/tail commands diff --git a/govc/USAGE.md b/govc/USAGE.md index c91803db5..0d01bcfa4 100644 --- a/govc/USAGE.md +++ b/govc/USAGE.md @@ -517,14 +517,22 @@ Options: ## device.serial.connect ``` -Usage: govc device.serial.connect [OPTIONS] +Usage: govc device.serial.connect [OPTIONS] URI Connect service URI to serial port. +If "-" is given as URI, connects file backed device with file name of +device name + .log suffix in the VM Config.Files.LogDirectory. + +Defaults to the first serial port if no DEVICE is given. + Examples: govc device.ls | grep serialport- govc device.serial.connect -vm $vm -device serialport-8000 telnet://:33233 govc device.info -vm $vm serialport-* + govc device.serial.connect -vm $vm "[datastore1] $vm/console.log" + govc device.serial.connect -vm $vm - + govc datastore.tail -f $vm/serialport-8000.log Options: -client=false Use client direction diff --git a/govc/device/serial/connect.go b/govc/device/serial/connect.go index 93f22ba2a..84cb99484 100644 --- a/govc/device/serial/connect.go +++ b/govc/device/serial/connect.go @@ -19,9 +19,12 @@ package serial import ( "context" "flag" + "fmt" + "path" "github.com/vmware/govmomi/govc/cli" "github.com/vmware/govmomi/govc/flags" + "github.com/vmware/govmomi/vim25/mo" ) type connect struct { @@ -45,13 +48,25 @@ func (cmd *connect) Register(ctx context.Context, f *flag.FlagSet) { f.BoolVar(&cmd.client, "client", false, "Use client direction") } +func (cmd *connect) Usage() string { + return "URI" +} + func (cmd *connect) Description() string { return `Connect service URI to serial port. +If "-" is given as URI, connects file backed device with file name of +device name + .log suffix in the VM Config.Files.LogDirectory. + +Defaults to the first serial port if no DEVICE is given. + Examples: govc device.ls | grep serialport- govc device.serial.connect -vm $vm -device serialport-8000 telnet://:33233 - govc device.info -vm $vm serialport-*` + govc device.info -vm $vm serialport-* + govc device.serial.connect -vm $vm "[datastore1] $vm/console.log" + govc device.serial.connect -vm $vm - + govc datastore.tail -f $vm/serialport-8000.log` } func (cmd *connect) Process(ctx context.Context) error { @@ -62,6 +77,10 @@ func (cmd *connect) Process(ctx context.Context) error { } func (cmd *connect) Run(ctx context.Context, f *flag.FlagSet) error { + if f.NArg() != 1 { + return flag.ErrHelp + } + vm, err := cmd.VirtualMachine() if err != nil { return err @@ -81,5 +100,17 @@ func (cmd *connect) Run(ctx context.Context, f *flag.FlagSet) error { return err } - return vm.EditDevice(ctx, devices.ConnectSerialPort(d, f.Arg(0), cmd.client, cmd.proxy)) + uri := f.Arg(0) + + if uri == "-" { + var mvm mo.VirtualMachine + err = vm.Properties(ctx, vm.Reference(), []string{"config.files.logDirectory"}, &mvm) + if err != nil { + return err + } + + uri = path.Join(mvm.Config.Files.LogDirectory, fmt.Sprintf("%s.log", devices.Name(d))) + } + + return vm.EditDevice(ctx, devices.ConnectSerialPort(d, uri, cmd.client, cmd.proxy)) } diff --git a/govc/flags/version.go b/govc/flags/version.go index eea915658..65b9f39a2 100644 --- a/govc/flags/version.go +++ b/govc/flags/version.go @@ -21,7 +21,7 @@ import ( "strings" ) -const Version = "0.12.0" +const Version = "0.12.1" type version []int diff --git a/govc/test/boot_order_test.sh b/govc/test/boot_order_test.sh index e52d16be9..cc97f6ee4 100755 --- a/govc/test/boot_order_test.sh +++ b/govc/test/boot_order_test.sh @@ -53,16 +53,15 @@ govc vm.power -off $id govc device.cdrom.eject -vm $id -host_ip=$(echo $vnc | awk -F@ '{print $2}' | awk -F: '{print $1}') -serial_port=33233 govc device.serial.add -vm $id > /dev/null -govc device.serial.connect -vm $id $uri telnet://:$serial_port +govc device.serial.connect -vm $id - echo "booting from network, will timeout then boot from disk..." govc vm.power -on $id -# capture serial console -echo | nc $host_ip $serial_port 2>/dev/null & +# serial console log +device=$(govc device.ls -vm "$id" | grep serialport- | awk '{print $1}') +govc datastore.tail -f "$id/$device.log" & ip=$(govc vm.ip $id) diff --git a/govc/test/device.bats b/govc/test/device.bats index cf06618fa..ab252e342 100755 --- a/govc/test/device.bats +++ b/govc/test/device.bats @@ -151,6 +151,12 @@ load test_helper run govc device.info -vm $vm $id assert_success + run govc device.serial.connect -vm $vm - + assert_success + + run govc device.info -vm $vm $id + assert_line "Summary: File [$GOVC_DATASTORE] $vm/${id}.log" + uri=telnet://:33233 run govc device.serial.connect -vm $vm -device $id $uri assert_success diff --git a/object/virtual_device_list.go b/object/virtual_device_list.go index 9caa3cc68..e81ca4e67 100644 --- a/object/virtual_device_list.go +++ b/object/virtual_device_list.go @@ -672,6 +672,16 @@ func (l VirtualDeviceList) CreateSerialPort() (*types.VirtualSerialPort, error) // ConnectSerialPort connects a serial port to a server or client uri. func (l VirtualDeviceList) ConnectSerialPort(device *types.VirtualSerialPort, uri string, client bool, proxyuri string) *types.VirtualSerialPort { + if strings.HasPrefix(uri, "[") { + device.Backing = &types.VirtualSerialPortFileBackingInfo{ + VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{ + FileName: uri, + }, + } + + return device + } + direction := types.VirtualDeviceURIBackingOptionDirectionServer if client { direction = types.VirtualDeviceURIBackingOptionDirectionClient