Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions pkg/vsphere/toolbox/backdoor.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,7 @@ type backdoorChannel struct {
}

func (b *backdoorChannel) Start() error {
isVM, err := vmcheck.IsVirtualWorld()
if err != nil {
return err
}

if !isVM {
if !vmcheck.IsVirtualCPU() {
return ErrNotVirtualWorld
}

Expand Down
9 changes: 7 additions & 2 deletions pkg/vsphere/toolbox/backdoor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@ func TestBackdoorChannel(t *testing.T) {
}

for _, f := range funcs {
if err := f(); err != nil {
t.Skip(err.Error())
err := f()

if err != nil {
if err == ErrNotVirtualWorld {
t.SkipNow()
}
t.Fatal(err)
}
}

Expand Down
181 changes: 181 additions & 0 deletions pkg/vsphere/toolbox/guest_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// Copyright 2017 VMware, Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package toolbox

import (
"bytes"
"fmt"
"net"

"github.com/davecgh/go-xdr/xdr2"
)

// Defs from: open-vm-tools/lib/guestRpc/nicinfo.x

type TypedIPAddress struct {
Type int32
Address []byte
}

type IPAddressEntry struct {
Address TypedIPAddress
PrefixLength uint32
Origin *int32 `xdr:"optional"`
Status *int32 `xdr:"optional"`
}

type InetCidrRouteEntry struct {
Dest TypedIPAddress
PrefixLength uint32
NextHop *TypedIPAddress `xdr:"optional"`
IfIndex uint32
Type int32
Metric uint32
}

type DNSConfigInfo struct {
HostName *string `xdr:"optional"`
DomainName *string `xdr:"optional"`
Servers []TypedIPAddress
Search *string `xdr:"optional"`
}

type WinsConfigInfo struct {
Primary TypedIPAddress
Secondary TypedIPAddress
}

type DhcpConfigInfo struct {
Enabled bool
Settings string
}

type GuestNicV3 struct {
MacAddress string
IPs []IPAddressEntry
DNSConfigInfo *DNSConfigInfo `xdr:"optional"`
WinsConfigInfo *WinsConfigInfo `xdr:"optional"`
DhcpConfigInfov4 *DhcpConfigInfo `xdr:"optional"`
DhcpConfigInfov6 *DhcpConfigInfo `xdr:"optional"`
}

type NicInfoV3 struct {
Nics []GuestNicV3
Routes []InetCidrRouteEntry
DNSConfigInfo *DNSConfigInfo `xdr:"optional"`
WinsConfigInfo *WinsConfigInfo `xdr:"optional"`
DhcpConfigInfov4 *DhcpConfigInfo `xdr:"optional"`
DhcpConfigInfov6 *DhcpConfigInfo `xdr:"optional"`
}

type GuestNicInfo struct {
Version int32
V3 *NicInfoV3 `xdr:"optional"`
}

func EncodeXDR(val interface{}) ([]byte, error) {
var buf bytes.Buffer

_, err := xdr.Marshal(&buf, val)
if err != nil {
return nil, err
}

return buf.Bytes(), nil
}

func DecodeXDR(buf []byte, val interface{}) error {
r := bytes.NewReader(buf)
_, err := xdr.Unmarshal(r, val)
return err
}

func NewGuestNicInfo() *GuestNicInfo {
return &GuestNicInfo{
Version: 3,
V3: &NicInfoV3{},
}
}

func (nic *GuestNicV3) AddIP(addr net.Addr) {
ip, ok := addr.(*net.IPNet)
if !ok {
return
}

kind := int32(1) // IAT_IPV4
if ip.IP.To4() == nil {
kind = 2 // IAT_IPV6
} else {
ip.IP = ip.IP.To4() // convert to 4-byte representation
}

size, _ := ip.Mask.Size()

// nicinfo.x defines enum IpAddressStatus, but vmtoolsd only uses IAS_PREFERRED
var status int32 = 1 // IAS_PREFERRED

e := IPAddressEntry{
Address: TypedIPAddress{
Type: kind,
Address: []byte(ip.IP),
},
PrefixLength: uint32(size),
Status: &status,
}

nic.IPs = append(nic.IPs, e)
}

func GuestInfoCommand(kind int, req []byte) []byte {
request := fmt.Sprintf("SetGuestInfo %d ", kind)
return append([]byte(request), req...)
}

func DefaultGuestNicInfo() *GuestNicInfo {
proto := NewGuestNicInfo()
info := proto.V3

ifs, _ := net.Interfaces()

for _, i := range ifs {
if i.Flags&net.FlagLoopback == net.FlagLoopback {
continue
}

nic := GuestNicV3{
MacAddress: i.HardwareAddr.String(),
}

addrs, _ := i.Addrs()

for _, addr := range addrs {
nic.AddIP(addr)
}

info.Nics = append(info.Nics, nic)
}

return proto
}

func GuestInfoNicInfoRequest() ([]byte, error) {
r, err := EncodeXDR(DefaultGuestNicInfo())
if err != nil {
return nil, err
}

return GuestInfoCommand(9 /*INFO_IPADDRESS_V3*/, r), nil
}
49 changes: 49 additions & 0 deletions pkg/vsphere/toolbox/guest_info_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2017 VMware, Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package toolbox

import (
"net"
"reflect"
"testing"
)

func TestDefaultGuestNicProto(t *testing.T) {
p := DefaultGuestNicInfo()

info := p.V3

for _, nic := range info.Nics {
_, err := net.ParseMAC(nic.MacAddress)
if err != nil {
t.Errorf("invalid MAC %s: %s", nic.MacAddress, err)
}
}

b, err := EncodeXDR(p)
if err != nil {
t.Fatal(err)
}

var dp GuestNicInfo
err = DecodeXDR(b, &dp)
if err != nil {
t.Fatal(err)
}

if !reflect.DeepEqual(p, &dp) {
t.Error("decode mismatch")
}
}
20 changes: 20 additions & 0 deletions pkg/vsphere/toolbox/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ func (s *Service) SetOption(args []byte) ([]byte, error) {
if err != nil {
return nil, err
}

s.SendGuestInfo()
}
default:
// TODO: handle other options...
Expand Down Expand Up @@ -268,3 +270,21 @@ func (s *Service) CapabilitiesRegister([]byte) ([]byte, error) {

return nil, nil
}

func (s *Service) SendGuestInfo() {
info := []func() ([]byte, error){
GuestInfoNicInfoRequest,
}

for i, r := range info {
b, err := r()

if err == nil {
_, err = s.out.Request(b)
}

if err != nil {
log.Printf("SendGuestInfo %d: %s", i, err)
}
}
}
1 change: 1 addition & 0 deletions pkg/vsphere/toolbox/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ func TestServiceErrors(t *testing.T) {
out.reply,
rpciERR,
rpciOK,
rpciOK,
append(rpciOK, foo...),
rpciERR,
)
Expand Down
2 changes: 1 addition & 1 deletion pkg/vsphere/toolbox/toolbox-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ scp "${opts[@]}" "$GOPATH"/bin/toolbox{,.test} "core@${ip}:"

if [ -n "$test" ] ; then
echo "Running toolbox tests..."
ssh "${opts[@]}" "core@${ip}" sudo ./toolbox.test -test.v -test.run TestServiceRunESX -toolbox.testesx \
ssh "${opts[@]}" "core@${ip}" ./toolbox.test -test.v -test.run TestServiceRunESX -toolbox.testesx \
-toolbox.testpid="$$" -toolbox.powerState="$state" &

echo "Waiting for VM ip from toolbox..."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ Verify container VM guest IP is reported
${name}= Generate Random String 15
${rc} ${id}= Run And Return Rc And Output docker %{VCH-PARAMS} run --name ${name} -d busybox /bin/top
Should Be Equal As Integers ${rc} 0
${rc} ${output}= Run And Return Rc And Output govc vm.ip ${name}-*
${rc} ${ip}= Run And Return Rc And Output govc vm.ip ${name}-*
Should Be Equal As Integers ${rc} 0
${rc} ${output}= Run And Return Rc And Output govc vm.info -json ${name}-* | jq -r .VirtualMachines[].Guest.Net[].IpAddress[]
Should Be Equal As Integers ${rc} 0
Should Contain ${output} ${ip}

Stop container VM using guest shutdown
${rc}= Run And Return Rc docker %{VCH-PARAMS} pull busybox
Expand Down
13 changes: 13 additions & 0 deletions vendor/github.com/davecgh/go-xdr/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading