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