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

Side by Side Diff: cmd/juju/upgradecharm.go

Issue 8540050: cmd/juju: upgrade-charm --switch support (Closed)
Patch Set: cmd/juju: upgrade-charm --switch support Created 10 years, 11 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 | « [revision details] ('k') | cmd/juju/upgradecharm_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 "errors" 4 "errors"
5 "fmt" 5 "fmt"
6 "launchpad.net/gnuflag" 6 "launchpad.net/gnuflag"
7 "launchpad.net/juju-core/charm" 7 "launchpad.net/juju-core/charm"
8 "launchpad.net/juju-core/cmd" 8 "launchpad.net/juju-core/cmd"
9 "launchpad.net/juju-core/juju" 9 "launchpad.net/juju-core/juju"
10 "launchpad.net/juju-core/state" 10 "launchpad.net/juju-core/state"
11 "os" 11 "os"
12 ) 12 )
13 13
14 // UpgradeCharm is responsible for upgrading a service's charm. 14 // UpgradeCharm is responsible for upgrading a service's charm.
15 type UpgradeCharmCommand struct { 15 type UpgradeCharmCommand struct {
16 EnvCommandBase 16 EnvCommandBase
17 ServiceName string 17 ServiceName string
18 Force bool 18 Force bool
19 RepoPath string // defaults to JUJU_REPOSITORY 19 RepoPath string // defaults to JUJU_REPOSITORY
20 SwitchURL string
21 Revision int // defaults to -1 (latest)
20 } 22 }
21 23
22 const upgradeCharmDoc = ` 24 const upgradeCharmDoc = `
23 When no flags are set, the service's charm will be upgraded to the latest 25 When no flags are set, the service's charm will be upgraded to the
24 revision available in the repository from which it was originally deployed. 26 latest revision available in the repository from which it was
27 originally deployed. An explicit revision can be chosen with the
28 --revision flag.
25 29
26 If the charm came from a local repository, its path will be assumed to be 30 If the charm came from a local repository, its path will be assumed to
27 $JUJU_REPOSITORY unless overridden by --repository. If there is no newer 31 be $JUJU_REPOSITORY unless overridden by --repository. If there is no
28 revision of a local charm directory, the local directory's revision will be 32 newer revision of a local charm directory, the local directory's
29 automatically incremented to create a newer charm. 33 revision will be automatically incremented to create a newer charm.
30 34
31 The local repository behaviour is tuned specifically to the workflow of a charm 35 The local repository behaviour is tuned specifically to the workflow
32 author working on a single client machine; use of local repositories from 36 of a charm author working on a single client machine; use of local
33 multiple clients is not supported and may lead to confusing behaviour. 37 repositories from multiple clients is not supported and may lead to
38 confusing behaviour.
34 39
35 Use of the --force flag is not generally recommended; units upgraded while in 40 The --switch flag allows you to replace the charm with an entirely
36 an error state will not have upgrade-charm hooks executed, and may cause 41 different one. The new charm's URL and revision are inferred as they
37 unexpected behavior. 42 would be when running a deploy command.
43
44 Please note that --switch is dangerous, because juju only has limited
45 information with which to determine compatibility; the operation will
46 succeed, regardless of potential havoc, so long as the following
47 conditions hold:
48
49 - The new charm must declare all relations that the service is
50 currently participating in.
51 - All config settings shared by the old and new charms must have the
52 same types.
53
54 The new charm may add new relations and configuration settings.
55
56 --switch and --revision are mutually exclusive. To specify a given
57 revision number with --switch, give it in the charm URL, for instance
58 "cs:wordpress-5" would specify revision number 5 of the wordpress
59 charm.
60
61 Use of the --force flag is not generally recommended; units upgraded
62 while in an error state will not have upgrade-charm hooks executed,
63 and may cause unexpected behavior.
38 ` 64 `
39 65
40 func (c *UpgradeCharmCommand) Info() *cmd.Info { 66 func (c *UpgradeCharmCommand) Info() *cmd.Info {
41 return &cmd.Info{ 67 return &cmd.Info{
42 Name: "upgrade-charm", 68 Name: "upgrade-charm",
43 Args: "<service>", 69 Args: "<service>",
44 Purpose: "upgrade a service's charm", 70 Purpose: "upgrade a service's charm",
45 Doc: upgradeCharmDoc, 71 Doc: upgradeCharmDoc,
46 } 72 }
47 } 73 }
48 74
49 func (c *UpgradeCharmCommand) SetFlags(f *gnuflag.FlagSet) { 75 func (c *UpgradeCharmCommand) SetFlags(f *gnuflag.FlagSet) {
50 c.EnvCommandBase.SetFlags(f) 76 c.EnvCommandBase.SetFlags(f)
51 f.BoolVar(&c.Force, "force", false, "upgrade all units immediately, even if in error state") 77 f.BoolVar(&c.Force, "force", false, "upgrade all units immediately, even if in error state")
52 f.StringVar(&c.RepoPath, "repository", os.Getenv("JUJU_REPOSITORY"), "lo cal charm repository path") 78 f.StringVar(&c.RepoPath, "repository", os.Getenv("JUJU_REPOSITORY"), "lo cal charm repository path")
79 f.StringVar(&c.SwitchURL, "switch", "", "crossgrade to a different charm ")
80 f.IntVar(&c.Revision, "revision", -1, "explicit revision of current char m")
53 } 81 }
54 82
55 func (c *UpgradeCharmCommand) Init(args []string) error { 83 func (c *UpgradeCharmCommand) Init(args []string) error {
56 switch len(args) { 84 switch len(args) {
57 case 1: 85 case 1:
58 if !state.IsServiceName(args[0]) { 86 if !state.IsServiceName(args[0]) {
59 return fmt.Errorf("invalid service name %q", args[0]) 87 return fmt.Errorf("invalid service name %q", args[0])
60 } 88 }
61 c.ServiceName = args[0] 89 c.ServiceName = args[0]
62 case 0: 90 case 0:
63 return errors.New("no service specified") 91 return errors.New("no service specified")
64 default: 92 default:
65 return cmd.CheckEmpty(args[1:]) 93 return cmd.CheckEmpty(args[1:])
66 } 94 }
67 » // TODO(dimitern): add the other flags --switch and --revision. 95 » if c.SwitchURL != "" && c.Revision != -1 {
96 » » return fmt.Errorf("--switch and --revision are mutually exclusiv e")
97 » }
68 return nil 98 return nil
69 } 99 }
70 100
71 // Run connects to the specified environment and starts the charm 101 // Run connects to the specified environment and starts the charm
72 // upgrade process. 102 // upgrade process.
73 func (c *UpgradeCharmCommand) Run(ctx *cmd.Context) error { 103 func (c *UpgradeCharmCommand) Run(ctx *cmd.Context) error {
74 conn, err := juju.NewConnFromName(c.EnvName) 104 conn, err := juju.NewConnFromName(c.EnvName)
75 if err != nil { 105 if err != nil {
76 return err 106 return err
77 } 107 }
78 defer conn.Close() 108 defer conn.Close()
79 service, err := conn.State.Service(c.ServiceName) 109 service, err := conn.State.Service(c.ServiceName)
80 if err != nil { 110 if err != nil {
81 return err 111 return err
82 } 112 }
83 » curl, _ := service.CharmURL() 113 » oldURL, _ := service.CharmURL()
84 » repo, err := charm.InferRepository(curl, ctx.AbsPath(c.RepoPath)) 114 » var newURL *charm.URL
115 » if c.SwitchURL != "" {
116 » » // A new charm URL was explicitly specified.
117 » » conf, err := conn.State.EnvironConfig()
118 » » if err != nil {
119 » » » return err
120 » » }
121 » » newURL, err = charm.InferURL(c.SwitchURL, conf.DefaultSeries())
122 » » if err != nil {
123 » » » return err
124 » » }
125 » } else {
126 » » // No new URL specified, but revision might have been.
127 » » newURL = oldURL.WithRevision(c.Revision)
128 » }
129 » repo, err := charm.InferRepository(newURL, ctx.AbsPath(c.RepoPath))
85 if err != nil { 130 if err != nil {
86 return err 131 return err
87 } 132 }
88 » rev, err := repo.Latest(curl) 133 » // If no explicit revision was set with either SwitchURL
134 » // or Revision flags, discover the latest.
135 » explicitRevision := true
136 » if newURL.Revision == -1 {
137 » » explicitRevision = false
138 » » latest, err := repo.Latest(newURL)
139 » » if err != nil {
140 » » » return err
141 » » }
142 » » newURL = newURL.WithRevision(latest)
143 » }
144 » bumpRevision := false
145 » if *newURL == *oldURL {
146 » » if explicitRevision {
147 » » » return fmt.Errorf("already running specified charm %q", newURL)
148 » » }
149 » » // Only try bumping the revision when necessary (local dir charm ).
150 » » if _, isLocal := repo.(*charm.LocalRepository); !isLocal {
151 » » » // TODO(dimitern): If the --force flag is set to somethi ng
152 » » » // different to before, we might actually want to allow this
153 » » » // case (and the other error below). LP bug #1174287
fwereade 2013/04/29 16:34:08 Move this comment up to the top case.
154 » » » return fmt.Errorf("already running latest charm %q", new URL)
155 » » }
156 » » // This is a local repository.
157 » » if ch, err := repo.Get(newURL); err != nil {
158 » » » return err
159 » » } else if _, bumpRevision = ch.(*charm.Dir); !bumpRevision {
160 » » » // Only bump the revision when it's a directory.
161 » » » return fmt.Errorf("already running latest charm %q", new URL)
162 » » }
163 » }
164 » sch, err := conn.PutCharm(newURL, repo, bumpRevision)
89 if err != nil { 165 if err != nil {
90 return err 166 return err
91 } 167 }
92 bumpRevision := false
93 if curl.Revision == rev {
94 if _, isLocal := repo.(*charm.LocalRepository); !isLocal {
95 return fmt.Errorf("already running latest charm %q", cur l)
96 }
97 // This is a local repository.
98 if ch, err := repo.Get(curl); err != nil {
99 return err
100 } else if _, bumpRevision = ch.(*charm.Dir); !bumpRevision {
fwereade 2013/04/29 16:34:08 We could just not bother checking this, and always
101 // Only bump the revision when it's a directory.
102 return fmt.Errorf("already running latest charm %q", cur l)
103 }
104 }
105 sch, err := conn.PutCharm(curl.WithRevision(rev), repo, bumpRevision)
106 if err != nil {
107 return err
108 }
109 return service.SetCharm(sch, c.Force) 168 return service.SetCharm(sch, c.Force)
110 } 169 }
OLDNEW
« no previous file with comments | « [revision details] ('k') | cmd/juju/upgradecharm_test.go » ('j') | no next file with comments »

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