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

Side by Side Diff: cmd/jujud/upgrade.go

Issue 6490067: state: remove ProposedTools.
Patch Set: state: remove ProposedTools. Created 12 years, 7 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
« no previous file with comments | « cmd/jujud/provisioning_test.go ('k') | cmd/jujud/upgrade_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 package main 1 package main
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 "launchpad.net/juju-core/downloader" 5 "launchpad.net/juju-core/downloader"
6 "launchpad.net/juju-core/environs" 6 "launchpad.net/juju-core/environs"
7 "launchpad.net/juju-core/log" 7 "launchpad.net/juju-core/log"
8 "launchpad.net/juju-core/state" 8 "launchpad.net/juju-core/state"
9 "launchpad.net/juju-core/state/watcher" 9 "launchpad.net/juju-core/state/watcher"
10 "launchpad.net/juju-core/version" 10 "launchpad.net/juju-core/version"
11 "launchpad.net/juju-core/worker"
11 "launchpad.net/tomb" 12 "launchpad.net/tomb"
12 "os" 13 "os"
13 ) 14 )
14 15
15 // An Upgrader observes the version information for an agent in the 16 // An Upgrader observes the version information for an agent in the
16 // environment state, and handles the downloading and unpacking of 17 // environment state, and handles the downloading and unpacking of
17 // new versions of the juju tools when necessary. 18 // new versions of the juju tools when necessary.
18 // 19 //
19 // When a new version is available Wait and Stop return UpgradedError. 20 // When a new version is available Wait and Stop return UpgradedError.
20 type Upgrader struct { 21 type Upgrader struct {
21 tomb tomb.Tomb 22 tomb tomb.Tomb
23 st *state.State
22 agentName string 24 agentName string
23 agentState AgentState 25 agentState AgentState
24 } 26 }
25 27
26 // UpgradedError is returned by an Upgrader to report that 28 // UpgradedError is returned by an Upgrader to report that
27 // an upgrade has been performed and a restart is due. 29 // an upgrade has been performed and a restart is due.
28 type UpgradedError struct { 30 type UpgradedError struct {
29 *state.Tools 31 *state.Tools
30 } 32 }
31 33
32 func (e *UpgradedError) Error() string { 34 func (e *UpgradedError) Error() string {
33 return fmt.Sprintf("must restart: agent has been upgraded to %v (from %q )", e.Binary, e.URL) 35 return fmt.Sprintf("must restart: agent has been upgraded to %v (from %q )", e.Binary, e.URL)
34 } 36 }
35 37
36 // The AgentState interface is implemented by state types 38 // The AgentState interface is implemented by state types
37 // that represent running agents. 39 // that represent running agents.
38 type AgentState interface { 40 type AgentState interface {
39 // SetAgentTools sets the tools that the agent is currently running. 41 // SetAgentTools sets the tools that the agent is currently running.
40 SetAgentTools(tools *state.Tools) error 42 SetAgentTools(tools *state.Tools) error
41
42 // WatchProposedAgentTools watches the tools that the agent is
43 // currently proposed to run.
44 WatchProposedAgentTools() *state.AgentToolsWatcher
45 } 43 }
46 44
47 // NewUpgrader returns a new Upgrader watching the given agent. 45 // NewUpgrader returns a new Upgrader watching the given agent.
48 func NewUpgrader(agentName string, agentState AgentState) *Upgrader { 46 func NewUpgrader(st *state.State, agentName string, agentState AgentState) *Upgr ader {
49 u := &Upgrader{ 47 u := &Upgrader{
48 st: st,
50 agentName: agentName, 49 agentName: agentName,
51 agentState: agentState, 50 agentState: agentState,
52 } 51 }
53 go func() { 52 go func() {
54 defer u.tomb.Done() 53 defer u.tomb.Done()
55 u.tomb.Kill(u.run()) 54 u.tomb.Kill(u.run())
56 }() 55 }()
57 return u 56 return u
58 } 57 }
59 58
(...skipping 16 matching lines...) Expand all
76 log.Printf("upgrader: cannot read current tools: %v", err) 75 log.Printf("upgrader: cannot read current tools: %v", err)
77 currentTools = &state.Tools{ 76 currentTools = &state.Tools{
78 Binary: version.Current, 77 Binary: version.Current,
79 } 78 }
80 } 79 }
81 err = u.agentState.SetAgentTools(currentTools) 80 err = u.agentState.SetAgentTools(currentTools)
82 if err != nil { 81 if err != nil {
83 return err 82 return err
84 } 83 }
85 84
86 » w := u.agentState.WatchProposedAgentTools() 85 » w := u.st.WatchEnvironConfig()
87 defer watcher.Stop(w, &u.tomb) 86 defer watcher.Stop(w, &u.tomb)
88 87
88 environ, err := worker.WaitForEnviron(w, u.tomb.Dying())
89 if err != nil {
90 return err
91 }
92
89 // TODO(rog) retry downloads when they fail. 93 // TODO(rog) retry downloads when they fail.
90 var ( 94 var (
91 download *downloader.Download 95 download *downloader.Download
92 downloadTools *state.Tools 96 downloadTools *state.Tools
93 downloadDone <-chan downloader.Status 97 downloadDone <-chan downloader.Status
94 ) 98 )
95 for { 99 for {
96 // We wait for the tools to change while we're downloading 100 // We wait for the tools to change while we're downloading
97 // so that if something goes wrong (for instance a bad URL 101 // so that if something goes wrong (for instance a bad URL
98 // hangs up) another change to the proposed tools can 102 // hangs up) another change to the proposed tools can
99 // potentially fix things. 103 // potentially fix things.
100 select { 104 select {
101 » » case tools, ok := <-w.Changes(): 105 » » case cfg, ok := <-w.Changes():
102 if !ok { 106 if !ok {
103 return watcher.MustErr(w) 107 return watcher.MustErr(w)
104 } 108 }
109 err := environ.SetConfig(cfg)
110 if err != nil {
111 log.Printf("provisioner loaded invalid environme nt configuration: %v", err)
112 // continue on, because the version number is st ill significant.
113 }
114 vers := cfg.AgentVersion()
105 if download != nil { 115 if download != nil {
106 // There's a download in progress, stop it if we need to. 116 // There's a download in progress, stop it if we need to.
107 » » » » if *tools == *downloadTools { 117 » » » » if vers == downloadTools.Number {
108 // We are already downloading the reques ted tools. 118 // We are already downloading the reques ted tools.
109 break 119 break
110 } 120 }
111 // Tools changed. We need to stop and restart. 121 // Tools changed. We need to stop and restart.
112 download.Stop() 122 download.Stop()
113 download, downloadTools, downloadDone = nil, nil , nil 123 download, downloadTools, downloadDone = nil, nil , nil
114 } 124 }
115 // Ignore the proposed tools if they haven't been set ye t 125 // Ignore the proposed tools if they haven't been set ye t
116 // or we're already running the proposed version. 126 // or we're already running the proposed version.
117 » » » if tools.URL == "" || *tools == *currentTools { 127 » » » if vers == version.Current.Number {
118 break 128 break
119 } 129 }
120 » » » if tools, err := environs.ReadTools(tools.Binary); err = = nil { 130 » » » binary := version.Current
131 » » » binary.Number = vers
132
133 » » » if tools, err := environs.ReadTools(binary); err == nil {
121 // The tools have already been downloaded, so us e them. 134 // The tools have already been downloaded, so us e them.
122 return &UpgradedError{tools} 135 return &UpgradedError{tools}
123 } 136 }
137 // TODO(rog) add support for environs.DevVersion
138 tools, err := environs.FindTools(environ, binary, enviro ns.CompatVersion)
139 if err != nil {
140 log.Printf("upgrader: error finding tools for %v : %v", binary, err)
141 // TODO(rog): poll until tools become available.
142 break
143 }
144 if tools.Binary != binary {
145 if tools.Number == version.Current.Number {
146 // TODO(rog): poll until tools become av ailable.
147 log.Printf("upgrader: version %v request ed but no newer version found", binary)
148 break
149 }
150 log.Printf("upgrader: cannot find exact tools ma tch for %s; using %s instead", binary, tools.Binary)
151 }
124 download = downloader.New(tools.URL, "") 152 download = downloader.New(tools.URL, "")
125 downloadTools = tools 153 downloadTools = tools
126 downloadDone = download.Done() 154 downloadDone = download.Done()
127 case status := <-downloadDone: 155 case status := <-downloadDone:
128 tools := downloadTools 156 tools := downloadTools
129 download, downloadTools, downloadDone = nil, nil, nil 157 download, downloadTools, downloadDone = nil, nil, nil
130 if status.Err != nil { 158 if status.Err != nil {
131 log.Printf("upgrader: download of %v failed: %v" , tools.Binary, status.Err) 159 log.Printf("upgrader: download of %v failed: %v" , tools.Binary, status.Err)
132 break 160 break
133 } 161 }
134 err := environs.UnpackTools(tools, status.File) 162 err := environs.UnpackTools(tools, status.File)
135 status.File.Close() 163 status.File.Close()
136 if err := os.Remove(status.File.Name()); err != nil { 164 if err := os.Remove(status.File.Name()); err != nil {
137 log.Printf("upgrader: cannot remove temporary do wnload file: %v", u.agentName, err) 165 log.Printf("upgrader: cannot remove temporary do wnload file: %v", u.agentName, err)
138 } 166 }
139 if err != nil { 167 if err != nil {
140 log.Printf("upgrader: cannot unpack %v tools: %v ", tools.Binary, err) 168 log.Printf("upgrader: cannot unpack %v tools: %v ", tools.Binary, err)
141 break 169 break
142 } 170 }
143 return &UpgradedError{tools} 171 return &UpgradedError{tools}
144 case <-u.tomb.Dying(): 172 case <-u.tomb.Dying():
145 return nil 173 return nil
146 } 174 }
147 } 175 }
148 panic("not reached") 176 panic("not reached")
149 } 177 }
OLDNEW
« no previous file with comments | « cmd/jujud/provisioning_test.go ('k') | cmd/jujud/upgrade_test.go » ('j') | no next file with comments »

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