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 }