Merge lp:~dave-cheney/juju-core/go-cmd-juju-add-unit into lp:~juju/juju-core/trunk

Proposed by Dave Cheney
Status: Merged
Approved by: Gustavo Niemeyer
Approved revision: no longer in the source branch.
Merged at revision: 374
Proposed branch: lp:~dave-cheney/juju-core/go-cmd-juju-add-unit
Merge into: lp:~juju/juju-core/trunk
Diff against target: 166 lines (+127/-0)
5 files modified
cmd/juju/addunit.go (+62/-0)
cmd/juju/addunit_test.go (+46/-0)
cmd/juju/cmd_test.go (+17/-0)
cmd/juju/main.go (+1/-0)
cmd/juju/main_test.go (+1/-0)
To merge this branch: bzr merge lp:~dave-cheney/juju-core/go-cmd-juju-add-unit
Reviewer Review Type Date Requested Status
The Go Language Gophers Pending
Review via email: mp+118280@code.launchpad.net

Description of the change

cmd/juju: add add-unit command

add-unit adds units.

https://codereview.appspot.com/6449093/

To post a comment you must log in.
Revision history for this message
William Reade (fwereade) wrote :

Code looks fine, but:

https://codereview.appspot.com/6449093/diff/4001/cmd/juju/addunit.go
File cmd/juju/addunit.go (right):

https://codereview.appspot.com/6449093/diff/4001/cmd/juju/addunit.go#newcode1
cmd/juju/addunit.go:1: package main
Can we call this add-unit please? Non-matching names just bug me :).

https://codereview.appspot.com/6449093/diff/4001/cmd/juju/addunit.go#newcode51
cmd/juju/addunit.go:51: st, err := conn.State()
I *think* that this is Doing It Wrong, and that Conn clients are not
meant to interact with state directly, but I may have the wrong end of
the stick.

https://codereview.appspot.com/6449093/

Revision history for this message
Roger Peppe (rogpeppe) wrote :

On 2012/08/06 09:16:36, dfc wrote:
> Thank you for your review.

> https://codereview.appspot.com/6449093/diff/4001/cmd/juju/addunit.go
> File cmd/juju/addunit.go (right):

https://codereview.appspot.com/6449093/diff/4001/cmd/juju/addunit.go#newcode51
> cmd/juju/addunit.go:51: st, err := conn.State()
> On 2012/08/06 06:46:37, fwereade wrote:
> > I *think* that this is Doing It Wrong, and that Conn clients are not
meant to
> > interact with state directly, but I may have the wrong end of the
stick.

> if conn.AddUnits took the service name as a string, we can avoid going
via the
> state. Should I raise a bug to address this ?

That could work. I'm still not sure where the correct line is between
juju.Conn and state.State. We're definitely not *hiding* the State - I'm
inclined to add operations to juju.Conn that make it trivial to
implement the juju command-line operations. AddUnits on the boundary
here, as it's trivial to implement on the State too.

https://codereview.appspot.com/6449093/

Revision history for this message
Roger Peppe (rogpeppe) wrote :
Revision history for this message
Gustavo Niemeyer (niemeyer) wrote :

LGTM with trivials:

https://codereview.appspot.com/6449093/diff/4001/cmd/juju/addunit.go
File cmd/juju/addunit.go (right):

https://codereview.appspot.com/6449093/diff/4001/cmd/juju/addunit.go#newcode1
cmd/juju/addunit.go:1: package main
On 2012/08/06 06:46:37, fwereade wrote:
> Can we call this add-unit please? Non-matching names just bug me :).

+1

