Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(121)

Side by Side Diff: worker/uniter/state.go

Issue 6489083: combine charm and hook states as uniter state
Patch Set: combine charm and hook states as uniter state Created 5 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 package uniter
2
3 import (
4 "errors"
5 "fmt"
6 "launchpad.net/juju-core/charm"
7 "launchpad.net/juju-core/trivial"
8 "launchpad.net/juju-core/worker/uniter/hook"
9 "os"
10 )
11
12 // Op enumerates the operations the uniter can perform.
13 type Op string
14
15 const (
16 // Install indicates that the uniter is installing the charm.
17 Install Op = "install"
18
19 // RunHook indicates that the uniter is running a hook.
20 RunHook Op = "run-hook"
21
22 // Upgrade indicates that the uniter is upgrading the charm.
23 Upgrade Op = "upgrade"
24
25 // Abide indicates that the uniter is not currently executing
26 // any other operation.
27 Abide Op = "abide"
28 )
29
30 // Status enumerates the possible operation statuses.
31 type Status string
niemeyer 2012/09/11 14:52:04 Can we call this and the field in State as OpStep?
fwereade 2012/09/12 15:16:40 SGTM. Done.
32
33 const (
34 // Queued indicates that the uniter should undertake the operation
35 // as soon as possible.
36 Queued Status = "queued"
37
38 // Pending indicates that the uniter has started, but not completed,
39 // the operation.
40 Pending Status = "pending"
41
42 // Committing indicates that the uniter has completed the operation,
niemeyer 2012/09/11 14:52:04 This status is feeling a bit awkward now. All of t
43 // but has yet to synchronize all necessary state.
44 Committing Status = "committing"
45 )
46
47 // State defines the local persistent state of the uniter, excluding relation
48 // state.
49 type State struct {
50 // Op indicates the current operation.
51 Op Op
52
53 // Status indicates the current operation's status.
54 Status Status
55
56 // Hook holds hook information relevant to the current operation. If Op
57 // is Abide, it holds the last hook that was executed; if Op is RunHook,
58 // it holds the running hook; if Op is Upgrade, a non-nil hook indicates
59 // that the uniter should return to that hook's Pending state after the
60 // upgrade is complete (instead of running an upgrade-charm hook).
61 Hook *hook.Info `yaml:"hook,omitempty"`
62
63 // Charm describes the charm being deployed by an Install or Upgrade
64 // operation, and is otherwise blank.
65 CharmURL *charm.URL `yaml:"charm,omitempty"`
66 }
67
68 // validate returns an error if the state violates expectations.
69 func (st State) validate() error {
70 hasHook := st.Hook != nil
71 hasCharm := st.CharmURL != nil
72 switch st.Op {
73 case Install:
74 if hasHook {
75 return fmt.Errorf("unexpected hook info")
76 }
77 fallthrough
78 case Upgrade:
79 if !hasCharm {
80 return fmt.Errorf("missing charm URL")
81 }
82 case Abide, RunHook:
83 if !hasHook {
84 return fmt.Errorf("missing hook info")
85 } else if hasCharm {
86 return fmt.Errorf("unexpected charm URL")
87 }
88 default:
89 return fmt.Errorf("unknown operation %q", st.Op)
90 }
91 switch st.Status {
92 case Queued, Pending, Committing:
93 default:
94 return fmt.Errorf("unknown operation status %q", st.Status)
95 }
96 if hasHook {
97 return st.Hook.Validate()
98 }
99 return nil
100 }
101
102 // StateFile reads and writes uniter operation state.
niemeyer 2012/09/11 14:52:04 // A StateFile holds the disk state for a uniter.
fwereade 2012/09/12 15:16:40 Done.
103 type StateFile struct {
104 path string
105 }
106
107 // NewStateFile returns a new StateFile using path.
108 func NewStateFile(path string) *StateFile {
109 return &StateFile{path}
110 }
111
112 var ErrNoStateFile = errors.New("uniter state file does not exist")
113
114 // Read reads a State from the file. If the file does not exist it returns
115 // ErrNoStateFile.
116 func (f *StateFile) Read() (State, error) {
niemeyer 2012/09/11 14:52:04 A *State here would be nice to work with and idiom
fwereade 2012/09/12 15:16:40 Done.
117 var st State
118 if err := trivial.ReadYaml(f.path, &st); err != nil {
119 if os.IsNotExist(err) {
120 return State{}, ErrNoStateFile
121 }
122 }
123 if err := st.validate(); err != nil {
124 return State{}, fmt.Errorf("invalid uniter state at %s: %s", f.p ath, err)
niemeyer 2012/09/11 14:52:04 s/at %s: %s/at %q: %v/
fwereade 2012/09/12 15:16:40 Done.
125 }
126 return st, nil
127 }
128
129 // Write stores the supplied state to the file.
130 func (f *StateFile) Write(op Op, status Status, hi *hook.Info, url *charm.URL) e rror {
131 if hi != nil {
132 // Strip membership info: it's potentially large, and can
133 // be reconstructed from relation state when required.
niemeyer 2012/09/11 14:52:04 This reflects better the intended operation, and r
fwereade 2012/09/12 15:16:40 Nice. Done.
134 hi = &hook.Info{
135 Kind: hi.Kind,
136 RelationId: hi.RelationId,
137 RemoteUnit: hi.RemoteUnit,
138 ChangeVersion: hi.ChangeVersion,
139 }
140 }
141 st := &State{
142 Op: op,
143 Status: status,
144 Hook: hi,
145 CharmURL: url,
146 }
147 if err := st.validate(); err != nil {
148 panic(err)
149 }
150 return trivial.WriteYaml(f.path, st)
151 }
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld 204d58d