Skip to content

Commit ecee0f1

Browse files
authored
Make VMware tool paths configurable in VsphereGuestInfoSettingsSource (#398)
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 ecee0f1

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)