~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/api/uniter/application.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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/errors"
 
10
        "gopkg.in/juju/charm.v6-unstable"
 
11
        "gopkg.in/juju/names.v2"
 
12
 
 
13
        "github.com/juju/juju/api/common"
 
14
        apiwatcher "github.com/juju/juju/api/watcher"
 
15
        "github.com/juju/juju/apiserver/params"
 
16
        "github.com/juju/juju/status"
 
17
        "github.com/juju/juju/watcher"
 
18
)
 
19
 
 
20
// This module implements a subset of the interface provided by
 
21
// state.Application, as needed by the uniter API.
 
22
 
 
23
// Application represents the state of an application.
 
24
type Application struct {
 
25
        st   *State
 
26
        tag  names.ApplicationTag
 
27
        life params.Life
 
28
}
 
29
 
 
30
// Tag returns the application's tag.
 
31
func (s *Application) Tag() names.ApplicationTag {
 
32
        return s.tag
 
33
}
 
34
 
 
35
// Name returns the application name.
 
36
func (s *Application) Name() string {
 
37
        return s.tag.Id()
 
38
}
 
39
 
 
40
// String returns the application as a string.
 
41
func (s *Application) String() string {
 
42
        return s.Name()
 
43
}
 
44
 
 
45
// Watch returns a watcher for observing changes to an application.
 
46
func (s *Application) Watch() (watcher.NotifyWatcher, error) {
 
47
        return common.Watch(s.st.facade, s.tag)
 
48
}
 
49
 
 
50
// WatchRelations returns a StringsWatcher that notifies of changes to
 
51
// the lifecycles of relations involving s.
 
52
func (s *Application) WatchRelations() (watcher.StringsWatcher, error) {
 
53
        var results params.StringsWatchResults
 
54
        args := params.Entities{
 
55
                Entities: []params.Entity{{Tag: s.tag.String()}},
 
56
        }
 
57
        err := s.st.facade.FacadeCall("WatchApplicationRelations", args, &results)
 
58
        if err != nil {
 
59
                return nil, err
 
60
        }
 
61
        if len(results.Results) != 1 {
 
62
                return nil, fmt.Errorf("expected 1 result, got %d", len(results.Results))
 
63
        }
 
64
        result := results.Results[0]
 
65
        if result.Error != nil {
 
66
                return nil, result.Error
 
67
        }
 
68
        w := apiwatcher.NewStringsWatcher(s.st.facade.RawAPICaller(), result)
 
69
        return w, nil
 
70
}
 
71
 
 
72
// Life returns the application's current life state.
 
73
func (s *Application) Life() params.Life {
 
74
        return s.life
 
75
}
 
76
 
 
77
// Refresh refreshes the contents of the Service from the underlying
 
78
// state.
 
79
func (s *Application) Refresh() error {
 
80
        life, err := s.st.life(s.tag)
 
81
        if err != nil {
 
82
                return err
 
83
        }
 
84
        s.life = life
 
85
        return nil
 
86
}
 
87
 
 
88
// CharmModifiedVersion increments every time the charm, or any part of it, is
 
89
// changed in some way.
 
90
func (s *Application) CharmModifiedVersion() (int, error) {
 
91
        var results params.IntResults
 
92
        args := params.Entities{
 
93
                Entities: []params.Entity{{Tag: s.tag.String()}},
 
94
        }
 
95
        err := s.st.facade.FacadeCall("CharmModifiedVersion", args, &results)
 
96
        if err != nil {
 
97
                return -1, err
 
98
        }
 
99
 
 
100
        if len(results.Results) != 1 {
 
101
                return -1, fmt.Errorf("expected 1 result, got %d", len(results.Results))
 
102
        }
 
103
        result := results.Results[0]
 
104
        if result.Error != nil {
 
105
                return -1, result.Error
 
106
        }
 
107
 
 
108
        return result.Result, nil
 
109
}
 
110
 
 
111
// CharmURL returns the service's charm URL, and whether units should
 
112
// upgrade to the charm with that URL even if they are in an error
 
113
// state (force flag).
 
114
//
 
115
// NOTE: This differs from state.Service.CharmURL() by returning
 
116
// an error instead as well, because it needs to make an API call.
 
117
func (s *Application) CharmURL() (*charm.URL, bool, error) {
 
118
        var results params.StringBoolResults
 
119
        args := params.Entities{
 
120
                Entities: []params.Entity{{Tag: s.tag.String()}},
 
121
        }
 
122
        err := s.st.facade.FacadeCall("CharmURL", args, &results)
 
123
        if err != nil {
 
124
                return nil, false, err
 
125
        }
 
126
        if len(results.Results) != 1 {
 
127
                return nil, false, fmt.Errorf("expected 1 result, got %d", len(results.Results))
 
128
        }
 
129
        result := results.Results[0]
 
130
        if result.Error != nil {
 
131
                return nil, false, result.Error
 
132
        }
 
133
        if result.Result != "" {
 
134
                curl, err := charm.ParseURL(result.Result)
 
135
                if err != nil {
 
136
                        return nil, false, err
 
137
                }
 
138
                return curl, result.Ok, nil
 
139
        }
 
140
        return nil, false, fmt.Errorf("%q has no charm url set", s.tag)
 
141
}
 
142
 
 
143
// SetStatus sets the status of the service if the passed unitName,
 
144
// corresponding to the calling unit, is of the leader.
 
145
func (s *Application) SetStatus(unitName string, serviceStatus status.Status, info string, data map[string]interface{}) error {
 
146
        tag := names.NewUnitTag(unitName)
 
147
        var result params.ErrorResults
 
148
        args := params.SetStatus{
 
149
                Entities: []params.EntityStatusArgs{
 
150
                        {
 
151
                                Tag:    tag.String(),
 
152
                                Status: serviceStatus.String(),
 
153
                                Info:   info,
 
154
                                Data:   data,
 
155
                        },
 
156
                },
 
157
        }
 
158
        err := s.st.facade.FacadeCall("SetApplicationStatus", args, &result)
 
159
        if err != nil {
 
160
                return errors.Trace(err)
 
161
        }
 
162
        return result.OneError()
 
163
}
 
164
 
 
165
// Status returns the status of the service if the passed unitName,
 
166
// corresponding to the calling unit, is of the leader.
 
167
func (s *Application) Status(unitName string) (params.ApplicationStatusResult, error) {
 
168
        tag := names.NewUnitTag(unitName)
 
169
        var results params.ApplicationStatusResults
 
170
        args := params.Entities{
 
171
                Entities: []params.Entity{
 
172
                        {
 
173
                                Tag: tag.String(),
 
174
                        },
 
175
                },
 
176
        }
 
177
        err := s.st.facade.FacadeCall("ApplicationStatus", args, &results)
 
178
        if err != nil {
 
179
                return params.ApplicationStatusResult{}, errors.Trace(err)
 
180
        }
 
181
        result := results.Results[0]
 
182
        if result.Error != nil {
 
183
                return params.ApplicationStatusResult{}, result.Error
 
184
        }
 
185
        return result, nil
 
186
}
 
187
 
 
188
// WatchLeadershipSettings returns a watcher which can be used to wait
 
189
// for leadership settings changes to be made for the application.
 
190
func (s *Application) WatchLeadershipSettings() (watcher.NotifyWatcher, error) {
 
191
        return s.st.LeadershipSettings.WatchLeadershipSettings(s.tag.Id())
 
192
}