Skip to content

Commit e31cf1b

Browse files
committed
Make VMware tool paths configurable in VsphereGuestInfoSettingsSource
Add RpcToolPath and VmToolsdPath fields to VsphereGuestInfoSourceOptions, allowing agent.json to specify custom paths for rpctool and vmtoolsd executables. Defaults to "vmware-rpctool" and "vmtoolsd" when not set. This enables Windows deployments where the tools are located at "C:\Program Files\VMware\VMware Tools\rpctool.exe".
1 parent f407bf7 commit e31cf1b

File tree

4 files changed

+81
-11
lines changed

4 files changed

+81
-11
lines changed

infrastructure/settings_source_factory.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ type CDROMSourceOptions struct {
6464

6565
func (o CDROMSourceOptions) sourceOptionsInterface() {}
6666

67-
type VsphereGuestInfoSourceOptions struct{}
67+
type VsphereGuestInfoSourceOptions struct {
68+
RpcToolPath string
69+
VmToolsdPath string
70+
}
6871

6972
func (o VsphereGuestInfoSourceOptions) sourceOptionsInterface() {}
7073

@@ -143,6 +146,8 @@ func (f SettingsSourceFactory) buildWithoutRegistry() (boshsettings.Source, erro
143146
settingsSource = NewVsphereGuestInfoSettingsSource(
144147
f.platform,
145148
f.logger,
149+
typedOpts.RpcToolPath,
150+
typedOpts.VmToolsdPath,
146151
)
147152

148153
case InstanceMetadataSourceOptions:

infrastructure/settings_source_factory_test.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ var _ = Describe("SettingsSourceFactory", func() {
135135
})
136136

137137
It("returns a settings source that uses the VsphereGuestInfo to fetch settings", func() {
138-
vsphereGuestInfoSettingsSource := NewVsphereGuestInfoSettingsSource(platform, logger)
138+
vsphereGuestInfoSettingsSource := NewVsphereGuestInfoSettingsSource(platform, logger, "", "")
139139

140140
multiSettingsSource, err := NewMultiSettingsSource(logger, vsphereGuestInfoSettingsSource)
141141
Expect(err).ToNot(HaveOccurred())
@@ -204,6 +204,17 @@ var _ = Describe("SettingsSourceFactory", func() {
204204
Expect(sourceOptionsSlice[0]).To(Equal(VsphereGuestInfoSourceOptions{}))
205205
})
206206

207+
It("unmarshals VsphereGuestInfo source options with custom tool paths", func() {
208+
jsonStr := `[{"Type": "VsphereGuestInfo", "RpcToolPath": "C:\\Program Files\\VMware\\VMware Tools\\rpctool.exe", "VmToolsdPath": "C:\\Program Files\\VMware\\VMware Tools\\vmtoolsd.exe"}]`
209+
err := json.Unmarshal([]byte(jsonStr), &sourceOptionsSlice)
210+
Expect(err).ToNot(HaveOccurred())
211+
Expect(sourceOptionsSlice).To(HaveLen(1))
212+
Expect(sourceOptionsSlice[0]).To(Equal(VsphereGuestInfoSourceOptions{
213+
RpcToolPath: `C:\Program Files\VMware\VMware Tools\rpctool.exe`,
214+
VmToolsdPath: `C:\Program Files\VMware\VMware Tools\vmtoolsd.exe`,
215+
}))
216+
})
217+
207218
It("returns error when Type is missing", func() {
208219
jsonStr := `[{"URI": "http://example.com"}]`
209220
err := json.Unmarshal([]byte(jsonStr), &sourceOptionsSlice)

infrastructure/vsphere_guest_info_settings_source.go

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,41 @@ import (
1515
boshsettings "github.com/cloudfoundry/bosh-agent/v2/settings"
1616
)
1717

18+
const (
19+
defaultRpcToolPath = "vmware-rpctool"
20+
defaultVmToolsdPath = "vmtoolsd"
21+
)
22+
1823
type VsphereGuestInfoSettingsSource struct {
1924
platform boshplatform.Platform
2025
cmdRunner boshsys.CmdRunner
2126

27+
rpcToolPath string
28+
vmToolsdPath string
29+
2230
logTag string
2331
logger boshlog.Logger
2432
}
2533

2634
func NewVsphereGuestInfoSettingsSource(
2735
platform boshplatform.Platform,
2836
logger boshlog.Logger,
37+
rpcToolPath string,
38+
vmToolsdPath string,
2939
) *VsphereGuestInfoSettingsSource {
40+
if rpcToolPath == "" {
41+
rpcToolPath = defaultRpcToolPath
42+
}
43+
if vmToolsdPath == "" {
44+
vmToolsdPath = defaultVmToolsdPath
45+
}
3046
return &VsphereGuestInfoSettingsSource{
31-
platform: platform,
32-
cmdRunner: platform.GetRunner(),
33-
logTag: "VsphereGuestInfoSettingsSource",
34-
logger: logger,
47+
platform: platform,
48+
cmdRunner: platform.GetRunner(),
49+
rpcToolPath: rpcToolPath,
50+
vmToolsdPath: vmToolsdPath,
51+
logTag: "VsphereGuestInfoSettingsSource",
52+
logger: logger,
3553
}
3654
}
3755

@@ -87,12 +105,13 @@ func (s *VsphereGuestInfoSettingsSource) Settings() (boshsettings.Settings, erro
87105
return settings, nil
88106
}
89107

90-
// vmWareRPC runs the given command using vmware-rpctool, and if it fails, it runs the same command using vmtoolsd
91-
// for some versions, vmware-rpctool is significantly faster than vmtoolsd, so we use it if it is available.
108+
// vmWareRPC runs the given command using the configured rpctool path, and if it fails,
109+
// it runs the same command using the configured vmtoolsd path.
110+
// For some versions, vmware-rpctool is significantly faster than vmtoolsd, so we use it if it is available.
92111
func (s *VsphereGuestInfoSettingsSource) vmWareRPC(cmd string) (string, string, int, error) {
93-
stdOut, stdErr, status, err := s.cmdRunner.RunCommand("vmware-rpctool", cmd)
112+
stdOut, stdErr, status, err := s.cmdRunner.RunCommand(s.rpcToolPath, cmd)
94113
if err != nil || status != 0 {
95-
return s.cmdRunner.RunCommand("vmtoolsd", "--cmd", cmd)
114+
return s.cmdRunner.RunCommand(s.vmToolsdPath, "--cmd", cmd)
96115
}
97116
return stdOut, stdErr, status, nil
98117
}

infrastructure/vsphere_guest_info_settings_source_test.go

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ var _ = Describe("VsphereGuestInfoSettingsSource", func() {
3232
cmdRunner = fakes.NewFakeCmdRunner()
3333
platform.GetRunnerReturns(cmdRunner)
3434
logger := logger.NewLogger(logger.LevelNone)
35-
source = NewVsphereGuestInfoSettingsSource(platform, logger)
35+
source = NewVsphereGuestInfoSettingsSource(platform, logger, "", "")
3636
settings = boshsettings.Settings{AgentID: "123"}
3737
settingsBytes, err := json.Marshal(settings)
3838
Expect(err).ToNot(HaveOccurred())
@@ -134,5 +134,40 @@ var _ = Describe("VsphereGuestInfoSettingsSource", func() {
134134
Expect(cmdRunner.RunCommands[1]).To(Equal([]string{"vmware-rpctool", "info-set guestinfo.userdata ---"}))
135135
Expect(cmdRunner.RunCommands[2]).To(Equal([]string{"vmware-rpctool", "info-set guestinfo.userdata.encoding ''"}))
136136
})
137+
138+
Context("with custom tool paths", func() {
139+
var customSource *VsphereGuestInfoSettingsSource
140+
141+
BeforeEach(func() {
142+
l := logger.NewLogger(logger.LevelNone)
143+
customSource = NewVsphereGuestInfoSettingsSource(
144+
platform, l,
145+
`C:\Program Files\VMware\VMware Tools\rpctool.exe`,
146+
`C:\Program Files\VMware\VMware Tools\vmtoolsd.exe`,
147+
)
148+
})
149+
150+
It("uses the custom rpctool path", func() {
151+
cmdRunner.AddCmdResult(`C:\Program Files\VMware\VMware Tools\rpctool.exe info-get guestinfo.userdata`, fakes.FakeCmdResult{Stdout: encodedSettings})
152+
153+
settings, err := customSource.Settings()
154+
Expect(err).ToNot(HaveOccurred())
155+
Expect(settings.AgentID).To(Equal("123"))
156+
Expect(cmdRunner.RunCommands[0]).To(Equal([]string{`C:\Program Files\VMware\VMware Tools\rpctool.exe`, "info-get guestinfo.userdata"}))
157+
})
158+
159+
It("falls back to the custom vmtoolsd path when rpctool fails", func() {
160+
cmdRunner.AddCmdResult(`C:\Program Files\VMware\VMware Tools\rpctool.exe info-get guestinfo.userdata`, fakes.FakeCmdResult{Error: errors.New("fail"), ExitStatus: 1})
161+
cmdRunner.AddCmdResult(`C:\Program Files\VMware\VMware Tools\vmtoolsd.exe --cmd info-get guestinfo.userdata`, fakes.FakeCmdResult{Stdout: encodedSettings})
162+
cmdRunner.AddCmdResult(`C:\Program Files\VMware\VMware Tools\rpctool.exe info-set guestinfo.userdata ---`, fakes.FakeCmdResult{Error: errors.New("fail"), ExitStatus: 1})
163+
cmdRunner.AddCmdResult(`C:\Program Files\VMware\VMware Tools\rpctool.exe info-set guestinfo.userdata.encoding `, fakes.FakeCmdResult{Error: errors.New("fail"), ExitStatus: 1})
164+
165+
settings, err := customSource.Settings()
166+
Expect(err).ToNot(HaveOccurred())
167+
Expect(settings.AgentID).To(Equal("123"))
168+
Expect(cmdRunner.RunCommands[0]).To(Equal([]string{`C:\Program Files\VMware\VMware Tools\rpctool.exe`, "info-get guestinfo.userdata"}))
169+
Expect(cmdRunner.RunCommands[1]).To(Equal([]string{`C:\Program Files\VMware\VMware Tools\vmtoolsd.exe`, "--cmd", "info-get guestinfo.userdata"}))
170+
})
171+
})
137172
})
138173
})

0 commit comments

Comments
 (0)