github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/api/agent/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 "github.com/juju/names/v5" 9 10 "github.com/juju/juju/api/base" 11 apiwatcher "github.com/juju/juju/api/watcher" 12 apiservererrors "github.com/juju/juju/apiserver/errors" 13 "github.com/juju/juju/core/watcher" 14 "github.com/juju/juju/rpc/params" 15 ) 16 17 type StorageAccessor struct { 18 facade base.FacadeCaller 19 } 20 21 // NewStorageAccessor creates a StorageAccessor on the specified facade, 22 // and uses this name when calling through the caller. 23 func NewStorageAccessor(facade base.FacadeCaller) *StorageAccessor { 24 return &StorageAccessor{facade} 25 } 26 27 // UnitStorageAttachments returns the IDs of a unit's storage attachments. 28 func (sa *StorageAccessor) UnitStorageAttachments(unitTag names.UnitTag) ([]params.StorageAttachmentId, error) { 29 args := params.Entities{ 30 Entities: []params.Entity{{Tag: unitTag.String()}}, 31 } 32 var results params.StorageAttachmentIdsResults 33 err := sa.facade.FacadeCall("UnitStorageAttachments", args, &results) 34 if err != nil { 35 return nil, errors.Trace(err) 36 } 37 if len(results.Results) != 1 { 38 return nil, errors.Errorf("expected 1 result, got %d", len(results.Results)) 39 } 40 result := results.Results[0] 41 if result.Error != nil { 42 return nil, result.Error 43 } 44 return result.Result.Ids, nil 45 } 46 47 // DestroyUnitStorageAttachments ensures that the specified unit's storage 48 // attachments will be removed at some point in the future. 49 func (sa *StorageAccessor) DestroyUnitStorageAttachments(unitTag names.UnitTag) error { 50 args := params.Entities{ 51 Entities: []params.Entity{{Tag: unitTag.String()}}, 52 } 53 var results params.ErrorResults 54 err := sa.facade.FacadeCall("DestroyUnitStorageAttachments", args, &results) 55 if err != nil { 56 return errors.Trace(err) 57 } 58 if len(results.Results) != 1 { 59 return errors.Errorf("expected 1 result, got %d", len(results.Results)) 60 } 61 result := results.Results[0] 62 if result.Error != nil { 63 return result.Error 64 } 65 return nil 66 } 67 68 // WatchUnitStorageAttachments starts a watcher for changes to storage 69 // attachments related to the unit. The watcher will return the 70 // IDs of the corresponding storage instances. 71 func (sa *StorageAccessor) WatchUnitStorageAttachments(unitTag names.UnitTag) (watcher.StringsWatcher, error) { 72 var results params.StringsWatchResults 73 args := params.Entities{ 74 Entities: []params.Entity{{Tag: unitTag.String()}}, 75 } 76 err := sa.facade.FacadeCall("WatchUnitStorageAttachments", args, &results) 77 if err != nil { 78 return nil, err 79 } 80 if len(results.Results) != 1 { 81 return nil, errors.Errorf("expected 1 result, got %d", len(results.Results)) 82 } 83 result := results.Results[0] 84 if result.Error != nil { 85 return nil, result.Error 86 } 87 w := apiwatcher.NewStringsWatcher(sa.facade.RawAPICaller(), result) 88 return w, nil 89 } 90 91 // StorageAttachment returns the storage attachment with the specified 92 // unit and storage tags. 93 func (sa *StorageAccessor) StorageAttachment(storageTag names.StorageTag, unitTag names.UnitTag) (params.StorageAttachment, error) { 94 args := params.StorageAttachmentIds{ 95 Ids: []params.StorageAttachmentId{{ 96 StorageTag: storageTag.String(), 97 UnitTag: unitTag.String(), 98 }}, 99 } 100 var results params.StorageAttachmentResults 101 err := sa.facade.FacadeCall("StorageAttachments", args, &results) 102 if err != nil { 103 return params.StorageAttachment{}, errors.Trace(err) 104 } 105 if len(results.Results) != 1 { 106 return params.StorageAttachment{}, errors.Errorf("expected 1 result, got %d", len(results.Results)) 107 } 108 result := results.Results[0] 109 if result.Error != nil { 110 return params.StorageAttachment{}, apiservererrors.RestoreError(result.Error) 111 } 112 return result.Result, nil 113 } 114 115 // StorageAttachmentLife returns the lifecycle state of the storage attachments 116 // with the specified IDs. 117 func (sa *StorageAccessor) StorageAttachmentLife(ids []params.StorageAttachmentId) ([]params.LifeResult, error) { 118 args := params.StorageAttachmentIds{ids} 119 var results params.LifeResults 120 err := sa.facade.FacadeCall("StorageAttachmentLife", args, &results) 121 if err != nil { 122 return nil, errors.Trace(err) 123 } 124 if len(results.Results) != len(ids) { 125 return nil, errors.Errorf("expected %d results, got %d", len(ids), len(results.Results)) 126 } 127 return results.Results, nil 128 } 129 130 // WatchStorageAttachments starts a watcher for changes to the info 131 // of the storage attachment with the specified unit and storage tags. 132 func (sa *StorageAccessor) WatchStorageAttachment(storageTag names.StorageTag, unitTag names.UnitTag) (watcher.NotifyWatcher, error) { 133 var results params.NotifyWatchResults 134 args := params.StorageAttachmentIds{ 135 Ids: []params.StorageAttachmentId{{ 136 StorageTag: storageTag.String(), 137 UnitTag: unitTag.String(), 138 }}, 139 } 140 err := sa.facade.FacadeCall("WatchStorageAttachments", args, &results) 141 if err != nil { 142 return nil, err 143 } 144 if len(results.Results) != 1 { 145 return nil, errors.Errorf("expected 1 result, got %d", len(results.Results)) 146 } 147 result := results.Results[0] 148 if result.Error != nil { 149 return nil, result.Error 150 } 151 w := apiwatcher.NewNotifyWatcher(sa.facade.RawAPICaller(), result) 152 return w, nil 153 } 154 155 // RemoveStorageAttachment removes the storage attachment with the 156 // specified unit and storage tags from state. This method is only 157 // expected to succeed if the storage attachment is Dead. 158 func (sa *StorageAccessor) RemoveStorageAttachment(storageTag names.StorageTag, unitTag names.UnitTag) error { 159 var results params.ErrorResults 160 args := params.StorageAttachmentIds{ 161 Ids: []params.StorageAttachmentId{{ 162 StorageTag: storageTag.String(), 163 UnitTag: unitTag.String(), 164 }}, 165 } 166 err := sa.facade.FacadeCall("RemoveStorageAttachments", args, &results) 167 if err != nil { 168 return err 169 } 170 if len(results.Results) != 1 { 171 return errors.Errorf("expected 1 result, got %d", len(results.Results)) 172 } 173 result := results.Results[0] 174 if result.Error != nil { 175 return result.Error 176 } 177 return nil 178 }