https://codereview.appspot.com/6449093/diff/4001/cmd/juju/addunit.go#newcode24
cmd/juju/addunit.go:24: f.IntVar(&c.NumUnits, "num-units", 1, "Number of
service units to add.")
s/Number/number/
s/\.//

Also, I believe we have a -n shorthand for this.

https://codereview.appspot.com/6449093/diff/4001/cmd/juju/addunit.go#newcode51
cmd/juju/addunit.go:51: st, err := conn.State()
On 2012/08/06 09:16:38, dfc wrote:
> On 2012/08/06 06:46:37, fwereade wrote:
> > I *think* that this is Doing It Wrong, and that Conn clients are not
meant to
> > interact with state directly, but I may have the wrong end of the
stick.

> if conn.AddUnits took the service name as a string, we can avoid going
via the
> state. Should I raise a bug to address this ?

I think this is good as it is for now. Conn may be seen as a set of
high-level logic used by command lines, but IMO we don't need one-liner
wrappers there for functionality like the one seen here.

https://codereview.appspot.com/6449093/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'cmd/juju/addunit.go'
2--- cmd/juju/addunit.go 1970-01-01 00:00:00 +0000
3+++ cmd/juju/addunit.go 2012-08-06 04:48:27 +0000
4@@ -0,0 +1,62 @@
5+package main
6+
7+import (
8+ "errors"
9+
10+ "launchpad.net/gnuflag"
11+ "launchpad.net/juju-core/cmd"
12+ "launchpad.net/juju-core/juju"
13+)
14+
15+// AddUnitCommand is responsible adding additional units to a service.
16+type AddUnitCommand struct {
17+ EnvName string
18+ ServiceName string
19+ NumUnits int
20+}
21+
22+func (c *AddUnitCommand) Info() *cmd.Info {
23+ return &cmd.Info{"add-unit", "", "add a service unit", ""}
24+}
25+
26+func (c *AddUnitCommand) Init(f *gnuflag.FlagSet, args []string) error {
27+ addEnvironFlags(&c.EnvName, f)
28+ f.IntVar(&c.NumUnits, "num-units", 1, "Number of service units to add.")
29+ if err := f.Parse(true, args); err != nil {
30+ return err
31+ }
32+ args = f.Args()
33+ switch len(args) {
34+ case 1:
35+ c.ServiceName = args[0]
36+ case 0:
37+ return errors.New("no service specified")
38+ default:
39+ return cmd.CheckEmpty(args[1:])
40+ }
41+ if c.NumUnits < 1 {
42+ return errors.New("must add at least one unit")
43+ }
44+ return nil
45+}
46+
47+// Run connects to the environment specified on the command line
48+// and calls conn.AddUnits.
49+func (c *AddUnitCommand) Run(_ *cmd.Context) error {
50+ conn, err := juju.NewConn(c.EnvName)
51+ if err != nil {
52+ return err
53+ }
54+ defer conn.Close()
55+ st, err := conn.State()
56+ if err != nil {
57+ return err
58+ }
59+ service, err := st.Service(c.ServiceName)
60+ if err != nil {
61+ return err
62+ }
63+ _, err = conn.AddUnits(service, c.NumUnits)
64+ return err
65+
66+}
67
68=== added file 'cmd/juju/addunit_test.go'
69--- cmd/juju/addunit_test.go 1970-01-01 00:00:00 +0000
70+++ cmd/juju/addunit_test.go 2012-08-06 04:48:27 +0000
71@@ -0,0 +1,46 @@
72+package main
73+
74+import (
75+ "bytes"
76+ . "launchpad.net/gocheck"
77+ "launchpad.net/juju-core/charm"
78+ "launchpad.net/juju-core/cmd"
79+ "launchpad.net/juju-core/testing"
80+)
81+
82+type AddUnitSuite struct {
83+ DeploySuite
84+}
85+
86+var _ = Suite(&AddUnitSuite{})
87+
88+func (s *AddUnitSuite) SetUpTest(c *C) {
89+ s.DeploySuite.SetUpTest(c)
90+}
91+
92+func (s *AddUnitSuite) TearDownTest(c *C) {
93+ s.DeploySuite.TearDownTest(c)
94+}
95+
96+func runAddUnit(c *C, args ...string) error {
97+ com := &AddUnitCommand{}
98+ err := com.Init(newFlagSet(), args)
99+ c.Assert(err, IsNil)
100+ return com.Run(&cmd.Context{c.MkDir(), &bytes.Buffer{}, &bytes.Buffer{}})
101+}
102+
103+func (s *AddUnitSuite) TestAddUnit(c *C) {
104+ testing.Charms.BundlePath(s.seriesPath, "dummy")
105+ err := runDeploy(c, "local:dummy", "some-service-name")
106+ c.Assert(err, IsNil)
107+ curl := charm.MustParseURL("local:precise/dummy-1")
108+ s.assertService(c, "some-service-name", curl, 1, 0)
109+
110+ err = runAddUnit(c, "some-service-name")
111+ c.Assert(err, IsNil)
112+ s.assertService(c, "some-service-name", curl, 2, 0)
113+
114+ err = runAddUnit(c, "--num-units", "2", "some-service-name")
115+ c.Assert(err, IsNil)
116+ s.assertService(c, "some-service-name", curl, 4, 0)
117+}
118
119=== modified file 'cmd/juju/cmd_test.go'
120--- cmd/juju/cmd_test.go 2012-07-30 16:51:00 +0000
121+++ cmd/juju/cmd_test.go 2012-08-06 04:48:27 +0000
122@@ -264,3 +264,20 @@
123
124 // environment tested elsewhere
125 }
126+
127+func initAddUnitCommand(args ...string) (*AddUnitCommand, error) {
128+ com := &AddUnitCommand{}
129+ return com, com.Init(newFlagSet(), args)
130+}
131+
132+func (*cmdSuite) TestAddUnitCommandInit(c *C) {
133+ // missing args
134+ _, err := initAddUnitCommand()
135+ c.Assert(err, ErrorMatches, "no service specified")
136+
137+ // bad unit count
138+ _, err = initAddUnitCommand("service-name", "--num-units", "0")
139+ c.Assert(err, ErrorMatches, "must add at least one unit")
140+
141+ // environment tested elsewhere
142+}
143
144=== modified file 'cmd/juju/main.go'
145--- cmd/juju/main.go 2012-07-18 00:33:07 +0000
146+++ cmd/juju/main.go 2012-08-06 04:48:27 +0000
147@@ -25,6 +25,7 @@
148 // provides an entry point for testing with arbitrary command line arguments.
149 func Main(args []string) {
150 juju := &cmd.SuperCommand{Name: "juju", Doc: jujuDoc, Log: &cmd.Log{}}
151+ juju.Register(&AddUnitCommand{})
152 juju.Register(&BootstrapCommand{})
153 juju.Register(&DeployCommand{})
154 juju.Register(&DestroyCommand{})
155
156=== modified file 'cmd/juju/main_test.go'
157--- cmd/juju/main_test.go 2012-07-25 15:46:01 +0000
158+++ cmd/juju/main_test.go 2012-08-06 04:48:27 +0000
159@@ -138,6 +138,7 @@
160 }
161
162 var commandNames = []string{
163+ "add-unit",
164 "bootstrap",
165 "deploy",
166 "destroy-environment",

Subscribers

People subscribed via source and target branches