Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
Release storage client worker provider #7649
Conversation
babbageclunk
suggested changes
Jul 19, 2017
I think the code's fine but the names are really confusing. I can see that it's potentially a lot of work to change them now - do you think it's worth it?
| @@ -180,7 +180,7 @@ func (c *Client) Attach(unitId string, storageIds []string) ([]params.ErrorResul | ||
| } | ||
| // Destroy destroys specified storage entities. | ||
| -func (c *Client) Destroy(storageIds []string, destroyAttached bool) ([]params.ErrorResult, error) { | ||
| +func (c *Client) Destroy(storageIds []string, destroyAttachments, releaseStorage bool) ([]params.ErrorResult, error) { |
babbageclunk
Jul 19, 2017
Member
Maybe this should also be Remove? It feels like less of a problem here though, I guess because here there's a distinction between the storage in the model and the underlying storage in the cloud.
axw
Jul 19, 2017
Member
I was all ready to change this to Remove, but I'm hesitating now because it makes it different to all the other places we use the name Destroy in the client APIs. Probably better to keep consistency, and put "underlying" in the arg name somewhere.
axw
Jul 19, 2017
Member
OTOH, the API structure is different enough that it can't be directly compared anyway. I'll call it Remove here.
| @@ -243,6 +243,26 @@ func (st *State) VolumeParams(tags []names.VolumeTag) ([]params.VolumeParamsResu | ||
| return results.Results, nil | ||
| } | ||
| +// DestroyVolumeParams returns the parameters for destroying the volumes | ||
| +// with the specified tags. | ||
| +func (st *State) DestroyVolumeParams(tags []names.VolumeTag) ([]params.DestroyVolumeParamsResult, error) { |
babbageclunk
Jul 19, 2017
Member
Similarly, the struct that comes back shouldn't be a DestroyVolumeParams (or -Filesystem-) if it only sometimes indicates that the volume should be destroyed. I think ReleaseVolumeParams would be better here too.
axw
Jul 19, 2017
Member
Renamed to RemoveVolumeParams (same for Filesystem), and changed the field from Release to Destroy.
| @@ -85,7 +95,7 @@ func (c *removeStorageCommand) Run(ctx *cmd.Context) error { | ||
| } | ||
| defer destroyer.Close() | ||
| - results, err := destroyer.Destroy(c.storageIds, c.force) | ||
| + results, err := destroyer.Destroy(c.storageIds, c.force, c.noDestroy) |
babbageclunk
Jul 19, 2017
Member
What about if you called the flag noDestroyUnderlying? Then you keep fairly close to the option name (which is fine since the command is remove), but make this line less oxymoronic.
I know it's minor but I find things like this really throw me off when I'm reading code.
| + return destroyVolumes(v.env.ec2, volIds, true), nil | ||
| +} | ||
| + | ||
| +func destroyVolumes(client *ec2.EC2, volIds []string, release bool) []error { |
babbageclunk
Jul 19, 2017
Member
The name's pretty misleading now - destroyVolumes but with a don't-actually-destroy-them flag. The other sense would be less surprising: releaseVolumes with an also-destroy-them flag.
axw
Jul 19, 2017
Member
I've looked at this a bit more closely, and there's enough differences (which I missed) that these should just be separate methods. e.g. release should error if delete-on-termination is set, or if there are attachments in the attaching/attached state.
| - filesystem, ok := ctx.filesystems[filesystemParams.Tag] | ||
| - if !ok { | ||
| - return errors.NotFoundf("filesystem %s", filesystemParams.Tag.Id()) | ||
| + destroyFilesystemTags := make([]names.FilesystemTag, 0, len(destroyFilesystemParams)) |
babbageclunk
Jul 19, 2017
Member
This method's become really long and is shuffling things around in several different data structures. Maybe split this part (partitioning into release and destroy groups, and then executing the groups) into a separate method?
axw
Jul 19, 2017
Member
I've split out the code that partitions the tags/IDs, but I think it's going to be messy to split out any more than that. I've created a function literal to avoid repeating the code that deals with the errors (rescheduling/adding to the set of storage to remove).
| - volume, ok := ctx.volumes[volumeParams.Tag] | ||
| - if !ok { | ||
| - return errors.NotFoundf("volume %s", volumeParams.Tag.Id()) | ||
| + destroyVolumeTags := make([]names.VolumeTag, 0, len(destroyVolumeParams)) |
babbageclunk
approved these changes
Jul 19, 2017
Thanks! I find these names much clearer. I feel like you could change the noDestroyUnderlying flag back to noDestroy now that the API method is Remove though. (Sorry! But not essential either.)
| + newStorageRemoverCloser NewStorageRemoverCloserFunc | ||
| + storageIds []string | ||
| + force bool | ||
| + noDestroyUnderlying bool |
babbageclunk
Jul 19, 2017
Member
Sorry to do this, but now that the method's Remove, I think this would be better as just noDestroy. I only wanted it to be noDestroyUnderlying so that it wouldn't read as Destroy(noDestroy). Not a big deal though.
| @@ -445,22 +445,22 @@ func (v *ebsVolumeSource) DescribeVolumes(volIds []string) ([]storage.DescribeVo | ||
| // DestroyVolumes is specified on the storage.VolumeSource interface. | ||
| func (v *ebsVolumeSource) DestroyVolumes(volIds []string) ([]error, error) { | ||
| - return destroyVolumes(v.env.ec2, volIds, false), nil | ||
| + return foreachVolume(v.env.ec2, volIds, destroyVolume), nil |
| - destroyFilesystemParams := make([]params.RemoveFilesystemParams, len(filesystemParams)) | ||
| - for i, args := range filesystemParams { | ||
| - destroyFilesystemParams[i] = destroyFilesystemParamsByTag[args.Tag] | ||
| + removeFilesystems := func(tags []names.FilesystemTag, ids []string, f func([]string) ([]error, error)) error { |
axw
added some commits
Jul 18, 2017
|
$$merge$$ |
|
Status: merge request accepted. Url: http://juju-ci.vapour.ws:8080/job/github-merge-juju |
axw commentedJul 18, 2017
•
Edited 1 time
-
axw
Jul 18, 2017
Description of change
Add api, cmd, worker/storageprovisioner, and storage provider changes required to support non-destructively removing storage from a model.
The
juju remove-storagecommand grows a--no-destroyflag, which instructs Juju to remove the storage without destroying the associated cloud storage resources. This can be used to release the storage from Juju's control. Once the storage is removed from the model, destroying the model or controller will not destroy the storage.The VolumeSource and FilesystemSource interfaces grow methods for releasing storage, rather than destroying it. The storageprovisioner worker uses these methods for storage that is marked for releasing.
Requires #7648
QA steps
(volume should remain, but should show no juju-controller-uuid or juju-model-uuid tags)
As above, but with EBS. In the portal, you should see the juju-controller-uuid/juju-model-uuid tags are empty after the storage is released/removed.
Documentation changes
Yes, we'll need to document
juju remove-storage --no-destroy.Bug reference
None.