launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/state/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  	"launchpad.net/errgo/errors"
    10  	"launchpad.net/juju-core/charm"
    11  	"launchpad.net/juju-core/names"
    12  	"launchpad.net/juju-core/state/api/base"
    13  	"launchpad.net/juju-core/state/api/params"
    14  	"launchpad.net/juju-core/state/api/watcher"
    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  string
    24  	life params.Life
    25  }
    26  
    27  // Name returns the service name.
    28  func (s *Service) Name() string {
    29  	_, serviceName, err := names.ParseTag(s.tag, names.ServiceTagKind)
    30  	if err != nil {
    31  		panic(fmt.Sprintf("%q is not a valid service tag", s.tag))
    32  	}
    33  	return serviceName
    34  }
    35  
    36  // String returns the service as a string.
    37  func (s *Service) String() string {
    38  	return s.Name()
    39  }
    40  
    41  // Watch returns a watcher for observing changes to a service.
    42  func (s *Service) Watch() (watcher.NotifyWatcher, error) {
    43  	var results params.NotifyWatchResults
    44  	args := params.Entities{
    45  		Entities: []params.Entity{{Tag: s.tag}},
    46  	}
    47  	err := s.st.caller.Call("Uniter", "", "Watch", args, &results)
    48  	if err != nil {
    49  		return nil, base.WrapError(err)
    50  	}
    51  	if len(results.Results) != 1 {
    52  		return nil, errors.Newf("expected one result, got %d", len(results.Results))
    53  	}
    54  	result := results.Results[0]
    55  	if result.Error != nil {
    56  		return nil, result.Error
    57  	}
    58  	w := watcher.NewNotifyWatcher(s.st.caller, result)
    59  	return w, nil
    60  }
    61  
    62  // WatchRelations returns a StringsWatcher that notifies of changes to
    63  // the lifecycles of relations involving s.
    64  func (s *Service) WatchRelations() (watcher.StringsWatcher, error) {
    65  	var results params.StringsWatchResults
    66  	args := params.Entities{
    67  		Entities: []params.Entity{{Tag: s.tag}},
    68  	}
    69  	err := s.st.caller.Call("Uniter", "", "WatchServiceRelations", args, &results)
    70  	if err != nil {
    71  		return nil, base.WrapError(err)
    72  	}
    73  	if len(results.Results) != 1 {
    74  		return nil, errors.Newf("expected one result, got %d", len(results.Results))
    75  	}
    76  	result := results.Results[0]
    77  	if result.Error != nil {
    78  		return nil, result.Error
    79  	}
    80  	w := watcher.NewStringsWatcher(s.st.caller, result)
    81  	return w, nil
    82  }
    83  
    84  // Life returns the service's current life state.
    85  func (s *Service) Life() params.Life {
    86  	return s.life
    87  }
    88  
    89  // Refresh refreshes the contents of the Service from the underlying
    90  // state.
    91  func (s *Service) Refresh() error {
    92  	life, err := s.st.life(s.tag)
    93  	if err != nil {
    94  		return base.WrapError(err)
    95  	}
    96  	s.life = life
    97  	return nil
    98  }
    99  
   100  // CharmURL returns the service's charm URL, and whether units should
   101  // upgrade to the charm with that URL even if they are in an error
   102  // state (force flag).
   103  //
   104  // NOTE: This differs from state.Service.CharmURL() by returning
   105  // an error instead as well, because it needs to make an API call.
   106  func (s *Service) CharmURL() (*charm.URL, bool, error) {
   107  	var results params.StringBoolResults
   108  	args := params.Entities{
   109  		Entities: []params.Entity{{Tag: s.tag}},
   110  	}
   111  	err := s.st.caller.Call("Uniter", "", "CharmURL", args, &results)
   112  	if err != nil {
   113  		return nil, false, base.WrapError(err)
   114  	}
   115  	if len(results.Results) != 1 {
   116  		return nil, false, errors.Newf("expected one result, got %d", len(results.Results))
   117  	}
   118  	result := results.Results[0]
   119  	if result.Error != nil {
   120  		return nil, false, result.Error
   121  	}
   122  	if result.Result != "" {
   123  		curl, err := charm.ParseURL(result.Result)
   124  		if err != nil {
   125  			return nil, false, base.WrapError(err)
   126  		}
   127  		return curl, result.Ok, nil
   128  	}
   129  	return nil, false, errors.Newf("%q has no charm url set", s.tag)
   130  }
   131  
   132  // TODO(dimitern) bug #1270795 2014-01-20
   133  // Add a doc comment here.
   134  func (s *Service) GetOwnerTag() (string, error) {
   135  	var result params.StringResult
   136  	args := params.Entities{
   137  		Entities: []params.Entity{{Tag: s.tag}},
   138  	}
   139  	err := s.st.caller.Call("Uniter", "", "GetOwnerTag", args, &result)
   140  	if err != nil {
   141  		return "", base.WrapError(err)
   142  	}
   143  	if result.Error != nil {
   144  		return "", result.Error
   145  	}
   146  	return result.Result, nil
   147  }