github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/api/uniter/storage.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package uniter 5 6 import ( 7 "github.com/juju/errors" 8 "gopkg.in/juju/names.v2" 9 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/core/watcher" 14 ) 15 16 type StorageAccessor struct { 17 facade base.FacadeCaller 18 } 19 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} 24 } 25 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+)") 30 } 31 args := params.Entities{ 32 Entities: []params.Entity{{Tag: unitTag.String()}}, 33 } 34 var results params.StorageAttachmentIdsResults 35 err := sa.facade.FacadeCall("UnitStorageAttachments", args, &results) 36 if err != nil { 37 return nil, errors.Trace(err) 38 } 39 if len(results.Results) != 1 { 40 return nil, errors.Errorf("expected 1 result, got %d", len(results.Results)) 41 } 42 result := results.Results[0] 43 if result.Error != nil { 44 return nil, result.Error 45 } 46 return result.Result.Ids, nil 47 } 48 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+)") 54 } 55 args := params.Entities{ 56 Entities: []params.Entity{{Tag: unitTag.String()}}, 57 } 58 var results params.ErrorResults 59 err := sa.facade.FacadeCall("DestroyUnitStorageAttachments", args, &results) 60 if err != nil { 61 return errors.Trace(err) 62 } 63 if len(results.Results) != 1 { 64 return errors.Errorf("expected 1 result, got %d", len(results.Results)) 65 } 66 result := results.Results[0] 67 if result.Error != nil { 68 return result.Error 69 } 70 return nil 71 } 72 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()}}, 80 } 81 err := sa.facade.FacadeCall("WatchUnitStorageAttachments", args, &results) 82 if err != nil { 83 return nil, err 84 } 85 if len(results.Results) != 1 { 86 return nil, errors.Errorf("expected 1 result, got %d", len(results.Results)) 87 } 88 result := results.Results[0] 89 if result.Error != nil { 90 return nil, result.Error 91 } 92 w := apiwatcher.NewStringsWatcher(sa.facade.RawAPICaller(), result) 93 return w, nil 94 } 95 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+)") 101 } 102 args := params.StorageAttachmentIds{ 103 Ids: []params.StorageAttachmentId{{ 104 StorageTag: storageTag.String(), 105 UnitTag: unitTag.String(), 106 }}, 107 } 108 var results params.StorageAttachmentResults 109 err := sa.facade.FacadeCall("StorageAttachments", args, &results) 110 if err != nil { 111 return params.StorageAttachment{}, errors.Trace(err) 112 } 113 if len(results.Results) != 1 { 114 return params.StorageAttachment{}, errors.Errorf("expected 1 result, got %d", len(results.Results)) 115 } 116 result := results.Results[0] 117 if result.Error != nil { 118 return params.StorageAttachment{}, result.Error 119 } 120 return result.Result, nil 121 } 122 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+)") 128 } 129 args := params.StorageAttachmentIds{ids} 130 var results params.LifeResults 131 err := sa.facade.FacadeCall("StorageAttachmentLife", args, &results) 132 if err != nil { 133 return nil, errors.Trace(err) 134 } 135 if len(results.Results) != len(ids) { 136 return nil, errors.Errorf("expected %d results, got %d", len(ids), len(results.Results)) 137 } 138 return results.Results, nil 139 } 140 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(), 149 }}, 150 } 151 err := sa.facade.FacadeCall("WatchStorageAttachments", args, &results) 152 if err != nil { 153 return nil, err 154 } 155 if len(results.Results) != 1 { 156 return nil, errors.Errorf("expected 1 result, got %d", len(results.Results)) 157 } 158 result := results.Results[0] 159 if result.Error != nil { 160 return nil, result.Error 161 } 162 w := apiwatcher.NewNotifyWatcher(sa.facade.RawAPICaller(), result) 163 return w, nil 164 } 165 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(), 175 }}, 176 } 177 err := sa.facade.FacadeCall("RemoveStorageAttachments", args, &results) 178 if err != nil { 179 return err 180 } 181 if len(results.Results) != 1 { 182 return errors.Errorf("expected 1 result, got %d", len(results.Results)) 183 } 184 result := results.Results[0] 185 if result.Error != nil { 186 return result.Error 187 } 188 return nil 189 }