func (s *provisionerSuite) TestNewState(c *gc.C) { apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { return nil }) st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) c.Assert(st, gc.NotNil) st = storageprovisioner.NewState(apiCaller, names.NewEnvironTag("87927ace-9e41-4fd5-8103-1a6fb5ff7eb4")) c.Assert(st, gc.NotNil) c.Assert(func() { storageprovisioner.NewState(apiCaller, names.NewUnitTag("mysql/0")) }, gc.PanicMatches, "expected EnvironTag or MachineTag, got names.UnitTag") }
func (s *provisionerSuite) TestSetFilesystemAttachmentInfo(c *gc.C) { filesystemAttachments := []params.FilesystemAttachment{{ FilesystemTag: "filesystem-100", MachineTag: "machine-200", Info: params.FilesystemAttachmentInfo{ MountPoint: "/srv", }, }} var callCount int apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { c.Check(objType, gc.Equals, "StorageProvisioner") c.Check(version, gc.Equals, 0) c.Check(id, gc.Equals, "") c.Check(request, gc.Equals, "SetFilesystemAttachmentInfo") c.Check(arg, jc.DeepEquals, params.FilesystemAttachments{filesystemAttachments}) c.Assert(result, gc.FitsTypeOf, ¶ms.ErrorResults{}) *(result.(*params.ErrorResults)) = params.ErrorResults{ Results: []params.ErrorResult{{Error: nil}}, } callCount++ return nil }) st, err := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) c.Assert(err, jc.ErrorIsNil) errorResults, err := st.SetFilesystemAttachmentInfo(filesystemAttachments) c.Check(err, jc.ErrorIsNil) c.Check(callCount, gc.Equals, 1) c.Assert(errorResults, gc.HasLen, 1) c.Assert(errorResults[0].Error, gc.IsNil) }
func (s *provisionerSuite) TestVolumeBlockDevices(c *gc.C) { blockDeviceResults := []params.BlockDeviceResult{{ Result: storage.BlockDevice{ DeviceName: "xvdf1", HardwareId: "kjlaksjdlasjdklasd123123", Size: 1024, }, }} apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { c.Check(objType, gc.Equals, "StorageProvisioner") c.Check(version, gc.Equals, 0) c.Check(id, gc.Equals, "") c.Check(request, gc.Equals, "VolumeBlockDevices") c.Check(arg, gc.DeepEquals, params.MachineStorageIds{ Ids: []params.MachineStorageId{{ MachineTag: "machine-100", AttachmentTag: "volume-100", }}, }) c.Assert(result, gc.FitsTypeOf, ¶ms.BlockDeviceResults{}) *(result.(*params.BlockDeviceResults)) = params.BlockDeviceResults{ Results: blockDeviceResults, } return nil }) st, err := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) c.Assert(err, jc.ErrorIsNil) volumes, err := st.VolumeBlockDevices([]params.MachineStorageId{{ MachineTag: "machine-100", AttachmentTag: "volume-100", }}) c.Check(err, jc.ErrorIsNil) c.Assert(volumes, jc.DeepEquals, blockDeviceResults) }
func (s *provisionerSuite) testOpWithTags( c *gc.C, opName string, apiCall func(*storageprovisioner.State, []names.Tag) ([]params.ErrorResult, error), ) { var callCount int apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { c.Check(objType, gc.Equals, "StorageProvisioner") c.Check(version, gc.Equals, 0) c.Check(id, gc.Equals, "") c.Check(request, gc.Equals, opName) c.Check(arg, gc.DeepEquals, params.Entities{Entities: []params.Entity{{Tag: "volume-100"}}}) c.Assert(result, gc.FitsTypeOf, ¶ms.ErrorResults{}) *(result.(*params.ErrorResults)) = params.ErrorResults{ Results: []params.ErrorResult{{Error: nil}}, } callCount++ return nil }) st, err := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) c.Assert(err, jc.ErrorIsNil) volumes := []names.Tag{names.NewVolumeTag("100")} errorResults, err := apiCall(st, volumes) c.Check(err, jc.ErrorIsNil) c.Check(callCount, gc.Equals, 1) c.Assert(errorResults, jc.DeepEquals, []params.ErrorResult{{}}) }
func (config MachineManifoldConfig) newWorker(a agent.Agent, apiCaller base.APICaller) (worker.Worker, error) { if config.Clock == nil { return nil, dependency.ErrMissing } cfg := a.CurrentConfig() api, err := storageprovisioner.NewState(apiCaller, cfg.Tag()) if err != nil { return nil, errors.Trace(err) } tag, ok := cfg.Tag().(names.MachineTag) if !ok { return nil, errors.Errorf("this manifold may only be used inside a machine agent") } storageDir := filepath.Join(cfg.DataDir(), "storage") w, err := NewStorageProvisioner(Config{ Scope: tag, StorageDir: storageDir, Volumes: api, Filesystems: api, Life: api, Registry: provider.CommonStorageProviders(), Machines: api, Status: api, Clock: config.Clock, }) if err != nil { return nil, errors.Trace(err) } return w, nil }
func (s *provisionerSuite) TestFilesystemParams(c *gc.C) { var callCount int apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { c.Check(objType, gc.Equals, "StorageProvisioner") c.Check(version, gc.Equals, 0) c.Check(id, gc.Equals, "") c.Check(request, gc.Equals, "FilesystemParams") c.Check(arg, gc.DeepEquals, params.Entities{Entities: []params.Entity{{"filesystem-100"}}}) c.Assert(result, gc.FitsTypeOf, ¶ms.FilesystemParamsResults{}) *(result.(*params.FilesystemParamsResults)) = params.FilesystemParamsResults{ Results: []params.FilesystemParamsResult{{ Result: params.FilesystemParams{ FilesystemTag: "filesystem-100", Size: 1024, Provider: "loop", }, }}, } callCount++ return nil }) st, err := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) c.Assert(err, jc.ErrorIsNil) filesystemParams, err := st.FilesystemParams([]names.FilesystemTag{names.NewFilesystemTag("100")}) c.Check(err, jc.ErrorIsNil) c.Check(callCount, gc.Equals, 1) c.Assert(filesystemParams, jc.DeepEquals, []params.FilesystemParamsResult{{ Result: params.FilesystemParams{ FilesystemTag: "filesystem-100", Size: 1024, Provider: "loop", }, }}) }
func (s *provisionerSuite) testClientError(c *gc.C, apiCall func(*storageprovisioner.State) error) { apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { return errors.New("blargh") }) st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) err := apiCall(st) c.Check(err, gc.ErrorMatches, "blargh") }
func (s *provisionerSuite) TestWatchVolumesServerError(c *gc.C) { apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { *(result.(*params.StringsWatchResults)) = params.StringsWatchResults{ Results: []params.StringsWatchResult{{ Error: ¶ms.Error{Message: "MSG", Code: "621"}, }}, } return nil }) st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) _, err := st.WatchVolumes() c.Check(err, gc.ErrorMatches, "MSG") }
func (s *provisionerSuite) TestVolumeParamsServerError(c *gc.C) { apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { *(result.(*params.VolumeParamsResults)) = params.VolumeParamsResults{ Results: []params.VolumeParamsResult{{ Error: ¶ms.Error{Message: "MSG", Code: "621"}, }}, } return nil }) st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) results, err := st.VolumeParams([]names.VolumeTag{names.NewVolumeTag("100")}) c.Assert(err, jc.ErrorIsNil) c.Assert(results, gc.HasLen, 1) c.Check(results[0].Error, gc.ErrorMatches, "MSG") }
func (s *provisionerSuite) TestWatchForEnvironConfigChanges(c *gc.C) { apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { c.Check(objType, gc.Equals, "StorageProvisioner") c.Check(version, gc.Equals, 0) c.Check(id, gc.Equals, "") c.Check(request, gc.Equals, "WatchForEnvironConfigChanges") c.Assert(result, gc.FitsTypeOf, ¶ms.NotifyWatchResult{}) *(result.(*params.NotifyWatchResult)) = params.NotifyWatchResult{ NotifyWatcherId: "abc", } return errors.New("FAIL") }) st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) _, err := st.WatchForEnvironConfigChanges() c.Assert(err, gc.ErrorMatches, "FAIL") }
func (s *provisionerSuite) TestEnvironConfig(c *gc.C) { inputCfg := coretesting.EnvironConfig(c) apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { c.Check(objType, gc.Equals, "StorageProvisioner") c.Check(version, gc.Equals, 0) c.Check(id, gc.Equals, "") c.Check(request, gc.Equals, "EnvironConfig") c.Assert(result, gc.FitsTypeOf, ¶ms.EnvironConfigResult{}) *(result.(*params.EnvironConfigResult)) = params.EnvironConfigResult{ Config: inputCfg.AllAttrs(), } return nil }) st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) outputCfg, err := st.EnvironConfig() c.Assert(err, jc.ErrorIsNil) c.Assert(outputCfg.AllAttrs(), jc.DeepEquals, inputCfg.AllAttrs()) }
func (s *provisionerSuite) TestVolumes(c *gc.C) { var callCount int apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { c.Check(objType, gc.Equals, "StorageProvisioner") c.Check(version, gc.Equals, 0) c.Check(id, gc.Equals, "") c.Check(request, gc.Equals, "Volumes") c.Check(arg, gc.DeepEquals, params.Entities{Entities: []params.Entity{{"volume-100"}}}) c.Assert(result, gc.FitsTypeOf, ¶ms.VolumeResults{}) *(result.(*params.VolumeResults)) = params.VolumeResults{ Results: []params.VolumeResult{{ Result: params.Volume{ VolumeTag: "volume-100", Info: params.VolumeInfo{ VolumeId: "volume-id", HardwareId: "abc", Size: 1024, }, }, }}, } callCount++ return nil }) st, err := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) c.Assert(err, jc.ErrorIsNil) volumes, err := st.Volumes([]names.VolumeTag{names.NewVolumeTag("100")}) c.Check(err, jc.ErrorIsNil) c.Check(callCount, gc.Equals, 1) c.Assert(volumes, jc.DeepEquals, []params.VolumeResult{{ Result: params.Volume{ VolumeTag: "volume-100", Info: params.VolumeInfo{ VolumeId: "volume-id", HardwareId: "abc", Size: 1024, }, }, }}) }
func (s *provisionerSuite) TestSetVolumeInfo(c *gc.C) { var callCount int apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { c.Check(objType, gc.Equals, "StorageProvisioner") c.Check(version, gc.Equals, 0) c.Check(id, gc.Equals, "") c.Check(request, gc.Equals, "SetVolumeInfo") c.Check(arg, gc.DeepEquals, params.Volumes{ Volumes: []params.Volume{{ VolumeTag: "volume-100", Info: params.VolumeInfo{ VolumeId: "123", HardwareId: "abc", Size: 1024, Persistent: true, }, }}, }) c.Assert(result, gc.FitsTypeOf, ¶ms.ErrorResults{}) *(result.(*params.ErrorResults)) = params.ErrorResults{ Results: []params.ErrorResult{{Error: nil}}, } callCount++ return nil }) st, err := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) c.Assert(err, jc.ErrorIsNil) volumes := []params.Volume{{ VolumeTag: "volume-100", Info: params.VolumeInfo{ VolumeId: "123", HardwareId: "abc", Size: 1024, Persistent: true, }, }} errorResults, err := st.SetVolumeInfo(volumes) c.Check(err, jc.ErrorIsNil) c.Check(callCount, gc.Equals, 1) c.Assert(errorResults, gc.HasLen, 1) c.Assert(errorResults[0].Error, gc.IsNil) }
// ModelManifold returns a dependency.Manifold that runs a storage provisioner. func ModelManifold(config ModelManifoldConfig) dependency.Manifold { return dependency.Manifold{ Inputs: []string{config.APICallerName, config.ClockName, config.EnvironName}, Start: func(context dependency.Context) (worker.Worker, error) { var clock clock.Clock if err := context.Get(config.ClockName, &clock); err != nil { return nil, errors.Trace(err) } var apiCaller base.APICaller if err := context.Get(config.APICallerName, &apiCaller); err != nil { return nil, errors.Trace(err) } var environ environs.Environ if err := context.Get(config.EnvironName, &environ); err != nil { return nil, errors.Trace(err) } api, err := storageprovisioner.NewState(apiCaller, config.Scope) if err != nil { return nil, errors.Trace(err) } w, err := NewStorageProvisioner(Config{ Scope: config.Scope, StorageDir: config.StorageDir, Volumes: api, Filesystems: api, Life: api, Registry: environ, Machines: api, Status: api, Clock: clock, }) if err != nil { return nil, errors.Trace(err) } return w, nil }, } }
func (s *provisionerSuite) TestWatchBlockDevices(c *gc.C) { apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { c.Check(objType, gc.Equals, "StorageProvisioner") c.Check(version, gc.Equals, 0) c.Check(id, gc.Equals, "") c.Check(request, gc.Equals, "WatchBlockDevices") c.Assert(arg, gc.DeepEquals, params.Entities{ Entities: []params.Entity{{"machine-123"}}, }) c.Assert(result, gc.FitsTypeOf, ¶ms.NotifyWatchResults{}) *(result.(*params.NotifyWatchResults)) = params.NotifyWatchResults{ Results: []params.NotifyWatchResult{{ Error: ¶ms.Error{Message: "FAIL"}, }}, } return nil }) st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) _, err := st.WatchBlockDevices(names.NewMachineTag("123")) c.Check(err, gc.ErrorMatches, "FAIL") }
func (s *provisionerSuite) TestWatchVolumeAttachments(c *gc.C) { var callCount int apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { c.Check(objType, gc.Equals, "StorageProvisioner") c.Check(version, gc.Equals, 0) c.Check(id, gc.Equals, "") c.Check(request, gc.Equals, "WatchVolumeAttachments") c.Assert(result, gc.FitsTypeOf, ¶ms.MachineStorageIdsWatchResults{}) *(result.(*params.MachineStorageIdsWatchResults)) = params.MachineStorageIdsWatchResults{ Results: []params.MachineStorageIdsWatchResult{{ Error: ¶ms.Error{Message: "FAIL"}, }}, } callCount++ return nil }) st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) _, err := st.WatchVolumeAttachments() c.Check(err, gc.ErrorMatches, "FAIL") c.Check(callCount, gc.Equals, 1) }
func (s *provisionerSuite) TestVolumeAttachments(c *gc.C) { volumeAttachmentResults := []params.VolumeAttachmentResult{{ Result: params.VolumeAttachment{ MachineTag: "machine-100", VolumeTag: "volume-100", Info: params.VolumeAttachmentInfo{ DeviceName: "xvdf1", }, }, }} var callCount int apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { c.Check(objType, gc.Equals, "StorageProvisioner") c.Check(version, gc.Equals, 0) c.Check(id, gc.Equals, "") c.Check(request, gc.Equals, "VolumeAttachments") c.Check(arg, gc.DeepEquals, params.MachineStorageIds{ Ids: []params.MachineStorageId{{ MachineTag: "machine-100", AttachmentTag: "volume-100", }}, }) c.Assert(result, gc.FitsTypeOf, ¶ms.VolumeAttachmentResults{}) *(result.(*params.VolumeAttachmentResults)) = params.VolumeAttachmentResults{ Results: volumeAttachmentResults, } callCount++ return nil }) st, err := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) c.Assert(err, jc.ErrorIsNil) volumes, err := st.VolumeAttachments([]params.MachineStorageId{{ MachineTag: "machine-100", AttachmentTag: "volume-100", }}) c.Check(err, jc.ErrorIsNil) c.Check(callCount, gc.Equals, 1) c.Assert(volumes, jc.DeepEquals, volumeAttachmentResults) }
func (s *provisionerSuite) TestFilesystemAttachmentParams(c *gc.C) { paramsResults := []params.FilesystemAttachmentParamsResult{{ Result: params.FilesystemAttachmentParams{ MachineTag: "machine-100", FilesystemTag: "filesystem-100", InstanceId: "inst-ance", Provider: "loop", MountPoint: "/srv", }, }} var callCount int apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { c.Check(objType, gc.Equals, "StorageProvisioner") c.Check(version, gc.Equals, 0) c.Check(id, gc.Equals, "") c.Check(request, gc.Equals, "FilesystemAttachmentParams") c.Check(arg, gc.DeepEquals, params.MachineStorageIds{ Ids: []params.MachineStorageId{{ MachineTag: "machine-100", AttachmentTag: "filesystem-100", }}, }) c.Assert(result, gc.FitsTypeOf, ¶ms.FilesystemAttachmentParamsResults{}) *(result.(*params.FilesystemAttachmentParamsResults)) = params.FilesystemAttachmentParamsResults{ Results: paramsResults, } callCount++ return nil }) st, err := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) c.Assert(err, jc.ErrorIsNil) filesystemParams, err := st.FilesystemAttachmentParams([]params.MachineStorageId{{ MachineTag: "machine-100", AttachmentTag: "filesystem-100", }}) c.Check(err, jc.ErrorIsNil) c.Check(callCount, gc.Equals, 1) c.Assert(filesystemParams, jc.DeepEquals, paramsResults) }
func (s *provisionerSuite) TestLife(c *gc.C) { var callCount int apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { c.Check(objType, gc.Equals, "StorageProvisioner") c.Check(version, gc.Equals, 0) c.Check(id, gc.Equals, "") c.Check(request, gc.Equals, "Life") c.Check(arg, gc.DeepEquals, params.Entities{Entities: []params.Entity{{Tag: "volume-100"}}}) c.Assert(result, gc.FitsTypeOf, ¶ms.LifeResults{}) *(result.(*params.LifeResults)) = params.LifeResults{ Results: []params.LifeResult{{Life: params.Alive}}, } callCount++ return nil }) st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) volumes := []names.Tag{names.NewVolumeTag("100")} lifeResults, err := st.Life(volumes) c.Check(err, jc.ErrorIsNil) c.Check(callCount, gc.Equals, 1) c.Assert(lifeResults, jc.DeepEquals, []params.LifeResult{{Life: params.Alive}}) }
// Manifold returns a dependency.Manifold that runs a storage provisioner. func Manifold(config ManifoldConfig) dependency.Manifold { return dependency.Manifold{ Inputs: []string{config.APICallerName, config.ClockName}, Start: func(getResource dependency.GetResourceFunc) (worker.Worker, error) { var clock clock.Clock if err := getResource(config.ClockName, &clock); err != nil { return nil, errors.Trace(err) } var apiCaller base.APICaller if err := getResource(config.APICallerName, &apiCaller); err != nil { return nil, errors.Trace(err) } api, err := storageprovisioner.NewState(apiCaller, config.Scope) if err != nil { return nil, errors.Trace(err) } w, err := NewStorageProvisioner(Config{ Scope: config.Scope, StorageDir: config.StorageDir, Volumes: api, Filesystems: api, Life: api, Environ: api, Machines: api, Status: api, Clock: clock, }) if err != nil { return nil, errors.Trace(err) } return w, nil }, } }
// StorageProvisioner returns a version of the state that provides // functionality required by the storageprovisioner worker. // The scope tag defines the type of storage that is provisioned, either // either attached directly to a specified machine (machine scoped), // or provisioned on the underlying cloud for use by any machine in a // specified environment (environ scoped). func (st *State) StorageProvisioner(scope names.Tag) *storageprovisioner.State { return storageprovisioner.NewState(st, scope) }
func (s *provisionerSuite) TestNewStateMachineScope(c *gc.C) { st, err := storageprovisioner.NewState(nullAPICaller, names.NewMachineTag("123")) c.Check(err, jc.ErrorIsNil) c.Check(st, gc.NotNil) }
func (s *provisionerSuite) TestNewStateModelScope(c *gc.C) { st, err := storageprovisioner.NewState(nullAPICaller, names.NewModelTag("87927ace-9e41-4fd5-8103-1a6fb5ff7eb4")) c.Check(err, jc.ErrorIsNil) c.Check(st, gc.NotNil) }
func (s *provisionerSuite) TestNewStateBadScope(c *gc.C) { st, err := storageprovisioner.NewState(nullAPICaller, names.NewUnitTag("mysql/0")) c.Check(st, gc.IsNil) c.Check(err, gc.ErrorMatches, "expected ModelTag or MachineTag, got names.UnitTag") }