Left: | ||
Right: |
OLD | NEW |
---|---|
(Empty) | |
1 package main | |
2 | |
3 import ( | |
4 "fmt" | |
5 "launchpad.net/gnuflag" | |
6 "launchpad.net/juju-core/cmd" | |
7 "launchpad.net/juju-core/environs" | |
8 "launchpad.net/juju-core/juju" | |
9 "launchpad.net/juju-core/environs/config" | |
10 "launchpad.net/juju-core/state" | |
11 "launchpad.net/juju-core/version" | |
12 ) | |
13 | |
14 // UpgradeJujuCommand upgrades the agents in a juju installation. | |
15 type UpgradeJujuCommand struct { | |
16 EnvName string | |
17 UploadTools bool | |
18 Version version.Number | |
19 Development bool | |
20 conn *juju.Conn | |
21 toolsList *environs.ToolsList | |
22 agentVersion version.Number | |
23 } | |
24 | |
25 var putTools = environs.PutTools | |
26 | |
27 func (c *UpgradeJujuCommand) Info() *cmd.Info { | |
28 return &cmd.Info{"upgrade-juju", "", "upgrade the tools in a juju enviro nment", ""} | |
29 } | |
30 | |
31 func (c *UpgradeJujuCommand) Init(f *gnuflag.FlagSet, args []string) error { | |
32 addEnvironFlags(&c.EnvName, f) | |
33 var vers string | |
34 f.BoolVar(&c.UploadTools, "upload-tools", false, "upload local version o f tools") | |
35 f.StringVar(&vers, "version", "", "version to upgrade to (defaults to hi ghest available version with the current major version number)") | |
36 f.BoolVar(&c.Development, "dev", false, "allow development versions to b e chosen") | |
37 | |
38 if err := f.Parse(true, args); err != nil { | |
39 return err | |
40 } | |
41 if vers != "" { | |
42 var err error | |
43 c.Version, err = version.Parse(vers) | |
44 if err != nil { | |
45 return err | |
46 } | |
47 if c.Version == (version.Number{}) { | |
48 return fmt.Errorf("cannot upgrade to version 0.0.0") | |
49 } | |
50 } | |
51 | |
52 return cmd.CheckEmpty(f.Args()) | |
53 } | |
54 | |
55 // Run changes the version proposed for the juju tools. | |
56 func (c *UpgradeJujuCommand) Run(_ *cmd.Context) error { | |
57 var err error | |
58 c.conn, err = juju.NewConnFromName(c.EnvName) | |
59 if err != nil { | |
60 return err | |
61 } | |
62 defer c.conn.Close() | |
63 | |
64 cfg, err := c.conn.State.EnvironConfig() | |
65 if err != nil { | |
66 return err | |
67 } | |
68 c.agentVersion = cfg.AgentVersion() | |
69 c.toolsList, err = environs.ListTools(c.conn.Environ, c.agentVersion.Maj or) | |
70 if err != nil { | |
71 return err | |
72 } | |
73 if c.UploadTools { | |
74 var forceVersion *version.Binary | |
75 tools, err := putTools(c.conn.Environ.Storage(), forceVersion) | |
76 if err != nil { | |
77 return err | |
78 } | |
79 c.toolsList.Private = append(c.toolsList.Private, tools) | |
80 } | |
81 if c.Version == (version.Number{}) { | |
82 c.Version, err = c.newestVersion() | |
83 if err != nil { | |
84 return fmt.Errorf("cannot find newest version: %v", err) | |
85 } | |
86 } | |
87 if c.Version.Major != c.agentVersion.Major { | |
88 return fmt.Errorf("cannot upgrade major versions yet") | |
89 } | |
90 if c.Version == c.agentVersion && c.Development == cfg.Development() { | |
91 return nil | |
92 } | |
93 return SetStateAgentVersion(c.conn.State, c.Version, c.Development) | |
94 } | |
95 | |
96 // newestVersion returns the newest version of any tool. | |
97 // Private tools take precedence over public tools. | |
98 func (c *UpgradeJujuCommand) newestVersion() (version.Number, error) { | |
99 // When choosing a default version, don't choose | |
100 // a dev version if the current version is a release version. | |
101 allowDev := c.agentVersion.IsDev() || c.Development | |
102 max := c.highestVersion(c.toolsList.Private, allowDev) | |
103 if max != nil { | |
104 return max.Number, nil | |
105 } | |
106 max = c.highestVersion(c.toolsList.Public, allowDev) | |
107 if max == nil { | |
108 return version.Number{}, fmt.Errorf("no tools found") | |
109 } | |
110 return max.Number, nil | |
111 } | |
112 | |
113 // highestVersion returns the tools with the highest | |
114 // version number from the given list. | |
115 func (c *UpgradeJujuCommand) highestVersion(list []*state.Tools, allowDev bool) *state.Tools { | |
116 var max *state.Tools | |
117 for _, t := range list { | |
118 if !allowDev && t.IsDev() { | |
119 continue | |
120 } | |
121 if max == nil || max.Number.Less(t.Number) { | |
122 max = t | |
123 } | |
124 } | |
125 return max | |
126 } | |
127 | |
128 // SetStateAgentVersion sets the current agent version and | |
129 // development flag in the state's environment configuration. | |
130 func SetStateAgentVersion(st *state.State, vers version.Number, development bool ) error { | |
niemeyer
2012/09/06 13:02:09
FWIW, SetAgentVersion sounds like a fine name stil
rog
2012/09/06 16:38:01
Done.
| |
131 cfg, err := st.EnvironConfig() | |
132 if err != nil { | |
133 return err | |
134 } | |
135 attrs := cfg.AllAttrs() | |
136 attrs["agent-version"] = vers.String() | |
137 attrs["development"] = development | |
138 cfg, err = config.New(attrs) | |
139 if err != nil { | |
140 panic(fmt.Errorf("config refused agent-version: %v", err)) | |
141 } | |
142 return st.SetEnvironConfig(cfg) | |
143 } | |
OLD | NEW |