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