func (s *assignCleanSuite) TestAssignUnitWithNonDynamicStorageCleanAvailable(c *gc.C) { registry.RegisterProvider("static", &dummy.StorageProvider{ IsDynamic: false, }) registry.RegisterEnvironStorageProviders("someprovider", "static") defer registry.RegisterProvider("static", nil) _, unit, _ := s.setupSingleStorage(c, "filesystem", "static") storageAttachments, err := s.State.UnitStorageAttachments(unit.UnitTag()) c.Assert(err, jc.ErrorIsNil) c.Assert(storageAttachments, gc.HasLen, 1) // Add a clean machine. clean, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, jc.ErrorIsNil) // assign the unit to a machine, requesting clean/empty. Since // the unit has non dynamic storage instances associated, // it will be forced onto a new machine. err = s.State.AssignUnit(unit, state.AssignCleanEmpty) c.Assert(err, jc.ErrorIsNil) // Check the machine on the unit is set. machineId, err := unit.AssignedMachineId() c.Assert(err, jc.ErrorIsNil) // Check that the machine isn't our clean one. c.Assert(machineId, gc.Not(gc.Equals), clean.Id()) }
func (s *DestroySuite) TestIgnoreNoVolumeSupport(c *gc.C) { staticProvider := &dummy.StorageProvider{ IsDynamic: true, StorageScope: storage.ScopeEnviron, SupportsFunc: func(storage.StorageKind) bool { return false }, } registry.RegisterProvider("filesystem", staticProvider) defer registry.RegisterProvider("filesystem", nil) registry.RegisterEnvironStorageProviders("anything, really", "filesystem") defer registry.ResetEnvironStorageProviders("anything, really") env := &mockEnviron{ config: configGetter(c), allInstances: func() ([]instance.Instance, error) { return nil, environs.ErrNoInstances }, } err := common.Destroy(env) c.Assert(err, jc.ErrorIsNil) // common.Destroy will ignore storage providers that don't support // volumes (until we have persistent filesystems, that is). staticProvider.CheckCallNames(c, "Dynamic", "Scope", "Supports") }
func (s *DestroySuite) TestDestroyVolumeErrors(c *gc.C) { volumeSource := &dummy.VolumeSource{ ListVolumesFunc: func() ([]string, error) { return []string{"vol-0", "vol-1", "vol-2"}, nil }, DestroyVolumesFunc: func(ids []string) []error { return []error{ nil, errors.New("cannot destroy vol-1"), errors.New("cannot destroy vol-2"), } }, } staticProvider := &dummy.StorageProvider{ IsDynamic: true, StorageScope: storage.ScopeEnviron, VolumeSourceFunc: func(*config.Config, *storage.Config) (storage.VolumeSource, error) { return volumeSource, nil }, } registry.RegisterProvider("environ", staticProvider) defer registry.RegisterProvider("environ", nil) registry.RegisterEnvironStorageProviders("anything, really", "environ") defer registry.ResetEnvironStorageProviders("anything, really") env := &mockEnviron{ config: configGetter(c), allInstances: func() ([]instance.Instance, error) { return nil, environs.ErrNoInstances }, } err := common.Destroy(env) c.Assert(err, gc.ErrorMatches, "destroying storage: destroying volumes: cannot destroy vol-1, cannot destroy vol-2") }
func (s *watcherSuite) TestWatchMachineStorage(c *gc.C) { registry.RegisterProvider( "envscoped", &dummy.StorageProvider{ StorageScope: storage.ScopeEnviron, }, ) registry.RegisterEnvironStorageProviders("dummy", "envscoped") defer registry.RegisterProvider("envscoped", nil) f := factory.NewFactory(s.BackingState) f.MakeMachine(c, &factory.MachineParams{ Volumes: []state.MachineVolumeParams{{ Volume: state.VolumeParams{ Pool: "envscoped", Size: 1024, }, }}, }) var results params.MachineStorageIdsWatchResults args := params.Entities{Entities: []params.Entity{{ Tag: s.State.EnvironTag().String(), }}} err := s.stateAPI.APICall( "StorageProvisioner", s.stateAPI.BestFacadeVersion("StorageProvisioner"), "", "WatchVolumeAttachments", args, &results) c.Assert(err, jc.ErrorIsNil) c.Assert(results.Results, gc.HasLen, 1) result := results.Results[0] c.Assert(result.Error, gc.IsNil) w := watcher.NewVolumeAttachmentsWatcher(s.stateAPI, result) select { case changes, ok := <-w.Changes(): c.Assert(ok, jc.IsTrue) c.Assert(changes, jc.SameContents, []params.MachineStorageId{{ MachineTag: "machine-1", AttachmentTag: "volume-0", }}) case <-time.After(coretesting.LongWait): c.Fatalf("timed out waiting for change") } select { case <-w.Changes(): c.Fatalf("received unexpected change") case <-time.After(coretesting.ShortWait): } statetesting.AssertStop(c, w) select { case _, ok := <-w.Changes(): c.Assert(ok, jc.IsFalse) case <-time.After(coretesting.LongWait): c.Fatalf("timed out waiting for watcher channel to be closed") } }
func (s *poolSuite) TestCreateInvalidConfig(c *gc.C) { registry.RegisterProvider("invalid", &dummy.StorageProvider{ ValidateConfigFunc: func(*storage.Config) error { return errors.New("no good") }, }) defer registry.RegisterProvider("invalid", nil) _, err := s.poolManager.Create("testpool", "invalid", nil) c.Assert(err, gc.ErrorMatches, "validating storage provider config: no good") }
func (s *providerRegistrySuite) TestRegisterProviderDuplicate(c *gc.C) { defer func() { if v := recover(); v != nil { c.Assert(v, gc.ErrorMatches, `.*duplicate storage provider type "foo"`) } }() p1 := &mockProvider{} p2 := &mockProvider{} registry.RegisterProvider(storage.ProviderType("foo"), p1) registry.RegisterProvider(storage.ProviderType("foo"), p2) c.Errorf("panic expected") }
func (s *providerRegistrySuite) TestUnregisterProvider(c *gc.C) { ptype := storage.ProviderType("foo") // No-op, since there's nothing registered yet. registry.RegisterProvider(ptype, nil) // Register and then unregister, ensure that the provider cannot // be accessed. registry.RegisterProvider(ptype, &mockProvider{}) registry.RegisterProvider(ptype, nil) _, err := registry.StorageProvider(storage.ProviderType("foo")) c.Assert(err, gc.ErrorMatches, `storage provider "foo" not found`) }
func (s *StorageStateSuiteBase) SetUpSuite(c *gc.C) { s.ConnSuite.SetUpSuite(c) registry.RegisterProvider("environscoped", &dummy.StorageProvider{ StorageScope: storage.ScopeEnviron, IsDynamic: true, }) registry.RegisterProvider("machinescoped", &dummy.StorageProvider{ StorageScope: storage.ScopeMachine, IsDynamic: true, }) registry.RegisterProvider("environscoped-block", &dummy.StorageProvider{ StorageScope: storage.ScopeEnviron, SupportsFunc: func(k storage.StorageKind) bool { return k == storage.StorageKindBlock }, IsDynamic: true, }) registry.RegisterProvider("static", &dummy.StorageProvider{ IsDynamic: false, }) registry.RegisterEnvironStorageProviders( "someprovider", "environscoped", "machinescoped", "environscoped-block", "static", ) s.AddSuiteCleanup(func(c *gc.C) { registry.RegisterProvider("environscoped", nil) registry.RegisterProvider("machinescoped", nil) registry.RegisterProvider("environscoped-block", nil) registry.RegisterProvider("static", nil) }) }
func init() { environs.RegisterProvider(providerType, azureEnvironProvider{}) // Register the Azure storage provider. registry.RegisterProvider(storageProviderType, &azureStorageProvider{}) registry.RegisterEnvironStorageProviders(providerType, storageProviderType) }
func (s *serviceSuite) TestClientServiceDeployWithUnsupportedStoragePool(c *gc.C) { registry.RegisterProvider("hostloop", &mockStorageProvider{kind: storage.StorageKindBlock}) pm := poolmanager.New(state.NewStateSettings(s.State)) _, err := pm.Create("host-loop-pool", provider.HostLoopProviderType, map[string]interface{}{}) c.Assert(err, jc.ErrorIsNil) curl, _ := s.UploadCharm(c, "utopic/storage-block-0", "storage-block") storageConstraints := map[string]storage.Constraints{ "data": storage.Constraints{ Pool: "host-loop-pool", Count: 1, Size: 1024, }, } var cons constraints.Value args := params.ServiceDeploy{ ServiceName: "service", CharmUrl: curl.String(), NumUnits: 1, Constraints: cons, Storage: storageConstraints, } results, err := s.serviceApi.ServicesDeploy(params.ServicesDeploy{ Services: []params.ServiceDeploy{args}}, ) c.Assert(err, jc.ErrorIsNil) c.Assert(results.Results, gc.HasLen, 1) c.Assert(results.Results[0].Error, gc.ErrorMatches, `.*pool "host-loop-pool" uses storage provider "hostloop" which is not supported for environments of type "dummy"`) }
func (s *providerRegistrySuite) TestRegisterProvider(c *gc.C) { p1 := &mockProvider{} ptype := storage.ProviderType("foo") registry.RegisterProvider(ptype, p1) p, err := registry.StorageProvider(ptype) c.Assert(err, jc.ErrorIsNil) c.Assert(p, gc.Equals, p1) }
func init() { environs.RegisterProvider(providerType, maasEnvironProvider{}) //Register the MAAS specific storage providers. registry.RegisterProvider(maasStorageProviderType, &maasStorageProvider{}) registry.RegisterEnvironStorageProviders(providerType, maasStorageProviderType) }
func (s *provisionerSuite) SetUpSuite(c *gc.C) { s.JujuConnSuite.SetUpSuite(c) registry.RegisterProvider("environscoped", &dummy.StorageProvider{ StorageScope: storage.ScopeEnviron, }) registry.RegisterProvider("machinescoped", &dummy.StorageProvider{ StorageScope: storage.ScopeMachine, }) registry.RegisterEnvironStorageProviders( "dummy", "environscoped", "machinescoped", ) s.AddCleanup(func(c *gc.C) { registry.RegisterProvider("environscoped", nil) registry.RegisterProvider("machinescoped", nil) }) }
func (s *ProvisionerSuite) TestProvisioningMachinesWithRequestedVolumes(c *gc.C) { // Set up a persistent pool. registry.RegisterProvider("static", &dummystorage.StorageProvider{IsDynamic: false}) registry.RegisterEnvironStorageProviders("dummy", "static") defer registry.RegisterProvider("static", nil) poolManager := poolmanager.New(state.NewStateSettings(s.State)) _, err := poolManager.Create("persistent-pool", "static", map[string]interface{}{"persistent": true}) c.Assert(err, jc.ErrorIsNil) p := s.newEnvironProvisioner(c) defer stop(c, p) // Add and provision a machine with volumes specified. requestedVolumes := []state.MachineVolumeParams{{ Volume: state.VolumeParams{Pool: "static", Size: 1024}, Attachment: state.VolumeAttachmentParams{}, }, { Volume: state.VolumeParams{Pool: "persistent-pool", Size: 2048}, Attachment: state.VolumeAttachmentParams{}, }} expectVolumeInfo := []storage.Volume{{ names.NewVolumeTag("1"), storage.VolumeInfo{ Size: 1024, }, }, { names.NewVolumeTag("2"), storage.VolumeInfo{ Size: 2048, Persistent: true, }, }} m, err := s.addMachineWithRequestedVolumes(requestedVolumes, s.defaultConstraints) c.Assert(err, jc.ErrorIsNil) inst := s.checkStartInstanceCustom( c, m, "pork", s.defaultConstraints, nil, nil, nil, expectVolumeInfo, false, nil, true, ) // Cleanup. c.Assert(m.EnsureDead(), gc.IsNil) s.checkStopInstances(c, inst) s.waitRemoved(c, m) }
func init() { environs.RegisterProvider(providerType, providerInstance) // Register the GCE specific providers. registry.RegisterProvider(storageProviderType, &storageProvider{}) // Inform the storage provider registry about the GCE providers. registry.RegisterEnvironStorageProviders(providerType, storageProviderType) }
func init() { environs.RegisterProvider(providerType, environProvider{}) //Register the AWS specific providers. registry.RegisterProvider(EBS_ProviderType, &ebsProvider{}) // Inform the storage provider registry about the AWS providers. registry.RegisterEnvironStorageProviders(providerType, EBS_ProviderType) }
func (s *DestroySuite) TestIgnoreMachineScopedVolumes(c *gc.C) { staticProvider := &dummy.StorageProvider{ IsDynamic: true, StorageScope: storage.ScopeMachine, } registry.RegisterProvider("machine", staticProvider) defer registry.RegisterProvider("machine", nil) registry.RegisterEnvironStorageProviders("anything, really", "machine") defer registry.ResetEnvironStorageProviders("anything, really") env := &mockEnviron{ config: configGetter(c), allInstances: func() ([]instance.Instance, error) { return nil, environs.ErrNoInstances }, } err := common.Destroy(env) c.Assert(err, jc.ErrorIsNil) // common.Destroy will ignore machine-scoped storage providers. staticProvider.CheckCallNames(c, "Dynamic", "Scope") }
func (s *storageProvisionerSuite) SetUpTest(c *gc.C) { s.BaseSuite.SetUpTest(c) s.provider = &dummyProvider{dynamic: true} registry.RegisterProvider("dummy", s.provider) s.AddCleanup(func(*gc.C) { registry.RegisterProvider("dummy", nil) }) s.managedFilesystemSource = nil s.PatchValue( storageprovisioner.NewManagedFilesystemSource, func( blockDevices map[names.VolumeTag]storage.BlockDevice, filesystems map[names.FilesystemTag]storage.Filesystem, ) storage.FilesystemSource { s.managedFilesystemSource = &mockManagedFilesystemSource{ blockDevices: blockDevices, filesystems: filesystems, } return s.managedFilesystemSource }, ) }
func (s *DestroySuite) TestDestroyEnvScopedVolumes(c *gc.C) { volumeSource := &dummy.VolumeSource{ ListVolumesFunc: func() ([]string, error) { return []string{"vol-0", "vol-1", "vol-2"}, nil }, DestroyVolumesFunc: func(ids []string) []error { return make([]error, len(ids)) }, } staticProvider := &dummy.StorageProvider{ IsDynamic: true, StorageScope: storage.ScopeEnviron, VolumeSourceFunc: func(*config.Config, *storage.Config) (storage.VolumeSource, error) { return volumeSource, nil }, } registry.RegisterProvider("environ", staticProvider) defer registry.RegisterProvider("environ", nil) registry.RegisterEnvironStorageProviders("anything, really", "environ") defer registry.ResetEnvironStorageProviders("anything, really") env := &mockEnviron{ config: configGetter(c), allInstances: func() ([]instance.Instance, error) { return nil, environs.ErrNoInstances }, } err := common.Destroy(env) c.Assert(err, jc.ErrorIsNil) // common.Destroy will ignore machine-scoped storage providers. staticProvider.CheckCallNames(c, "Dynamic", "Scope", "Supports", "VolumeSource") volumeSource.CheckCalls(c, []gitjujutesting.StubCall{ {"ListVolumes", nil}, {"DestroyVolumes", []interface{}{[]string{"vol-0", "vol-1", "vol-2"}}}, }) }
func (s *assignCleanSuite) TestAssignToMachineErrors(c *gc.C) { registry.RegisterProvider("static", &dummy.StorageProvider{ IsDynamic: false, }) registry.RegisterEnvironStorageProviders("someprovider", "static") defer registry.RegisterProvider("static", nil) _, unit, _ := s.setupSingleStorage(c, "filesystem", "static") machine, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, jc.ErrorIsNil) err = unit.AssignToMachine(machine) c.Assert( err, gc.ErrorMatches, `cannot assign unit "storage-filesystem/0" to machine 0: "static" storage provider does not support dynamic storage`, ) container, err := s.State.AddMachineInsideMachine(state.MachineTemplate{ Series: "quantal", Jobs: []state.MachineJob{state.JobHostUnits}, }, machine.Id(), instance.LXC) c.Assert(err, jc.ErrorIsNil) err = unit.AssignToMachine(container) c.Assert(err, gc.ErrorMatches, `cannot assign unit "storage-filesystem/0" to machine 0/lxc/0: adding storage to lxc container not supported`) }
func init() { environs.RegisterProvider(providerType, providerInstance) environs.RegisterImageDataSourceFunc("keystone catalog", getKeystoneImageSource) tools.RegisterToolsDataSourceFunc("keystone catalog", getKeystoneToolsSource) // Register the Openstack specific providers. registry.RegisterProvider( CinderProviderType, &cinderProvider{newOpenstackStorageAdapter}, ) // Register the Cinder provider with the Openstack provider. registry.RegisterEnvironStorageProviders(providerType, CinderProviderType) }
func init() { environProvider, storageProvider, err := NewProviders(ProviderConfig{ NewStorageClient: azurestorage.NewClient, StorageAccountNameGenerator: RandomStorageAccountName, }) if err != nil { panic(err) } environs.RegisterProvider(providerType, environProvider) registry.RegisterProvider(storageProviderType, storageProvider) registry.RegisterEnvironStorageProviders(providerType, storageProviderType) // TODO(axw) register an image metadata data source that queries // the Azure image registry, and introduce a way to disable the // common simplestreams source. }
// TODO(fwereade): 2015-11-18 lp:1517391 func (s *watcherSuite) TestWatchMachineStorage(c *gc.C) { registry.RegisterProvider( "envscoped", &dummy.StorageProvider{ StorageScope: storage.ScopeEnviron, }, ) registry.RegisterEnvironStorageProviders("dummy", "envscoped") defer registry.RegisterProvider("envscoped", nil) f := factory.NewFactory(s.BackingState) f.MakeMachine(c, &factory.MachineParams{ Volumes: []state.MachineVolumeParams{{ Volume: state.VolumeParams{ Pool: "envscoped", Size: 1024, }, }}, }) var results params.MachineStorageIdsWatchResults args := params.Entities{Entities: []params.Entity{{ Tag: s.State.ModelTag().String(), }}} err := s.stateAPI.APICall( "StorageProvisioner", s.stateAPI.BestFacadeVersion("StorageProvisioner"), "", "WatchVolumeAttachments", args, &results) c.Assert(err, jc.ErrorIsNil) c.Assert(results.Results, gc.HasLen, 1) result := results.Results[0] c.Assert(result.Error, gc.IsNil) w := watcher.NewVolumeAttachmentsWatcher(s.stateAPI, result) defer func() { // Check we can stop the watcher... w.Kill() wait := make(chan error) go func() { wait <- w.Wait() }() select { case err := <-wait: c.Assert(err, jc.ErrorIsNil) case <-time.After(coretesting.LongWait): c.Fatalf("watcher never stopped") } // ...and that its channel hasn't been closed. s.BackingState.StartSync() select { case change, ok := <-w.Changes(): c.Fatalf("watcher sent unexpected change: (%#v, %v)", change, ok) default: } }() // Check initial event; s.BackingState.StartSync() select { case changes, ok := <-w.Changes(): c.Assert(ok, jc.IsTrue) c.Assert(changes, jc.SameContents, []corewatcher.MachineStorageId{{ MachineTag: "machine-1", AttachmentTag: "volume-0", }}) case <-time.After(coretesting.LongWait): c.Fatalf("timed out waiting for change") } // check no subsequent event. s.BackingState.StartSync() select { case <-w.Changes(): c.Fatalf("received unexpected change") case <-time.After(coretesting.ShortWait): } }
func (s *withoutControllerSuite) registerStaticStorageProvider(c *gc.C) { registry.RegisterProvider("static", &storagedummy.StorageProvider{IsDynamic: false}) s.AddCleanup(func(*gc.C) { registry.RegisterProvider("static", nil) }) }
func init() { registry.RegisterEnvironStorageProviders("dummy", "dummy") registry.RegisterProvider("dummy", &dummystorage.StorageProvider{}) }