github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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/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  		panic(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  		panic(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  		panic(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  		panic(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  }