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