1
// Copyright 2015 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
7
"github.com/juju/errors"
8
"gopkg.in/juju/names.v2"
10
"github.com/juju/juju/api/base"
11
apiwatcher "github.com/juju/juju/api/watcher"
12
"github.com/juju/juju/apiserver/params"
13
"github.com/juju/juju/watcher"
16
type StorageAccessor struct {
17
facade base.FacadeCaller
20
// NewStorageAccessor creates a StorageAccessor on the specified facade,
21
// and uses this name when calling through the caller.
22
func NewStorageAccessor(facade base.FacadeCaller) *StorageAccessor {
23
return &StorageAccessor{facade}
26
// UnitStorageAttachments returns the IDs of a unit's storage attachments.
27
func (sa *StorageAccessor) UnitStorageAttachments(unitTag names.UnitTag) ([]params.StorageAttachmentId, error) {
28
if sa.facade.BestAPIVersion() < 2 {
29
return nil, errors.NotImplementedf("UnitStorageAttachments() (need V2+)")
31
args := params.Entities{
32
Entities: []params.Entity{{Tag: unitTag.String()}},
34
var results params.StorageAttachmentIdsResults
35
err := sa.facade.FacadeCall("UnitStorageAttachments", args, &results)
37
return nil, errors.Trace(err)
39
if len(results.Results) != 1 {
40
panic(errors.Errorf("expected 1 result, got %d", len(results.Results)))
42
result := results.Results[0]
43
if result.Error != nil {
44
return nil, result.Error
46
return result.Result.Ids, nil
49
// DestroyUnitStorageAttachments ensures that the specified unit's storage
50
// attachments will be removed at some point in the future.
51
func (sa *StorageAccessor) DestroyUnitStorageAttachments(unitTag names.UnitTag) error {
52
if sa.facade.BestAPIVersion() < 2 {
53
return errors.NotImplementedf("DestroyUnitStorageAttachments() (need V2+)")
55
args := params.Entities{
56
Entities: []params.Entity{{Tag: unitTag.String()}},
58
var results params.ErrorResults
59
err := sa.facade.FacadeCall("DestroyUnitStorageAttachments", args, &results)
61
return errors.Trace(err)
63
if len(results.Results) != 1 {
64
panic(errors.Errorf("expected 1 result, got %d", len(results.Results)))
66
result := results.Results[0]
67
if result.Error != nil {
73
// WatchUnitStorageAttachments starts a watcher for changes to storage
74
// attachments related to the unit. The watcher will return the
75
// IDs of the corresponding storage instances.
76
func (sa *StorageAccessor) WatchUnitStorageAttachments(unitTag names.UnitTag) (watcher.StringsWatcher, error) {
77
var results params.StringsWatchResults
78
args := params.Entities{
79
Entities: []params.Entity{{Tag: unitTag.String()}},
81
err := sa.facade.FacadeCall("WatchUnitStorageAttachments", args, &results)
85
if len(results.Results) != 1 {
86
return nil, errors.Errorf("expected 1 result, got %d", len(results.Results))
88
result := results.Results[0]
89
if result.Error != nil {
90
return nil, result.Error
92
w := apiwatcher.NewStringsWatcher(sa.facade.RawAPICaller(), result)
96
// StorageAttachment returns the storage attachment with the specified
97
// unit and storage tags.
98
func (sa *StorageAccessor) StorageAttachment(storageTag names.StorageTag, unitTag names.UnitTag) (params.StorageAttachment, error) {
99
if sa.facade.BestAPIVersion() < 2 {
100
return params.StorageAttachment{}, errors.NotImplementedf("StorageAttachment() (need V2+)")
102
args := params.StorageAttachmentIds{
103
Ids: []params.StorageAttachmentId{{
104
StorageTag: storageTag.String(),
105
UnitTag: unitTag.String(),
108
var results params.StorageAttachmentResults
109
err := sa.facade.FacadeCall("StorageAttachments", args, &results)
111
return params.StorageAttachment{}, errors.Trace(err)
113
if len(results.Results) != 1 {
114
panic(errors.Errorf("expected 1 result, got %d", len(results.Results)))
116
result := results.Results[0]
117
if result.Error != nil {
118
return params.StorageAttachment{}, result.Error
120
return result.Result, nil
123
// StorageAttachmentLife returns the lifecycle state of the storage attachments
124
// with the specified IDs.
125
func (sa *StorageAccessor) StorageAttachmentLife(ids []params.StorageAttachmentId) ([]params.LifeResult, error) {
126
if sa.facade.BestAPIVersion() < 2 {
127
return nil, errors.NotImplementedf("StorageAttachmentLife() (need V2+)")
129
args := params.StorageAttachmentIds{ids}
130
var results params.LifeResults
131
err := sa.facade.FacadeCall("StorageAttachmentLife", args, &results)
133
return nil, errors.Trace(err)
135
if len(results.Results) != len(ids) {
136
panic(errors.Errorf("expected %d results, got %d", len(ids), len(results.Results)))
138
return results.Results, nil
141
// WatchStorageAttachments starts a watcher for changes to the info
142
// of the storage attachment with the specified unit and storage tags.
143
func (sa *StorageAccessor) WatchStorageAttachment(storageTag names.StorageTag, unitTag names.UnitTag) (watcher.NotifyWatcher, error) {
144
var results params.NotifyWatchResults
145
args := params.StorageAttachmentIds{
146
Ids: []params.StorageAttachmentId{{
147
StorageTag: storageTag.String(),
148
UnitTag: unitTag.String(),
151
err := sa.facade.FacadeCall("WatchStorageAttachments", args, &results)
155
if len(results.Results) != 1 {
156
return nil, errors.Errorf("expected 1 result, got %d", len(results.Results))
158
result := results.Results[0]
159
if result.Error != nil {
160
return nil, result.Error
162
w := apiwatcher.NewNotifyWatcher(sa.facade.RawAPICaller(), result)
166
// RemoveStorageAttachment removes the storage attachment with the
167
// specified unit and storage tags from state. This method is only
168
// expected to succeed if the storage attachment is Dead.
169
func (sa *StorageAccessor) RemoveStorageAttachment(storageTag names.StorageTag, unitTag names.UnitTag) error {
170
var results params.ErrorResults
171
args := params.StorageAttachmentIds{
172
Ids: []params.StorageAttachmentId{{
173
StorageTag: storageTag.String(),
174
UnitTag: unitTag.String(),
177
err := sa.facade.FacadeCall("RemoveStorageAttachments", args, &results)
181
if len(results.Results) != 1 {
182
return errors.Errorf("expected 1 result, got %d", len(results.Results))
184
result := results.Results[0]
185
if result.Error != nil {