diff --git a/agent/action/add_dynamic_disk.go b/agent/action/add_dynamic_disk.go new file mode 100644 index 000000000..9b8291137 --- /dev/null +++ b/agent/action/add_dynamic_disk.go @@ -0,0 +1,57 @@ +package action + +import ( + "errors" + + boshplatform "github.com/cloudfoundry/bosh-agent/v2/platform" + boshsettings "github.com/cloudfoundry/bosh-agent/v2/settings" + bosherr "github.com/cloudfoundry/bosh-utils/errors" +) + +type AddDynamicDiskAction struct { + settingsService boshsettings.Service + platform boshplatform.Platform +} + +func NewAddDynamicDiskAction(settingsService boshsettings.Service, platform boshplatform.Platform) AddDynamicDiskAction { + return AddDynamicDiskAction{ + settingsService: settingsService, + platform: platform, + } +} + +func (a AddDynamicDiskAction) Run(diskCID string, diskHint interface{}) (interface{}, error) { + err := a.settingsService.LoadSettings() + if err != nil { + return nil, bosherr.WrapError(err, "Refreshing the settings") + } + + currentSettings := a.settingsService.GetSettings() + + diskSetting := currentSettings.PersistentDiskSettingsFromHint(diskCID, diskHint) + if err := a.platform.SetupDynamicDisk(diskSetting); err != nil { + return "", bosherr.WrapError(err, "Setting up dynamic disk") + } + + return map[string]string{}, nil +} + +func (a AddDynamicDiskAction) IsAsynchronous(_ ProtocolVersion) bool { + return true +} + +func (a AddDynamicDiskAction) IsPersistent() bool { + return false +} + +func (a AddDynamicDiskAction) IsLoggable() bool { + return true +} + +func (a AddDynamicDiskAction) Resume() (interface{}, error) { + return nil, errors.New("not supported") +} + +func (a AddDynamicDiskAction) Cancel() error { + return errors.New("not supported") +} diff --git a/agent/action/add_dynamic_disk_test.go b/agent/action/add_dynamic_disk_test.go new file mode 100644 index 000000000..6d8634e96 --- /dev/null +++ b/agent/action/add_dynamic_disk_test.go @@ -0,0 +1,49 @@ +package action + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/pkg/errors" + + "github.com/cloudfoundry/bosh-agent/v2/platform/platformfakes" + "github.com/cloudfoundry/bosh-agent/v2/settings" + fakesettings "github.com/cloudfoundry/bosh-agent/v2/settings/fakes" +) + +var _ = Describe("AddDynamicDiskAction", func() { + var ( + action AddDynamicDiskAction + settingsService *fakesettings.FakeSettingsService + platform *platformfakes.FakePlatform + ) + + BeforeEach(func() { + settingsService = &fakesettings.FakeSettingsService{} + platform = &platformfakes.FakePlatform{} + action = NewAddDynamicDiskAction(settingsService, platform) + }) + + It("sets up dynamic disk", func() { + result, err := action.Run("diskCID", "/dev/sdb") + + Expect(err).ToNot(HaveOccurred()) + Expect(result).To(Equal(map[string]string{})) + Expect(platform.SetupDynamicDiskCallCount()).To(Equal(1)) + Expect(platform.SetupDynamicDiskArgsForCall(0)).To(Equal(settings.DiskSettings{ + ID: "diskCID", + Path: "/dev/sdb", + VolumeID: "/dev/sdb", + })) + }) + + Context("when setting up dynamic disk fails", func() { + BeforeEach(func() { + platform.SetupDynamicDiskReturns(errors.New("Could not setup")) + }) + + It("should raise error", func() { + _, err := action.Run("diskCID", "/dev/sdb") + Expect(err).To(HaveOccurred()) + }) + }) +}) diff --git a/agent/action/concrete_factory.go b/agent/action/concrete_factory.go index 957b8d53f..fc9307c87 100644 --- a/agent/action/concrete_factory.go +++ b/agent/action/concrete_factory.go @@ -85,6 +85,8 @@ func NewFactory( "unmount_disk": NewUnmountDisk(settingsService, platform), "add_persistent_disk": NewAddPersistentDiskAction(settingsService), "remove_persistent_disk": NewRemovePersistentDiskAction(settingsService), + "add_dynamic_disk": NewAddDynamicDiskAction(settingsService, platform), + "remove_dynamic_disk": NewRemoveDynamicDiskAction(platform), // ARP cache management "delete_arp_entries": NewDeleteARPEntries(platform), diff --git a/agent/action/remove_dynamic_disk.go b/agent/action/remove_dynamic_disk.go new file mode 100644 index 000000000..b5e4fa444 --- /dev/null +++ b/agent/action/remove_dynamic_disk.go @@ -0,0 +1,46 @@ +package action + +import ( + "errors" + + boshplatform "github.com/cloudfoundry/bosh-agent/v2/platform" + bosherr "github.com/cloudfoundry/bosh-utils/errors" +) + +type RemoveDynamicDiskAction struct { + platform boshplatform.Platform +} + +func NewRemoveDynamicDiskAction(platform boshplatform.Platform) RemoveDynamicDiskAction { + return RemoveDynamicDiskAction{ + platform: platform, + } +} + +func (a RemoveDynamicDiskAction) Run(diskCID string) (interface{}, error) { + if err := a.platform.CleanupDynamicDisk(diskCID); err != nil { + return "", bosherr.WrapError(err, "Setting up dynamic disk") + } + + return map[string]string{}, nil +} + +func (a RemoveDynamicDiskAction) IsAsynchronous(_ ProtocolVersion) bool { + return true +} + +func (a RemoveDynamicDiskAction) IsPersistent() bool { + return false +} + +func (a RemoveDynamicDiskAction) IsLoggable() bool { + return true +} + +func (a RemoveDynamicDiskAction) Resume() (interface{}, error) { + return nil, errors.New("not supported") +} + +func (a RemoveDynamicDiskAction) Cancel() error { + return errors.New("not supported") +} diff --git a/agent/action/remove_dynamic_disk_test.go b/agent/action/remove_dynamic_disk_test.go new file mode 100644 index 000000000..458a31dec --- /dev/null +++ b/agent/action/remove_dynamic_disk_test.go @@ -0,0 +1,41 @@ +package action + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/pkg/errors" + + "github.com/cloudfoundry/bosh-agent/v2/platform/platformfakes" +) + +var _ = Describe("RemoveDynamicDiskAction", func() { + var ( + action RemoveDynamicDiskAction + platform *platformfakes.FakePlatform + ) + + BeforeEach(func() { + platform = &platformfakes.FakePlatform{} + action = NewRemoveDynamicDiskAction(platform) + }) + + It("cleans up dynamic disk", func() { + result, err := action.Run("diskCID") + + Expect(err).ToNot(HaveOccurred()) + Expect(result).To(Equal(map[string]string{})) + Expect(platform.CleanupDynamicDiskCallCount()).To(Equal(1)) + Expect(platform.CleanupDynamicDiskArgsForCall(0)).To(Equal("diskCID")) + }) + + Context("when cleaning up dynamic disk fails", func() { + BeforeEach(func() { + platform.CleanupDynamicDiskReturns(errors.New("Could not setup")) + }) + + It("should raise error", func() { + _, err := action.Run("diskCID") + Expect(err).To(HaveOccurred()) + }) + }) +}) diff --git a/platform/dummy_platform.go b/platform/dummy_platform.go index c4a5632c0..5f4aefcab 100644 --- a/platform/dummy_platform.go +++ b/platform/dummy_platform.go @@ -222,6 +222,14 @@ func (p dummyPlatform) SetupRawEphemeralDisks(devices []boshsettings.DiskSetting return } +func (p dummyPlatform) SetupDynamicDisk(diskSetting boshsettings.DiskSettings) (err error) { + return +} + +func (p dummyPlatform) CleanupDynamicDisk(diskCID string) (err error) { + return +} + func (p dummyPlatform) SetupDataDir(_ boshsettings.JobDir, _ boshsettings.RunDir) error { dataDir := p.dirProvider.DataDir() diff --git a/platform/linux_platform.go b/platform/linux_platform.go index f9c33400a..10a3f8bec 100644 --- a/platform/linux_platform.go +++ b/platform/linux_platform.go @@ -778,6 +778,32 @@ func (p linux) SetupRawEphemeralDisks(devices []boshsettings.DiskSettings) (err return nil } +func (p linux) SetupDynamicDisk(diskSetting boshsettings.DiskSettings) error { + devicePath, timedOut, err := p.devicePathResolver.GetRealDevicePath(diskSetting) + if err != nil { + return bosherr.WrapError(err, "Getting dynamic disk real device path") + } + if timedOut { + return bosherr.WrapErrorf(err, "Timed out resolving device path for %s", diskSetting.ID) + } + + symlinkDestination := filepath.Join(p.dirProvider.DataDynamicDisksDir(), diskSetting.ID) + if err := p.fs.Symlink(devicePath, symlinkDestination); err != nil { + return bosherr.WrapError(err, "Symlinking dynamic disk real device path") + } + + return nil +} + +func (p linux) CleanupDynamicDisk(diskCID string) error { + symlinkDestination := filepath.Join(p.dirProvider.DataDynamicDisksDir(), diskCID) + if err := p.fs.RemoveAll(symlinkDestination); err != nil { + return bosherr.WrapError(err, "Removing dynamic disk symlink") + } + + return nil +} + func (p linux) SetupDataDir(jobConfig boshsettings.JobDir, runConfig boshsettings.RunDir) error { dataDir := p.dirProvider.DataDir() @@ -805,6 +831,12 @@ func (p linux) SetupDataDir(jobConfig boshsettings.JobDir, runConfig boshsetting return bosherr.WrapErrorf(err, "Making %s dir", jobsDir) } + dynamicDisksDir := p.dirProvider.DataDynamicDisksDir() + err = p.fs.MkdirAll(dynamicDisksDir, persistentDiskPermissions) + if err != nil { + return bosherr.WrapErrorf(err, "Making %s dir", dynamicDisksDir) + } + sensitiveDir := p.dirProvider.SensitiveBlobsDir() err = p.fs.MkdirAll(sensitiveDir, blobsDirPermissions) if err != nil { @@ -835,6 +867,11 @@ func (p linux) SetupDataDir(jobConfig boshsettings.JobDir, runConfig boshsetting return bosherr.WrapErrorf(err, "chown %s", sensitiveDir) } + _, _, _, err = p.cmdRunner.RunCommand("chown", "root:vcap", dynamicDisksDir) + if err != nil { + return bosherr.WrapErrorf(err, "chown %s", dynamicDisksDir) + } + packagesDir := p.dirProvider.PkgDir() err = p.fs.MkdirAll(packagesDir, packagesDirPermissions) if err != nil { diff --git a/platform/linux_platform_test.go b/platform/linux_platform_test.go index 892493a39..55ac7e471 100644 --- a/platform/linux_platform_test.go +++ b/platform/linux_platform_test.go @@ -958,6 +958,63 @@ fake-base-path/data/sys/log/*.log fake-base-path/data/sys/log/.*.log fake-base-p }) }) + Describe("SetupDynamicDisk", func() { + BeforeEach(func() { + devicePathResolver.GetRealDevicePathStub = func(diskSettings boshsettings.DiskSettings) (string, bool, error) { + return diskSettings.Path, false, nil + } + }) + + It("sets up dynamic disk symlink", func() { + err := platform.SetupDynamicDisk(boshsettings.DiskSettings{ID: "diskID", Path: "/dev/sdb"}) + Expect(err).NotTo(HaveOccurred()) + + sysStats := fs.GetFileTestStat("/fake-dir/data/dynamic_disks/diskID") + Expect(sysStats).ToNot(BeNil()) + Expect(sysStats.FileType).To(Equal(fakesys.FakeFileTypeSymlink)) + Expect(sysStats.SymlinkTarget).To(Equal("/dev/sdb")) + }) + + It("returns error if resolving device path fails", func() { + devicePathResolver.GetRealDevicePathStub = func(diskSettings boshsettings.DiskSettings) (string, bool, error) { + return "", false, errors.New("fake-get-real-device-path-err") + } + + err := platform.SetupDynamicDisk(boshsettings.DiskSettings{ID: "diskID", Path: "/dev/sdb"}) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("fake-get-real-device-path-err")) + }) + + It("returns error if resolving device path times out", func() { + devicePathResolver.GetRealDevicePathStub = func(diskSettings boshsettings.DiskSettings) (string, bool, error) { + return "", true, nil + } + + err := platform.SetupDynamicDisk(boshsettings.DiskSettings{ID: "diskID", Path: "/dev/sdb"}) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Timed out resolving device path for diskID")) + }) + }) + + Describe("CleanupDynamicDisk", func() { + BeforeEach(func() { + devicePathResolver.GetRealDevicePathStub = func(diskSettings boshsettings.DiskSettings) (string, bool, error) { + return diskSettings.Path, false, nil + } + }) + + It("removes dynamic disk symlink", func() { + err := platform.SetupDynamicDisk(boshsettings.DiskSettings{ID: "diskID", Path: "/dev/sdb"}) + Expect(err).NotTo(HaveOccurred()) + + err = platform.CleanupDynamicDisk("diskID") + Expect(err).NotTo(HaveOccurred()) + + sysStats := fs.GetFileTestStat("/fake-dir/data/dynamic_disks/diskID") + Expect(sysStats).To(BeNil()) + }) + }) + Describe("SetupEphemeralDiskWithPath", func() { var ( labelPrefix string @@ -1882,7 +1939,18 @@ Number Start End Size File system Name Flags Expect(sysLogStats).ToNot(BeNil()) Expect(sysLogStats.FileType).To(Equal(fakesys.FakeFileTypeDir)) Expect(sysLogStats.FileMode).To(Equal(os.FileMode(0755))) - Expect(cmdRunner.RunCommands[4]).To(Equal([]string{"chown", "root:vcap", "/fake-dir/data/packages"})) + Expect(cmdRunner.RunCommands[5]).To(Equal([]string{"chown", "root:vcap", "/fake-dir/data/packages"})) + }) + + It("creates dynamic disks directory in data directory", func() { + err := platform.SetupDataDir(boshsettings.JobDir{}, boshsettings.RunDir{}) + Expect(err).NotTo(HaveOccurred()) + + sysLogStats := fs.GetFileTestStat("/fake-dir/data/dynamic_disks") + Expect(sysLogStats).ToNot(BeNil()) + Expect(sysLogStats.FileType).To(Equal(fakesys.FakeFileTypeDir)) + Expect(sysLogStats.FileMode).To(Equal(os.FileMode(0700))) + Expect(cmdRunner.RunCommands[4]).To(Equal([]string{"chown", "root:vcap", "/fake-dir/data/dynamic_disks"})) }) Context("when a tmpfs for the sensitive directories is requested", func() { @@ -2060,7 +2128,7 @@ Number Start End Size File system Name Flags Expect(sysRunStats).ToNot(BeNil()) Expect(sysRunStats.FileType).To(Equal(fakesys.FakeFileTypeDir)) Expect(sysRunStats.FileMode).To(Equal(os.FileMode(0750))) - Expect(cmdRunner.RunCommands[5]).To(Equal([]string{"chown", "root:vcap", "/fake-dir/data/sys/run"})) + Expect(cmdRunner.RunCommands[6]).To(Equal([]string{"chown", "root:vcap", "/fake-dir/data/sys/run"})) }) It("mounts tmpfs to sys/run", func() { diff --git a/platform/platform_interface.go b/platform/platform_interface.go index e4cc77c38..d7f8d55a3 100644 --- a/platform/platform_interface.go +++ b/platform/platform_interface.go @@ -88,6 +88,8 @@ type Platform interface { IsPersistentDiskMounted(diskSettings boshsettings.DiskSettings) (result bool, err error) IsPersistentDiskMountable(diskSettings boshsettings.DiskSettings) (bool, error) AssociateDisk(name string, settings boshsettings.DiskSettings) error + SetupDynamicDisk(diskSetting boshsettings.DiskSettings) error + CleanupDynamicDisk(diskCID string) error GetFileContentsFromCDROM(filePath string) (contents []byte, err error) GetFilesContentsFromDisk(diskPath string, fileNames []string) (contents [][]byte, err error) diff --git a/platform/platformfakes/fake_platform.go b/platform/platformfakes/fake_platform.go index ea84e4fd9..9dbed7309 100644 --- a/platform/platformfakes/fake_platform.go +++ b/platform/platformfakes/fake_platform.go @@ -8,13 +8,13 @@ import ( "github.com/cloudfoundry/bosh-agent/v2/infrastructure/devicepathresolver" "github.com/cloudfoundry/bosh-agent/v2/platform" "github.com/cloudfoundry/bosh-agent/v2/platform/cert" + "github.com/cloudfoundry/bosh-agent/v2/platform/net/ip" "github.com/cloudfoundry/bosh-agent/v2/platform/vitals" "github.com/cloudfoundry/bosh-agent/v2/servicemanager" "github.com/cloudfoundry/bosh-agent/v2/settings" "github.com/cloudfoundry/bosh-agent/v2/settings/directories" "github.com/cloudfoundry/bosh-utils/fileutil" "github.com/cloudfoundry/bosh-utils/system" - boship "github.com/cloudfoundry/bosh-agent/v2/platform/net/ip" ) type FakePlatform struct { @@ -54,6 +54,17 @@ type FakePlatform struct { associateDiskReturnsOnCall map[int]struct { result1 error } + CleanupDynamicDiskStub func(string) error + cleanupDynamicDiskMutex sync.RWMutex + cleanupDynamicDiskArgsForCall []struct { + arg1 string + } + cleanupDynamicDiskReturns struct { + result1 error + } + cleanupDynamicDiskReturnsOnCall map[int]struct { + result1 error + } CreateUserStub func(string, string) error createUserMutex sync.RWMutex createUserArgsForCall []struct { @@ -151,9 +162,10 @@ type FakePlatform struct { getCopierReturnsOnCall map[int]struct { result1 fileutil.Copier } - GetDefaultNetworkStub func() (settings.Network, error) + GetDefaultNetworkStub func(ip.IPProtocol) (settings.Network, error) getDefaultNetworkMutex sync.RWMutex getDefaultNetworkArgsForCall []struct { + arg1 ip.IPProtocol } getDefaultNetworkReturns struct { result1 settings.Network @@ -495,6 +507,17 @@ type FakePlatform struct { setupDataDirReturnsOnCall map[int]struct { result1 error } + SetupDynamicDiskStub func(settings.DiskSettings) error + setupDynamicDiskMutex sync.RWMutex + setupDynamicDiskArgsForCall []struct { + arg1 settings.DiskSettings + } + setupDynamicDiskReturns struct { + result1 error + } + setupDynamicDiskReturnsOnCall map[int]struct { + result1 error + } SetupEphemeralDiskWithPathStub func(string, *uint64, string) error setupEphemeralDiskWithPathMutex sync.RWMutex setupEphemeralDiskWithPathArgsForCall []struct { @@ -908,6 +931,67 @@ func (fake *FakePlatform) AssociateDiskReturnsOnCall(i int, result1 error) { }{result1} } +func (fake *FakePlatform) CleanupDynamicDisk(arg1 string) error { + fake.cleanupDynamicDiskMutex.Lock() + ret, specificReturn := fake.cleanupDynamicDiskReturnsOnCall[len(fake.cleanupDynamicDiskArgsForCall)] + fake.cleanupDynamicDiskArgsForCall = append(fake.cleanupDynamicDiskArgsForCall, struct { + arg1 string + }{arg1}) + stub := fake.CleanupDynamicDiskStub + fakeReturns := fake.cleanupDynamicDiskReturns + fake.recordInvocation("CleanupDynamicDisk", []interface{}{arg1}) + fake.cleanupDynamicDiskMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakePlatform) CleanupDynamicDiskCallCount() int { + fake.cleanupDynamicDiskMutex.RLock() + defer fake.cleanupDynamicDiskMutex.RUnlock() + return len(fake.cleanupDynamicDiskArgsForCall) +} + +func (fake *FakePlatform) CleanupDynamicDiskCalls(stub func(string) error) { + fake.cleanupDynamicDiskMutex.Lock() + defer fake.cleanupDynamicDiskMutex.Unlock() + fake.CleanupDynamicDiskStub = stub +} + +func (fake *FakePlatform) CleanupDynamicDiskArgsForCall(i int) string { + fake.cleanupDynamicDiskMutex.RLock() + defer fake.cleanupDynamicDiskMutex.RUnlock() + argsForCall := fake.cleanupDynamicDiskArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakePlatform) CleanupDynamicDiskReturns(result1 error) { + fake.cleanupDynamicDiskMutex.Lock() + defer fake.cleanupDynamicDiskMutex.Unlock() + fake.CleanupDynamicDiskStub = nil + fake.cleanupDynamicDiskReturns = struct { + result1 error + }{result1} +} + +func (fake *FakePlatform) CleanupDynamicDiskReturnsOnCall(i int, result1 error) { + fake.cleanupDynamicDiskMutex.Lock() + defer fake.cleanupDynamicDiskMutex.Unlock() + fake.CleanupDynamicDiskStub = nil + if fake.cleanupDynamicDiskReturnsOnCall == nil { + fake.cleanupDynamicDiskReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.cleanupDynamicDiskReturnsOnCall[i] = struct { + result1 error + }{result1} +} + func (fake *FakePlatform) CreateUser(arg1 string, arg2 string) error { fake.createUserMutex.Lock() ret, specificReturn := fake.createUserReturnsOnCall[len(fake.createUserArgsForCall)] @@ -1421,17 +1505,18 @@ func (fake *FakePlatform) GetCopierReturnsOnCall(i int, result1 fileutil.Copier) }{result1} } -func (fake *FakePlatform) GetDefaultNetwork(ipProtocol boship.IPProtocol) (settings.Network, error) { +func (fake *FakePlatform) GetDefaultNetwork(arg1 ip.IPProtocol) (settings.Network, error) { fake.getDefaultNetworkMutex.Lock() ret, specificReturn := fake.getDefaultNetworkReturnsOnCall[len(fake.getDefaultNetworkArgsForCall)] fake.getDefaultNetworkArgsForCall = append(fake.getDefaultNetworkArgsForCall, struct { - }{}) + arg1 ip.IPProtocol + }{arg1}) stub := fake.GetDefaultNetworkStub fakeReturns := fake.getDefaultNetworkReturns - fake.recordInvocation("GetDefaultNetwork", []interface{}{}) + fake.recordInvocation("GetDefaultNetwork", []interface{}{arg1}) fake.getDefaultNetworkMutex.Unlock() if stub != nil { - return stub() + return stub(arg1) } if specificReturn { return ret.result1, ret.result2 @@ -1445,12 +1530,19 @@ func (fake *FakePlatform) GetDefaultNetworkCallCount() int { return len(fake.getDefaultNetworkArgsForCall) } -func (fake *FakePlatform) GetDefaultNetworkCalls(stub func() (settings.Network, error)) { +func (fake *FakePlatform) GetDefaultNetworkCalls(stub func(ip.IPProtocol) (settings.Network, error)) { fake.getDefaultNetworkMutex.Lock() defer fake.getDefaultNetworkMutex.Unlock() fake.GetDefaultNetworkStub = stub } +func (fake *FakePlatform) GetDefaultNetworkArgsForCall(i int) ip.IPProtocol { + fake.getDefaultNetworkMutex.RLock() + defer fake.getDefaultNetworkMutex.RUnlock() + argsForCall := fake.getDefaultNetworkArgsForCall[i] + return argsForCall.arg1 +} + func (fake *FakePlatform) GetDefaultNetworkReturns(result1 settings.Network, result2 error) { fake.getDefaultNetworkMutex.Lock() defer fake.getDefaultNetworkMutex.Unlock() @@ -3188,6 +3280,67 @@ func (fake *FakePlatform) SetupDataDirReturnsOnCall(i int, result1 error) { }{result1} } +func (fake *FakePlatform) SetupDynamicDisk(arg1 settings.DiskSettings) error { + fake.setupDynamicDiskMutex.Lock() + ret, specificReturn := fake.setupDynamicDiskReturnsOnCall[len(fake.setupDynamicDiskArgsForCall)] + fake.setupDynamicDiskArgsForCall = append(fake.setupDynamicDiskArgsForCall, struct { + arg1 settings.DiskSettings + }{arg1}) + stub := fake.SetupDynamicDiskStub + fakeReturns := fake.setupDynamicDiskReturns + fake.recordInvocation("SetupDynamicDisk", []interface{}{arg1}) + fake.setupDynamicDiskMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakePlatform) SetupDynamicDiskCallCount() int { + fake.setupDynamicDiskMutex.RLock() + defer fake.setupDynamicDiskMutex.RUnlock() + return len(fake.setupDynamicDiskArgsForCall) +} + +func (fake *FakePlatform) SetupDynamicDiskCalls(stub func(settings.DiskSettings) error) { + fake.setupDynamicDiskMutex.Lock() + defer fake.setupDynamicDiskMutex.Unlock() + fake.SetupDynamicDiskStub = stub +} + +func (fake *FakePlatform) SetupDynamicDiskArgsForCall(i int) settings.DiskSettings { + fake.setupDynamicDiskMutex.RLock() + defer fake.setupDynamicDiskMutex.RUnlock() + argsForCall := fake.setupDynamicDiskArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakePlatform) SetupDynamicDiskReturns(result1 error) { + fake.setupDynamicDiskMutex.Lock() + defer fake.setupDynamicDiskMutex.Unlock() + fake.SetupDynamicDiskStub = nil + fake.setupDynamicDiskReturns = struct { + result1 error + }{result1} +} + +func (fake *FakePlatform) SetupDynamicDiskReturnsOnCall(i int, result1 error) { + fake.setupDynamicDiskMutex.Lock() + defer fake.setupDynamicDiskMutex.Unlock() + fake.SetupDynamicDiskStub = nil + if fake.setupDynamicDiskReturnsOnCall == nil { + fake.setupDynamicDiskReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.setupDynamicDiskReturnsOnCall[i] = struct { + result1 error + }{result1} +} + func (fake *FakePlatform) SetupEphemeralDiskWithPath(arg1 string, arg2 *uint64, arg3 string) error { fake.setupEphemeralDiskWithPathMutex.Lock() ret, specificReturn := fake.setupEphemeralDiskWithPathReturnsOnCall[len(fake.setupEphemeralDiskWithPathArgsForCall)] @@ -4350,130 +4503,6 @@ func (fake *FakePlatform) UnmountPersistentDiskReturnsOnCall(i int, result1 bool func (fake *FakePlatform) Invocations() map[string][][]interface{} { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() - fake.addUserToGroupsMutex.RLock() - defer fake.addUserToGroupsMutex.RUnlock() - fake.adjustPersistentDiskPartitioningMutex.RLock() - defer fake.adjustPersistentDiskPartitioningMutex.RUnlock() - fake.associateDiskMutex.RLock() - defer fake.associateDiskMutex.RUnlock() - fake.createUserMutex.RLock() - defer fake.createUserMutex.RUnlock() - fake.deleteARPEntryWithIPMutex.RLock() - defer fake.deleteARPEntryWithIPMutex.RUnlock() - fake.deleteEphemeralUsersMatchingMutex.RLock() - defer fake.deleteEphemeralUsersMatchingMutex.RUnlock() - fake.getAgentSettingsPathMutex.RLock() - defer fake.getAgentSettingsPathMutex.RUnlock() - fake.getAuditLoggerMutex.RLock() - defer fake.getAuditLoggerMutex.RUnlock() - fake.getCertManagerMutex.RLock() - defer fake.getCertManagerMutex.RUnlock() - fake.getCompressorMutex.RLock() - defer fake.getCompressorMutex.RUnlock() - fake.getConfiguredNetworkInterfacesMutex.RLock() - defer fake.getConfiguredNetworkInterfacesMutex.RUnlock() - fake.getCopierMutex.RLock() - defer fake.getCopierMutex.RUnlock() - fake.getDefaultNetworkMutex.RLock() - defer fake.getDefaultNetworkMutex.RUnlock() - fake.getDevicePathResolverMutex.RLock() - defer fake.getDevicePathResolverMutex.RUnlock() - fake.getDirProviderMutex.RLock() - defer fake.getDirProviderMutex.RUnlock() - fake.getEphemeralDiskPathMutex.RLock() - defer fake.getEphemeralDiskPathMutex.RUnlock() - fake.getFileContentsFromCDROMMutex.RLock() - defer fake.getFileContentsFromCDROMMutex.RUnlock() - fake.getFilesContentsFromDiskMutex.RLock() - defer fake.getFilesContentsFromDiskMutex.RUnlock() - fake.getFsMutex.RLock() - defer fake.getFsMutex.RUnlock() - fake.getHostPublicKeyMutex.RLock() - defer fake.getHostPublicKeyMutex.RUnlock() - fake.getLogsTarProviderMutex.RLock() - defer fake.getLogsTarProviderMutex.RUnlock() - fake.getMonitCredentialsMutex.RLock() - defer fake.getMonitCredentialsMutex.RUnlock() - fake.getPersistentDiskSettingsPathMutex.RLock() - defer fake.getPersistentDiskSettingsPathMutex.RUnlock() - fake.getRunnerMutex.RLock() - defer fake.getRunnerMutex.RUnlock() - fake.getServiceManagerMutex.RLock() - defer fake.getServiceManagerMutex.RUnlock() - fake.getUpdateSettingsPathMutex.RLock() - defer fake.getUpdateSettingsPathMutex.RUnlock() - fake.getVitalsServiceMutex.RLock() - defer fake.getVitalsServiceMutex.RUnlock() - fake.isMountPointMutex.RLock() - defer fake.isMountPointMutex.RUnlock() - fake.isPersistentDiskMountableMutex.RLock() - defer fake.isPersistentDiskMountableMutex.RUnlock() - fake.isPersistentDiskMountedMutex.RLock() - defer fake.isPersistentDiskMountedMutex.RUnlock() - fake.migratePersistentDiskMutex.RLock() - defer fake.migratePersistentDiskMutex.RUnlock() - fake.mountPersistentDiskMutex.RLock() - defer fake.mountPersistentDiskMutex.RUnlock() - fake.prepareForNetworkingChangeMutex.RLock() - defer fake.prepareForNetworkingChangeMutex.RUnlock() - fake.removeDevToolsMutex.RLock() - defer fake.removeDevToolsMutex.RUnlock() - fake.removeStaticLibrariesMutex.RLock() - defer fake.removeStaticLibrariesMutex.RUnlock() - fake.saveDNSRecordsMutex.RLock() - defer fake.saveDNSRecordsMutex.RUnlock() - fake.setTimeWithNtpServersMutex.RLock() - defer fake.setTimeWithNtpServersMutex.RUnlock() - fake.setUserPasswordMutex.RLock() - defer fake.setUserPasswordMutex.RUnlock() - fake.setupBlobsDirMutex.RLock() - defer fake.setupBlobsDirMutex.RUnlock() - fake.setupBoshSettingsDiskMutex.RLock() - defer fake.setupBoshSettingsDiskMutex.RUnlock() - fake.setupCanRestartDirMutex.RLock() - defer fake.setupCanRestartDirMutex.RUnlock() - fake.setupDataDirMutex.RLock() - defer fake.setupDataDirMutex.RUnlock() - fake.setupEphemeralDiskWithPathMutex.RLock() - defer fake.setupEphemeralDiskWithPathMutex.RUnlock() - fake.setupHomeDirMutex.RLock() - defer fake.setupHomeDirMutex.RUnlock() - fake.setupHostnameMutex.RLock() - defer fake.setupHostnameMutex.RUnlock() - fake.setupIPv6Mutex.RLock() - defer fake.setupIPv6Mutex.RUnlock() - fake.setupLogDirMutex.RLock() - defer fake.setupLogDirMutex.RUnlock() - fake.setupLoggingAndAuditingMutex.RLock() - defer fake.setupLoggingAndAuditingMutex.RUnlock() - fake.setupLogrotateMutex.RLock() - defer fake.setupLogrotateMutex.RUnlock() - fake.setupMonitUserMutex.RLock() - defer fake.setupMonitUserMutex.RUnlock() - fake.setupNetworkingMutex.RLock() - defer fake.setupNetworkingMutex.RUnlock() - fake.setupOptDirMutex.RLock() - defer fake.setupOptDirMutex.RUnlock() - fake.setupRawEphemeralDisksMutex.RLock() - defer fake.setupRawEphemeralDisksMutex.RUnlock() - fake.setupRecordsJSONPermissionMutex.RLock() - defer fake.setupRecordsJSONPermissionMutex.RUnlock() - fake.setupRootDiskMutex.RLock() - defer fake.setupRootDiskMutex.RUnlock() - fake.setupRuntimeConfigurationMutex.RLock() - defer fake.setupRuntimeConfigurationMutex.RUnlock() - fake.setupSSHMutex.RLock() - defer fake.setupSSHMutex.RUnlock() - fake.setupSharedMemoryMutex.RLock() - defer fake.setupSharedMemoryMutex.RUnlock() - fake.setupTmpDirMutex.RLock() - defer fake.setupTmpDirMutex.RUnlock() - fake.shutdownMutex.RLock() - defer fake.shutdownMutex.RUnlock() - fake.startMonitMutex.RLock() - defer fake.startMonitMutex.RUnlock() - fake.unmountPersistentDiskMutex.RLock() - defer fake.unmountPersistentDiskMutex.RUnlock() copiedInvocations := map[string][][]interface{}{} for key, value := range fake.invocations { copiedInvocations[key] = value diff --git a/platform/windows_platform.go b/platform/windows_platform.go index b0a20b46e..3e4d16e63 100644 --- a/platform/windows_platform.go +++ b/platform/windows_platform.go @@ -548,6 +548,14 @@ func (p WindowsPlatform) SetupRawEphemeralDisks(devices []boshsettings.DiskSetti return } +func (p WindowsPlatform) SetupDynamicDisk(diskSetting boshsettings.DiskSettings) (err error) { + return +} + +func (p WindowsPlatform) CleanupDynamicDisk(diskID string) (err error) { + return +} + func (p WindowsPlatform) SetupDataDir(_ boshsettings.JobDir, _ boshsettings.RunDir) error { dataDir := p.dirProvider.DataDir() sysDataDir := filepath.Join(dataDir, "sys") diff --git a/settings/directories/directories_provider.go b/settings/directories/directories_provider.go index 067ca3754..3f3fb6031 100644 --- a/settings/directories/directories_provider.go +++ b/settings/directories/directories_provider.go @@ -68,6 +68,10 @@ func (p Provider) DataJobsDir() string { return filepath.Join(p.DataDir(), "jobs") } +func (p Provider) DataDynamicDisksDir() string { + return filepath.Join(p.DataDir(), "dynamic_disks") +} + func (p Provider) JobLogDir(jobName string) string { return filepath.Join(p.DataDir(), "sys", "log", jobName) }