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  }