github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/api/uniter/service.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package uniter
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/juju/names"
    10  	"gopkg.in/juju/charm.v4"
    11  
    12  	"github.com/juju/juju/api/common"
    13  	"github.com/juju/juju/api/watcher"
    14  	"github.com/juju/juju/apiserver/params"
    15  )
    16  
    17  // This module implements a subset of the interface provided by
    18  // state.Service, as needed by the uniter API.
    19  
    20  // Service represents the state of a service.
    21  type Service struct {
    22  	st   *State
    23  	tag  names.ServiceTag
    24  	life params.Life
    25  }
    26  
    27  // Tag returns the service's tag.
    28  func (s *Service) Tag() names.ServiceTag {
    29  	return s.tag
    30  }
    31  
    32  // Name returns the service name.
    33  func (s *Service) Name() string {
    34  	return s.tag.Id()
    35  }
    36  
    37  // String returns the service as a string.
    38  func (s *Service) String() string {
    39  	return s.Name()
    40  }
    41  
    42  // Watch returns a watcher for observing changes to a service.
    43  func (s *Service) Watch() (watcher.NotifyWatcher, error) {
    44  	return common.Watch(s.st.facade, s.tag)
    45  }
    46  
    47  // WatchRelations returns a StringsWatcher that notifies of changes to
    48  // the lifecycles of relations involving s.
    49  func (s *Service) WatchRelations() (watcher.StringsWatcher, error) {
    50  	var results params.StringsWatchResults
    51  	args := params.Entities{
    52  		Entities: []params.Entity{{Tag: s.tag.String()}},
    53  	}
    54  	err := s.st.facade.FacadeCall("WatchServiceRelations", args, &results)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  	if len(results.Results) != 1 {
    59  		return nil, fmt.Errorf("expected 1 result, got %d", len(results.Results))
    60  	}
    61  	result := results.Results[0]
    62  	if result.Error != nil {
    63  		return nil, result.Error
    64  	}
    65  	w := watcher.NewStringsWatcher(s.st.facade.RawAPICaller(), result)
    66  	return w, nil
    67  }
    68  
    69  // Life returns the service's current life state.
    70  func (s *Service) Life() params.Life {
    71  	return s.life
    72  }
    73  
    74  // Refresh refreshes the contents of the Service from the underlying
    75  // state.
    76  func (s *Service) Refresh() error {
    77  	life, err := s.st.life(s.tag)
    78  	if err != nil {
    79  		return err
    80  	}
    81  	s.life = life
    82  	return nil
    83  }
    84  
    85  // CharmURL returns the service's charm URL, and whether units should
    86  // upgrade to the charm with that URL even if they are in an error
    87  // state (force flag).
    88  //
    89  // NOTE: This differs from state.Service.CharmURL() by returning
    90  // an error instead as well, because it needs to make an API call.
    91  func (s *Service) CharmURL() (*charm.URL, bool, error) {
    92  	var results params.StringBoolResults
    93  	args := params.Entities{
    94  		Entities: []params.Entity{{Tag: s.tag.String()}},
    95  	}
    96  	err := s.st.facade.FacadeCall("CharmURL", args, &results)
    97  	if err != nil {
    98  		return nil, false, err
    99  	}
   100  	if len(results.Results) != 1 {
   101  		return nil, false, fmt.Errorf("expected 1 result, got %d", len(results.Results))
   102  	}
   103  	result := results.Results[0]
   104  	if result.Error != nil {
   105  		return nil, false, result.Error
   106  	}
   107  	if result.Result != "" {
   108  		curl, err := charm.ParseURL(result.Result)
   109  		if err != nil {
   110  			return nil, false, err
   111  		}
   112  		return curl, result.Ok, nil
   113  	}
   114  	return nil, false, fmt.Errorf("%q has no charm url set", s.tag)
   115  }
   116  
   117  // OwnerTag returns the service's owner user tag.
   118  func (s *Service) OwnerTag() (names.UserTag, error) {
   119  	if s.st.BestAPIVersion() > 0 {
   120  		return s.serviceOwnerTag()
   121  	}
   122  	return s.ownerTag()
   123  }
   124  
   125  func (s *Service) serviceOwnerTag() (names.UserTag, error) {
   126  	var invalidTag names.UserTag
   127  	var results params.StringResults
   128  	args := params.Entities{
   129  		Entities: []params.Entity{{Tag: s.tag.String()}},
   130  	}
   131  	err := s.st.facade.FacadeCall("ServiceOwner", args, &results)
   132  	if err != nil {
   133  		return invalidTag, err
   134  	}
   135  	if len(results.Results) != 1 {
   136  		return invalidTag, fmt.Errorf("expected 1 result, got %d", len(results.Results))
   137  	}
   138  	result := results.Results[0]
   139  	if result.Error != nil {
   140  		return invalidTag, result.Error
   141  	}
   142  	return names.ParseUserTag(result.Result)
   143  }
   144  
   145  func (s *Service) ownerTag() (names.UserTag, error) {
   146  	var invalidTag names.UserTag
   147  	var result params.StringResult
   148  	args := params.Entities{
   149  		Entities: []params.Entity{{Tag: s.tag.String()}},
   150  	}
   151  	err := s.st.facade.FacadeCall("GetOwnerTag", args, &result)
   152  	if err != nil {
   153  		return invalidTag, err
   154  	}
   155  	if result.Error != nil {
   156  		return invalidTag, result.Error
   157  	}
   158  	return names.ParseUserTag(result.Result)
   159  }