Permalink
...
Checking mergeability…
Don’t worry, you can still create the pull request.
Comparing changes
Open a pull request
6
contributors
Unified
Split
Showing
with
1,311 additions
and 258 deletions.
- +1 −0 api/provisioner/provisioner_test.go
- +78 −5 api/storageprovisioner/provisioner.go
- +144 −8 api/storageprovisioner/provisioner_test.go
- +59 −22 apiserver/common/volumes.go
- +4 −0 apiserver/diskformatter/diskformatter_test.go
- +1 −0 apiserver/diskmanager/diskmanager.go
- +36 −21 apiserver/metricsender/metricsender.go
- +45 −7 apiserver/metricsender/sender_test.go
- +3 −2 apiserver/metricsender/wireformat/wireformat.go
- +5 −8 apiserver/params/storage.go
- +22 −22 apiserver/provisioner/provisioner.go
- +20 −6 apiserver/provisioner/provisioner_test.go
- +14 −0 apiserver/storageprovisioner/state.go
- +243 −19 apiserver/storageprovisioner/storageprovisioner.go
- +176 −6 apiserver/storageprovisioner/storageprovisioner_test.go
- +1 −1 dependencies.tsv
- +1 −1 provider/gce/environ_broker_test.go
- +1 −1 provider/gce/google/conn_instance_test.go
- +5 −3 provider/gce/google/disk.go
- +2 −2 provider/gce/google/disk_test.go
- +1 −1 provider/gce/google/instance_test.go
- +2 −2 provider/gce/google/testing_test.go
- +1 −1 provider/gce/testing_test.go
- +30 −1 state/filesystem.go
- +1 −0 state/filesystem_test.go
- +146 −34 state/ipaddresses.go
- +67 −2 state/ipaddresses_test.go
- +6 −6 state/machine_test.go
- +16 −0 state/metricsmanager.go
- +20 −0 state/metricsmanager_test.go
- +1 −0 state/state.go
- +1 −1 state/state_test.go
- +17 −8 state/volume.go
- +2 −0 state/volume_test.go
- +10 −1 storage/interface.go
- +6 −2 worker/provisioner/container_initialisation_test.go
- +1 −2 worker/provisioner/export_test.go
- +12 −0 worker/provisioner/kvm-broker.go
- +68 −36 worker/provisioner/lxc-broker.go
- +22 −12 worker/provisioner/lxc-broker_test.go
- +11 −2 worker/provisioner/provisioner_task.go
- +1 −1 worker/storageprovisioner/storageprovisioner.go
- +4 −4 worker/storageprovisioner/storageprovisioner_test.go
- +3 −6 worker/storageprovisioner/volumes.go
- +1 −2 worker/uniter/storage/source.go
View
1
api/provisioner/provisioner_test.go
| @@ -369,6 +369,7 @@ func (s *provisionerSuite) TestSetInstanceInfo(c *gc.C) { | ||
| c.Assert(err, jc.ErrorIsNil) | ||
| c.Assert(volumeInfo, gc.Equals, state.VolumeInfo{ | ||
| VolumeId: "vol-123", | ||
| + Pool: "loop-pool", | ||
| Size: 124, | ||
| }) | ||
| stateVolumeAttachments, err := s.State.MachineVolumeAttachments(names.NewMachineTag("1")) | ||
View
83
api/storageprovisioner/provisioner.go
| @@ -22,8 +22,12 @@ type State struct { | ||
| // NewState creates a new client-side StorageProvisioner facade. | ||
| func NewState(caller base.APICaller, scope names.Tag) *State { | ||
| - // TODO(wallyworld) - validate that scope matches current environ | ||
| - // if it is an environment tag. | ||
| + switch scope.(type) { | ||
| + case names.EnvironTag: | ||
| + case names.MachineTag: | ||
| + default: | ||
| + panic(errors.Errorf("expected EnvironTag or MachineTag, got %T", scope)) | ||
| + } | ||
| return &State{ | ||
| base.NewFacadeCaller(caller, storageProvisionerFacade), | ||
| scope, | ||
| @@ -93,6 +97,20 @@ func (st *State) Volumes(tags []names.VolumeTag) ([]params.VolumeResult, error) | ||
| return results.Results, nil | ||
| } | ||
| +// VolumeAttachments returns details of volume attachments with the specified IDs. | ||
| +func (st *State) VolumeAttachments(ids []params.MachineStorageId) ([]params.VolumeAttachmentResult, error) { | ||
| + args := params.MachineStorageIds{ids} | ||
| + var results params.VolumeAttachmentResults | ||
| + err := st.facade.FacadeCall("VolumeAttachments", args, &results) | ||
| + if err != nil { | ||
| + return nil, err | ||
| + } | ||
| + if len(results.Results) != len(ids) { | ||
| + panic(errors.Errorf("expected %d result(s), got %d", len(ids), len(results.Results))) | ||
| + } | ||
| + return results.Results, nil | ||
| +} | ||
| + | ||
| // VolumeParams returns the parameters for creating the volumes | ||
| // with the specified tags. | ||
| func (st *State) VolumeParams(tags []names.VolumeTag) ([]params.VolumeParamsResult, error) { | ||
| @@ -113,18 +131,47 @@ func (st *State) VolumeParams(tags []names.VolumeTag) ([]params.VolumeParamsResu | ||
| return results.Results, nil | ||
| } | ||
| +// VolumeAttachmentParams returns the parameters for creating the volume | ||
| +// attachments with the specified tags. | ||
| +func (st *State) VolumeAttachmentParams(ids []params.MachineStorageId) ([]params.VolumeAttachmentParamsResult, error) { | ||
| + args := params.MachineStorageIds{ids} | ||
| + var results params.VolumeAttachmentParamsResults | ||
| + err := st.facade.FacadeCall("VolumeAttachmentParams", args, &results) | ||
| + if err != nil { | ||
| + return nil, err | ||
| + } | ||
| + if len(results.Results) != len(ids) { | ||
| + panic(errors.Errorf("expected %d result(s), got %d", len(ids), len(results.Results))) | ||
| + } | ||
| + return results.Results, nil | ||
| +} | ||
| + | ||
| // SetVolumeInfo records the details of newly provisioned volumes. | ||
| -func (st *State) SetVolumeInfo(volumes []params.Volume) (params.ErrorResults, error) { | ||
| +func (st *State) SetVolumeInfo(volumes []params.Volume) ([]params.ErrorResult, error) { | ||
| args := params.Volumes{Volumes: volumes} | ||
| var results params.ErrorResults | ||
| err := st.facade.FacadeCall("SetVolumeInfo", args, &results) | ||
| if err != nil { | ||
| - return results, err | ||
| + return nil, err | ||
| } | ||
| if len(results.Results) != len(volumes) { | ||
| panic(errors.Errorf("expected %d result(s), got %d", len(volumes), len(results.Results))) | ||
| } | ||
| - return results, nil | ||
| + return results.Results, nil | ||
| +} | ||
| + | ||
| +// SetVolumeAttachmentInfo records the details of newly provisioned volume attachments. | ||
| +func (st *State) SetVolumeAttachmentInfo(volumeAttachments []params.VolumeAttachment) ([]params.ErrorResult, error) { | ||
| + args := params.VolumeAttachments{VolumeAttachments: volumeAttachments} | ||
| + var results params.ErrorResults | ||
| + err := st.facade.FacadeCall("SetVolumeAttachmentInfo", args, &results) | ||
| + if err != nil { | ||
| + return nil, err | ||
| + } | ||
| + if len(results.Results) != len(volumeAttachments) { | ||
| + panic(errors.Errorf("expected %d result(s), got %d", len(volumeAttachments), len(results.Results))) | ||
| + } | ||
| + return results.Results, nil | ||
| } | ||
| // Life requests the life cycle of the entities with the specified tags. | ||
| @@ -145,6 +192,19 @@ func (st *State) Life(tags []names.Tag) ([]params.LifeResult, error) { | ||
| return results.Results, nil | ||
| } | ||
| +// AttachmentLife requests the life cycle of the attachments with the specified IDs. | ||
| +func (st *State) AttachmentLife(ids []params.MachineStorageId) ([]params.LifeResult, error) { | ||
| + var results params.LifeResults | ||
| + args := params.MachineStorageIds{ids} | ||
| + if err := st.facade.FacadeCall("AttachmentLife", args, &results); err != nil { | ||
| + return nil, err | ||
| + } | ||
| + if len(results.Results) != len(ids) { | ||
| + return nil, errors.Errorf("expected %d result(s), got %d", len(ids), len(results.Results)) | ||
| + } | ||
| + return results.Results, nil | ||
| +} | ||
| + | ||
| // EnsureDead progresses the entities with the specified tags to the Dead | ||
| // life cycle state, if they are Alive or Dying. | ||
| func (st *State) EnsureDead(tags []names.Tag) ([]params.ErrorResult, error) { | ||
| @@ -181,3 +241,16 @@ func (st *State) Remove(tags []names.Tag) ([]params.ErrorResult, error) { | ||
| } | ||
| return results.Results, nil | ||
| } | ||
| + | ||
| +// RemoveAttachments removes the attachments with the specified IDs from state. | ||
| +func (st *State) RemoveAttachments(ids []params.MachineStorageId) ([]params.ErrorResult, error) { | ||
| + var results params.ErrorResults | ||
| + args := params.MachineStorageIds{ids} | ||
| + if err := st.facade.FacadeCall("RemoveAttachment", args, &results); err != nil { | ||
| + return nil, err | ||
| + } | ||
| + if len(results.Results) != len(ids) { | ||
| + return nil, errors.Errorf("expected %d result(s), got %d", len(ids), len(results.Results)) | ||
| + } | ||
| + return results.Results, nil | ||
| +} | ||
View
152
api/storageprovisioner/provisioner_test.go
| @@ -22,6 +22,20 @@ type provisionerSuite struct { | ||
| coretesting.BaseSuite | ||
| } | ||
| +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) TestWatchVolumes(c *gc.C) { | ||
| var callCount int | ||
| apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { | ||
| @@ -102,6 +116,43 @@ func (s *provisionerSuite) TestVolumes(c *gc.C) { | ||
| }}) | ||
| } | ||
| +func (s *provisionerSuite) TestVolumeAttachments(c *gc.C) { | ||
| + volumeAttachmentResults := []params.VolumeAttachmentResult{{ | ||
| + Result: params.VolumeAttachment{ | ||
| + MachineTag: "machine-100", | ||
| + VolumeTag: "volume-100", | ||
| + 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 := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) | ||
| + 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) TestVolumeParams(c *gc.C) { | ||
| var callCount int | ||
| apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { | ||
| @@ -114,10 +165,9 @@ func (s *provisionerSuite) TestVolumeParams(c *gc.C) { | ||
| *(result.(*params.VolumeParamsResults)) = params.VolumeParamsResults{ | ||
| Results: []params.VolumeParamsResult{{ | ||
| Result: params.VolumeParams{ | ||
| - VolumeTag: "volume-100", | ||
| - Size: 1024, | ||
| - Provider: "loop", | ||
| - MachineTag: "machine-200", | ||
| + VolumeTag: "volume-100", | ||
| + Size: 1024, | ||
| + Provider: "loop", | ||
| }, | ||
| }}, | ||
| } | ||
| @@ -131,11 +181,50 @@ func (s *provisionerSuite) TestVolumeParams(c *gc.C) { | ||
| c.Check(callCount, gc.Equals, 1) | ||
| c.Assert(volumeParams, jc.DeepEquals, []params.VolumeParamsResult{{ | ||
| Result: params.VolumeParams{ | ||
| - VolumeTag: "volume-100", Size: 1024, Provider: "loop", MachineTag: "machine-200", | ||
| + VolumeTag: "volume-100", Size: 1024, Provider: "loop", | ||
| }, | ||
| }}) | ||
| } | ||
| +func (s *provisionerSuite) TestVolumeAttachmentParams(c *gc.C) { | ||
| + paramsResults := []params.VolumeAttachmentParamsResult{{ | ||
| + Result: params.VolumeAttachmentParams{ | ||
| + MachineTag: "machine-100", | ||
| + VolumeTag: "volume-100", | ||
| + VolumeId: "vol-ume", | ||
| + InstanceId: "inst-ance", | ||
| + Provider: "loop", | ||
| + }, | ||
| + }} | ||
| + | ||
| + 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, "VolumeAttachmentParams") | ||
| + c.Check(arg, gc.DeepEquals, params.MachineStorageIds{ | ||
| + Ids: []params.MachineStorageId{{ | ||
| + MachineTag: "machine-100", AttachmentTag: "volume-100", | ||
| + }}, | ||
| + }) | ||
| + c.Assert(result, gc.FitsTypeOf, ¶ms.VolumeAttachmentParamsResults{}) | ||
| + *(result.(*params.VolumeAttachmentParamsResults)) = params.VolumeAttachmentParamsResults{ | ||
| + Results: paramsResults, | ||
| + } | ||
| + callCount++ | ||
| + return nil | ||
| + }) | ||
| + | ||
| + st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) | ||
| + volumeParams, err := st.VolumeAttachmentParams([]params.MachineStorageId{{ | ||
| + MachineTag: "machine-100", AttachmentTag: "volume-100", | ||
| + }}) | ||
| + c.Check(err, jc.ErrorIsNil) | ||
| + c.Check(callCount, gc.Equals, 1) | ||
| + c.Assert(volumeParams, jc.DeepEquals, paramsResults) | ||
| +} | ||
| + | ||
| 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 { | ||
| @@ -159,7 +248,36 @@ func (s *provisionerSuite) TestSetVolumeInfo(c *gc.C) { | ||
| errorResults, err := st.SetVolumeInfo(volumes) | ||
| c.Check(err, jc.ErrorIsNil) | ||
| c.Check(callCount, gc.Equals, 1) | ||
| - c.Assert(errorResults.OneError(), jc.ErrorIsNil) | ||
| + c.Assert(errorResults, gc.HasLen, 1) | ||
| + c.Assert(errorResults[0].Error, gc.IsNil) | ||
| +} | ||
| + | ||
| +func (s *provisionerSuite) TestSetVolumeAttachmentInfo(c *gc.C) { | ||
| + volumeAttachments := []params.VolumeAttachment{{ | ||
| + VolumeTag: "volume-100", MachineTag: "machine-200", 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, "SetVolumeAttachmentInfo") | ||
| + c.Check(arg, jc.DeepEquals, params.VolumeAttachments{volumeAttachments}) | ||
| + c.Assert(result, gc.FitsTypeOf, ¶ms.ErrorResults{}) | ||
| + *(result.(*params.ErrorResults)) = params.ErrorResults{ | ||
| + Results: []params.ErrorResult{{Error: nil}}, | ||
| + } | ||
| + callCount++ | ||
| + return nil | ||
| + }) | ||
| + | ||
| + st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123")) | ||
| + errorResults, err := st.SetVolumeAttachmentInfo(volumeAttachments) | ||
| + 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) testOpWithTags( | ||
| @@ -246,18 +364,28 @@ func (s *provisionerSuite) TestVolumesClientError(c *gc.C) { | ||
| return err | ||
| }) | ||
| } | ||
| + | ||
| func (s *provisionerSuite) TestVolumeParamsClientError(c *gc.C) { | ||
| s.testClientError(c, func(st *storageprovisioner.State) error { | ||
| _, err := st.VolumeParams(nil) | ||
| return err | ||
| }) | ||
| } | ||
| + | ||
| func (s *provisionerSuite) TestRemoveClientError(c *gc.C) { | ||
| s.testClientError(c, func(st *storageprovisioner.State) error { | ||
| _, err := st.Remove(nil) | ||
| return err | ||
| }) | ||
| } | ||
| + | ||
| +func (s *provisionerSuite) TestRemoveAttachmentsClientError(c *gc.C) { | ||
| + s.testClientError(c, func(st *storageprovisioner.State) error { | ||
| + _, err := st.RemoveAttachments(nil) | ||
| + return err | ||
| + }) | ||
| +} | ||
| + | ||
| func (s *provisionerSuite) TestSetVolumeInfoClientError(c *gc.C) { | ||
| s.testClientError(c, func(st *storageprovisioner.State) error { | ||
| _, err := st.SetVolumeInfo(nil) | ||
| @@ -279,6 +407,13 @@ func (s *provisionerSuite) TestLifeClientError(c *gc.C) { | ||
| }) | ||
| } | ||
| +func (s *provisionerSuite) TestAttachmentLifeClientError(c *gc.C) { | ||
| + s.testClientError(c, func(st *storageprovisioner.State) error { | ||
| + _, err := st.AttachmentLife(nil) | ||
| + return err | ||
| + }) | ||
| +} | ||
| + | ||
| 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{ | ||
| @@ -308,6 +443,7 @@ func (s *provisionerSuite) TestVolumesServerError(c *gc.C) { | ||
| c.Assert(results, gc.HasLen, 1) | ||
| c.Check(results[0].Error, 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{ | ||
| @@ -338,8 +474,8 @@ func (s *provisionerSuite) TestSetVolumeInfoServerError(c *gc.C) { | ||
| VolumeTag: names.NewVolumeTag("100").String(), | ||
| }}) | ||
| c.Assert(err, jc.ErrorIsNil) | ||
| - c.Assert(results.Results, gc.HasLen, 1) | ||
| - c.Check(results.OneError(), gc.ErrorMatches, "MSG") | ||
| + c.Assert(results, gc.HasLen, 1) | ||
| + c.Check(results[0].Error, gc.ErrorMatches, "MSG") | ||
| } | ||
| func (s *provisionerSuite) testServerError(c *gc.C, apiCall func(*storageprovisioner.State, []names.Tag) ([]params.ErrorResult, error)) { | ||
Oops, something went wrong.