Merge lp:~axwalk/juju-core/cmdapi-ensureavailability into lp:~go-bot/juju-core/trunk

Proposed by Andrew Wilkins
Status: Merged
Approved by: Andrew Wilkins
Approved revision: no longer in the source branch.
Merged at revision: 2507
Proposed branch: lp:~axwalk/juju-core/cmdapi-ensureavailability
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 343 lines (+288/-0)
7 files modified
cmd/juju/ensureavailability.go (+81/-0)
cmd/juju/ensureavailability_test.go (+114/-0)
cmd/juju/main.go (+4/-0)
state/api/client.go (+10/-0)
state/api/params/params.go (+10/-0)
state/apiserver/client/client.go (+13/-0)
state/apiserver/client/client_test.go (+56/-0)
To merge this branch: bzr merge lp:~axwalk/juju-core/cmdapi-ensureavailability
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+213190@code.launchpad.net

Commit message

Add ensure-availability command, EnsureAvailability API

We introduce a new ensure-availability juju subcommand, which
calls the new EnsureAvailability client API. This
is the CLI for ensuring high availability of Juju
state servers.

Note: I have not exposed the ensure-availability command yet,
as there is still work to be done in the agents to
properly support HA state servers.

https://codereview.appspot.com/81700043/

Description of the change

ensure-availability command

We introduce a new ensure-availability juju subcommand,
which calls the new EnsureAvailability client API. This
is the CLI for ensuring high availability of Juju
state servers.

Note: I have not exposed the ensure-availability command yet,
as there is still work to be done in the agents to
properly support HA state servers.

https://codereview.appspot.com/81700043/

To post a comment you must log in.
Revision history for this message
Andrew Wilkins (axwalk) wrote :

Reviewers: mp+213190_code.launchpad.net,

Message:
Please take a look.

Description:
Add ensure-ha command, EnsureAvailability API

We introduce a new ensure-ha juju subcommand, which
calls the new EnsureAvailability client API. This
is the CLI for ensuring high availability of Juju
state servers.

Note: I have not exposed the ensure-ha command yet,
as there is still work to be done in the agents to
properly support HA state servers.

https://code.launchpad.net/~axwalk/juju-core/cmdapi-ensureavailability/+merge/213190

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/81700043/

Affected files (+301, -0 lines):
   A [revision details]
   A cmd/juju/ensureha.go
   A cmd/juju/ensureha_test.go
   M cmd/juju/main.go
   M state/api/client.go
   M state/api/params/params.go
   M state/apiserver/client/client.go
   M state/apiserver/client/client_test.go

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

LGTM modulo the below, thanks!

https://codereview.appspot.com/81700043/diff/1/cmd/juju/ensureha.go
File cmd/juju/ensureha.go (right):

https://codereview.appspot.com/81700043/diff/1/cmd/juju/ensureha.go#newcode19
cmd/juju/ensureha.go:19: // If specified, use this series, else use the
environment default-series
use this series for newly started instances ?

https://codereview.appspot.com/81700043/diff/1/cmd/juju/ensureha.go#newcode50
cmd/juju/ensureha.go:50: Name: "ensure-ha",
I'm not sure about "ha" in lower case - it looks too much like a word.
I'm thinking that either we make it into a proper word ("availability")
or we capitalise the ha - ensure-HA, thus making it clearer that it's an
acronym.

https://codereview.appspot.com/81700043/diff/1/cmd/juju/ensureha.go#newcode58
cmd/juju/ensureha.go:58: f.IntVar(&c.NumStateServers, "n", 1, "number of
state servers to make available")
Thought for the future - it would be good to be able to run "juju
ensure-HA" without any arguments at all, for when we just want to
maintain the current availability. Perhaps rather than defaulting to 1,
we should default to -1 and complain if it's not specified. That way we
leave that path open.

https://codereview.appspot.com/81700043/diff/1/state/api/client.go
File state/api/client.go (right):

https://codereview.appspot.com/81700043/diff/1/state/api/client.go#newcode680
state/api/client.go:680: } else if err := result.Error; err != nil {
There's no point in having an Error in the result as well as an error
return.

https://codereview.appspot.com/81700043/diff/1/state/api/params/params.go
File state/api/params/params.go (right):

https://codereview.appspot.com/81700043/diff/1/state/api/params/params.go#newcode649
state/api/params/params.go:649: Error *Error
d

https://codereview.appspot.com/81700043/diff/1/state/apiserver/client/client.go
File state/apiserver/client/client.go (right):

https://codereview.appspot.com/81700043/diff/1/state/apiserver/client/client.go#newcode990
state/apiserver/client/client.go:990: if err :=
c.api.state.EnsureAvailability(args.NumStateServers, args.Constraints,
series); err != nil {
err := c.api.state.EnsureAvailability(args.NumStateServers,
args.Constraints, series)
return params.EnsureAvailabilityResult{}, err

https://codereview.appspot.com/81700043/

Revision history for this message
Andrew Wilkins (axwalk) wrote :

Please take a look.

https://codereview.appspot.com/81700043/diff/1/cmd/juju/ensureha.go
File cmd/juju/ensureha.go (right):

https://codereview.appspot.com/81700043/diff/1/cmd/juju/ensureha.go#newcode19
cmd/juju/ensureha.go:19: // If specified, use this series, else use the
environment default-series
On 2014/03/28 07:54:23, rog wrote:
> use this series for newly started instances ?

Done.

https://codereview.appspot.com/81700043/diff/1/cmd/juju/ensureha.go#newcode50
cmd/juju/ensureha.go:50: Name: "ensure-ha",
On 2014/03/28 07:54:23, rog wrote:
> I'm not sure about "ha" in lower case - it looks too much like a word.
I'm
> thinking that either we make it into a proper word ("availability") or
we
> capitalise the ha - ensure-HA, thus making it clearer that it's an
acronym.

Yeah, it didn't look quite right to me, I was following what was in the
card. I've changed it to ensure-availability to be consistent with the
API.

If others disagree, it can be changed easily enough later -- this
command is not yet exposed.

https://codereview.appspot.com/81700043/diff/1/cmd/juju/ensureha.go#newcode58
cmd/juju/ensureha.go:58: f.IntVar(&c.NumStateServers, "n", 1, "number of
state servers to make available")
On 2014/03/28 07:54:23, rog wrote:
> Thought for the future - it would be good to be able to run "juju
ensure-HA"
> without any arguments at all, for when we just want to maintain the
current
> availability. Perhaps rather than defaulting to 1, we should default
to -1 and
> complain if it's not specified. That way we leave that path open.

Good point, will disallow for now.

https://codereview.appspot.com/81700043/diff/1/state/api/client.go
File state/api/client.go (right):

https://codereview.appspot.com/81700043/diff/1/state/api/client.go#newcode680
state/api/client.go:680: } else if err := result.Error; err != nil {
On 2014/03/28 07:54:23, rog wrote:
> There's no point in having an Error in the result as well as an error
return.

Done.

https://codereview.appspot.com/81700043/diff/1/state/api/params/params.go
File state/api/params/params.go (right):

https://codereview.appspot.com/81700043/diff/1/state/api/params/params.go#newcode649
state/api/params/params.go:649: Error *Error
On 2014/03/28 07:54:23, rog wrote:
> d

Done.

https://codereview.appspot.com/81700043/diff/1/state/apiserver/client/client.go
File state/apiserver/client/client.go (right):

https://codereview.appspot.com/81700043/diff/1/state/apiserver/client/client.go#newcode990
state/apiserver/client/client.go:990: if err :=
c.api.state.EnsureAvailability(args.NumStateServers, args.Constraints,
series); err != nil {
On 2014/03/28 07:54:23, rog wrote:
> err := c.api.state.EnsureAvailability(args.NumStateServers,
args.Constraints,
> series)
> return params.EnsureAvailabilityResult{}, err

Done, except the result is no longer necessary so I've dropped it.

https://codereview.appspot.com/81700043/

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

On 2014/03/28 10:03:41, axw wrote:
> Please take a look.

> https://codereview.appspot.com/81700043/diff/1/cmd/juju/ensureha.go
> File cmd/juju/ensureha.go (right):

https://codereview.appspot.com/81700043/diff/1/cmd/juju/ensureha.go#newcode19
> cmd/juju/ensureha.go:19: // If specified, use this series, else use
the
> environment default-series
> On 2014/03/28 07:54:23, rog wrote:
> > use this series for newly started instances ?

> Done.

https://codereview.appspot.com/81700043/diff/1/cmd/juju/ensureha.go#newcode50
> cmd/juju/ensureha.go:50: Name: "ensure-ha",
> On 2014/03/28 07:54:23, rog wrote:
> > I'm not sure about "ha" in lower case - it looks too much like a
word. I'm
> > thinking that either we make it into a proper word ("availability")
or we
> > capitalise the ha - ensure-HA, thus making it clearer that it's an
acronym.

> Yeah, it didn't look quite right to me, I was following what was in
the card.
> I've changed it to ensure-availability to be consistent with the API.

> If others disagree, it can be changed easily enough later -- this
command is not
> yet exposed.

https://codereview.appspot.com/81700043/diff/1/cmd/juju/ensureha.go#newcode58
> cmd/juju/ensureha.go:58: f.IntVar(&c.NumStateServers, "n", 1, "number
of state
> servers to make available")
> On 2014/03/28 07:54:23, rog wrote:
> > Thought for the future - it would be good to be able to run "juju
ensure-HA"
> > without any arguments at all, for when we just want to maintain the
current
> > availability. Perhaps rather than defaulting to 1, we should default
to -1 and
> > complain if it's not specified. That way we leave that path open.

> Good point, will disallow for now.

> https://codereview.appspot.com/81700043/diff/1/state/api/client.go
> File state/api/client.go (right):

https://codereview.appspot.com/81700043/diff/1/state/api/client.go#newcode680
> state/api/client.go:680: } else if err := result.Error; err != nil {
> On 2014/03/28 07:54:23, rog wrote:
> > There's no point in having an Error in the result as well as an
error return.

> Done.

https://codereview.appspot.com/81700043/diff/1/state/api/params/params.go
> File state/api/params/params.go (right):

https://codereview.appspot.com/81700043/diff/1/state/api/params/params.go#newcode649
> state/api/params/params.go:649: Error *Error
> On 2014/03/28 07:54:23, rog wrote:
> > d

> Done.

https://codereview.appspot.com/81700043/diff/1/state/apiserver/client/client.go
> File state/apiserver/client/client.go (right):

https://codereview.appspot.com/81700043/diff/1/state/apiserver/client/client.go#newcode990
> state/apiserver/client/client.go:990: if err :=
> c.api.state.EnsureAvailability(args.NumStateServers, args.Constraints,
series);
> err != nil {
> On 2014/03/28 07:54:23, rog wrote:
> > err := c.api.state.EnsureAvailability(args.NumStateServers,
args.Constraints,
> > series)
> > return params.EnsureAvailabilityResult{}, err

> Done, except the result is no longer necessary so I've dropped it.

LGTM, thanks!

https://codereview.appspot.com/81700043/

Revision history for this message
Go Bot (go-bot) wrote :

Attempt to merge into lp:juju-core failed due to conflicts:

text conflict in state/api/client.go
text conflict in state/api/params/params.go
text conflict in state/apiserver/client/client.go
text conflict in state/apiserver/client/client_test.go

Revision history for this message
Andrew Wilkins (axwalk) wrote :
Revision history for this message
Go Bot (go-bot) wrote :
Download full text (16.3 KiB)

The attempt to merge lp:~axwalk/juju-core/cmdapi-ensureavailability into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.014s
ok launchpad.net/juju-core/agent 1.123s
ok launchpad.net/juju-core/agent/mongo 0.529s
ok launchpad.net/juju-core/agent/tools 0.170s
ok launchpad.net/juju-core/bzr 5.544s
ok launchpad.net/juju-core/cert 2.478s
ok launchpad.net/juju-core/charm 0.448s
? launchpad.net/juju-core/charm/hooks [no test files]
? launchpad.net/juju-core/charm/testing [no test files]
ok launchpad.net/juju-core/cloudinit 0.026s
ok launchpad.net/juju-core/cloudinit/sshinit 0.822s
ok launchpad.net/juju-core/cmd 0.167s
ok launchpad.net/juju-core/cmd/charm-admin 0.766s
? launchpad.net/juju-core/cmd/charmd [no test files]
? launchpad.net/juju-core/cmd/charmload [no test files]
ok launchpad.net/juju-core/cmd/juju 204.103s
ok launchpad.net/juju-core/cmd/jujud 64.185s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 10.634s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/cmd/plugins/local 0.181s
? launchpad.net/juju-core/cmd/plugins/local/juju-local [no test files]
ok launchpad.net/juju-core/constraints 0.022s
ok launchpad.net/juju-core/container 0.075s
ok launchpad.net/juju-core/container/factory 0.050s
ok launchpad.net/juju-core/container/kvm 0.224s
ok launchpad.net/juju-core/container/kvm/mock 0.043s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 4.382s
? launchpad.net/juju-core/container/lxc/mock [no test files]
? launchpad.net/juju-core/container/lxc/testing [no test files]
? launchpad.net/juju-core/container/testing [no test files]
ok launchpad.net/juju-core/downloader 5.221s
ok launchpad.net/juju-core/environs 2.256s
ok launchpad.net/juju-core/environs/bootstrap 10.068s
ok launchpad.net/juju-core/environs/cloudinit 0.448s
ok launchpad.net/juju-core/environs/config 2.850s
ok launchpad.net/juju-core/environs/configstore 0.032s
ok launchpad.net/juju-core/environs/filestorage 0.027s
ok launchpad.net/juju-core/environs/httpstorage 0.643s
ok launchpad.net/juju-core/environs/imagemetadata 0.427s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.046s
ok launchpad.net/juju-core/environs/jujutest 0.175s
ok launchpad.net/juju-core/environs/manual 13.882s
ok launchpad.net/juju-core/environs/simplestreams 0.230s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 0.995s
ok launchpad.net/juju-core/environs/storage 0.928s
ok launchpad.net/juju-core/environs/sync 43.136s
ok launchpad.net/juju-core/environs/testing 0.139s
ok launchpad.net/juju-core/environs/tools 4.837s
? launchpad.net/juju-core/environs/tools/testing [no test files]
ok launchpad.net/juju-core/errors 0.011s
ok launchpad.net/juju-core/instance 0.017s
? launchpad.net/juju-core/instance/testing [no test files]
ok launchpad.net/juju-core/juju 19.193s
ok launchpad.net/juju-core/juju/arch 0....

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'cmd/juju/ensureavailability.go'
--- cmd/juju/ensureavailability.go 1970-01-01 00:00:00 +0000
+++ cmd/juju/ensureavailability.go 2014-03-28 13:32:35 +0000
@@ -0,0 +1,81 @@
1// Copyright 2014 Canonical Ltd.
2// Licensed under the AGPLv3, see LICENCE file for details.
3
4package main
5
6import (
7 "fmt"
8
9 "launchpad.net/gnuflag"
10
11 "launchpad.net/juju-core/cmd"
12 "launchpad.net/juju-core/constraints"
13 "launchpad.net/juju-core/juju"
14)
15
16type EnsureAvailabilityCommand struct {
17 cmd.EnvCommandBase
18 NumStateServers int
19 // If specified, use this series for newly created machines,
20 // else use the environment's default-series
21 Series string
22 // If specified, these constraints will be merged with those
23 // already in the environment when creating new machines.
24 Constraints constraints.Value
25}
26
27const ensureAvailabilityDoc = `
28To ensure availability of deployed services, the Juju infrastructure
29must itself be highly available. Ensure-availability must be called
30to ensure that the specified number of state servers are made available.
31
32An odd number of state servers is required.
33
34Examples:
35 juju ensure-availability -n 3
36 Ensure that 3 state servers are available,
37 with newly created state server machines
38 having the default series and constraints.
39 juju ensure-availability -n 5 --series=trusty
40 Ensure that 5 state servers are available,
41 with newly created state server machines
42 having the "trusty" series.
43 juju ensure-availability -n 7 --constraints mem=8G
44 Ensure that 7 state servers are available,
45 with newly created state server machines
46 having the default series, and at least
47 8GB RAM.
48`
49
50func (c *EnsureAvailabilityCommand) Info() *cmd.Info {
51 return &cmd.Info{
52 Name: "ensure-availability",
53 Purpose: "ensure the availability of Juju state servers",
54 Doc: ensureAvailabilityDoc,
55 }
56}
57
58func (c *EnsureAvailabilityCommand) SetFlags(f *gnuflag.FlagSet) {
59 c.EnvCommandBase.SetFlags(f)
60 f.IntVar(&c.NumStateServers, "n", -1, "number of state servers to make available")
61 f.StringVar(&c.Series, "series", "", "the charm series")
62 f.Var(constraints.ConstraintsValue{&c.Constraints}, "constraints", "additional machine constraints")
63}
64
65func (c *EnsureAvailabilityCommand) Init(args []string) error {
66 if c.NumStateServers%2 != 1 || c.NumStateServers <= 0 {
67 return fmt.Errorf("must specify a number of state servers odd and greater than zero")
68 }
69 return cmd.CheckEmpty(args)
70}
71
72// Run connects to the environment specified on the command line
73// and calls EnsureAvailability.
74func (c *EnsureAvailabilityCommand) Run(_ *cmd.Context) error {
75 client, err := juju.NewAPIClientFromName(c.EnvName)
76 if err != nil {
77 return err
78 }
79 defer client.Close()
80 return client.EnsureAvailability(c.NumStateServers, c.Constraints, c.Series)
81}
082
=== added file 'cmd/juju/ensureavailability_test.go'
--- cmd/juju/ensureavailability_test.go 1970-01-01 00:00:00 +0000
+++ cmd/juju/ensureavailability_test.go 2014-03-28 13:32:35 +0000
@@ -0,0 +1,114 @@
1// Copyright 2013 Canonical Ltd.
2// Licensed under the AGPLv3, see LICENCE file for details.
3
4package main
5
6import (
7 "fmt"
8
9 jc "github.com/juju/testing/checkers"
10 gc "launchpad.net/gocheck"
11
12 "launchpad.net/juju-core/constraints"
13 jujutesting "launchpad.net/juju-core/juju/testing"
14 "launchpad.net/juju-core/state"
15 "launchpad.net/juju-core/testing"
16)
17
18type EnsureAvailabilitySuite struct {
19 jujutesting.RepoSuite
20}
21
22var _ = gc.Suite(&EnsureAvailabilitySuite{})
23
24func runEnsureAvailability(c *gc.C, args ...string) error {
25 _, err := testing.RunCommand(c, &EnsureAvailabilityCommand{}, args)
26 return err
27}
28
29func (s *EnsureAvailabilitySuite) TestEnsureAvailability(c *gc.C) {
30 err := runEnsureAvailability(c, "-n", "1")
31 c.Assert(err, gc.IsNil)
32 m, err := s.State.Machine("0")
33 c.Assert(err, gc.IsNil)
34 c.Assert(m.Life(), gc.Equals, state.Alive)
35 c.Assert(m.Series(), gc.DeepEquals, "precise")
36 mcons, err := m.Constraints()
37 c.Assert(err, gc.IsNil)
38 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty)
39}
40
41func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityWithSeries(c *gc.C) {
42 err := runEnsureAvailability(c, "--series", "series", "-n", "1")
43 c.Assert(err, gc.IsNil)
44 m, err := s.State.Machine("0")
45 c.Assert(err, gc.IsNil)
46 c.Assert(m.Series(), gc.DeepEquals, "series")
47}
48
49func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityWithConstraints(c *gc.C) {
50 err := runEnsureAvailability(c, "--constraints", "mem=4G", "-n", "1")
51 c.Assert(err, gc.IsNil)
52 m, err := s.State.Machine("0")
53 c.Assert(err, gc.IsNil)
54 mcons, err := m.Constraints()
55 c.Assert(err, gc.IsNil)
56 expectedCons := constraints.MustParse("mem=4G")
57 c.Assert(mcons, gc.DeepEquals, expectedCons)
58}
59
60func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityIdempotent(c *gc.C) {
61 for i := 0; i < 2; i++ {
62 err := runEnsureAvailability(c, "-n", "1")
63 c.Assert(err, gc.IsNil)
64 }
65 m, err := s.State.Machine("0")
66 c.Assert(err, gc.IsNil)
67 mcons, err := m.Constraints()
68 c.Assert(err, gc.IsNil)
69 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty)
70
71 // Running ensure-availability with constraints or series
72 // will have no effect unless new machines are
73 // created.
74 err = runEnsureAvailability(c, "-n", "1", "--constraints", "mem=4G")
75 c.Assert(err, gc.IsNil)
76 m, err = s.State.Machine("0")
77 c.Assert(err, gc.IsNil)
78 mcons, err = m.Constraints()
79 c.Assert(err, gc.IsNil)
80 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty)
81}
82
83func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityMultiple(c *gc.C) {
84 err := runEnsureAvailability(c, "-n", "1")
85 c.Assert(err, gc.IsNil)
86 err = runEnsureAvailability(c, "-n", "3", "--constraints", "mem=4G")
87 c.Assert(err, gc.IsNil)
88
89 machines, err := s.State.AllMachines()
90 c.Assert(err, gc.IsNil)
91 c.Assert(machines, gc.HasLen, 3)
92 mcons, err := machines[0].Constraints()
93 c.Assert(err, gc.IsNil)
94 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty)
95 for i := 1; i < 3; i++ {
96 mcons, err := machines[i].Constraints()
97 c.Assert(err, gc.IsNil)
98 expectedCons := constraints.MustParse("mem=4G")
99 c.Assert(mcons, gc.DeepEquals, expectedCons)
100 }
101}
102
103func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityErrors(c *gc.C) {
104 err := runEnsureAvailability(c)
105 c.Assert(err, gc.ErrorMatches, "must specify a number of state servers odd and greater than zero")
106 for _, n := range []int{-1, 0, 2} {
107 err := runEnsureAvailability(c, "-n", fmt.Sprint(n))
108 c.Assert(err, gc.ErrorMatches, "must specify a number of state servers odd and greater than zero")
109 }
110 err = runEnsureAvailability(c, "-n", "3")
111 c.Assert(err, gc.IsNil)
112 err = runEnsureAvailability(c, "-n", "1")
113 c.Assert(err, gc.ErrorMatches, "cannot reduce state server count")
114}
0115
=== modified file 'cmd/juju/main.go'
--- cmd/juju/main.go 2014-03-26 13:40:28 +0000
+++ cmd/juju/main.go 2014-03-28 13:32:35 +0000
@@ -125,6 +125,10 @@
125 // Manage authorised ssh keys.125 // Manage authorised ssh keys.
126 jujucmd.Register(wrap(NewAuthorisedKeysCommand()))126 jujucmd.Register(wrap(NewAuthorisedKeysCommand()))
127127
128 // Manage state server availability.
129 // TODO: enable once the backend is ready for it.
130 //jujucmd.Register(wrap(&EnsureAvailabilityCommand{}))
131
128 // Common commands.132 // Common commands.
129 jujucmd.Register(wrap(&cmd.VersionCommand{}))133 jujucmd.Register(wrap(&cmd.VersionCommand{}))
130134
131135
=== modified file 'state/api/client.go'
--- state/api/client.go 2014-03-28 05:59:48 +0000
+++ state/api/client.go 2014-03-28 13:32:35 +0000
@@ -675,3 +675,13 @@
675 }675 }
676 return result.Servers, nil676 return result.Servers, nil
677}677}
678
679// EnsureAvailability ensures the availability of Juju state servers.
680func (c *Client) EnsureAvailability(numStateServers int, cons constraints.Value, series string) error {
681 args := params.EnsureAvailability{
682 NumStateServers: numStateServers,
683 Constraints: cons,
684 Series: series,
685 }
686 return c.call("EnsureAvailability", args, nil)
687}
678688
=== modified file 'state/api/params/params.go'
--- state/api/params/params.go 2014-03-28 05:59:48 +0000
+++ state/api/params/params.go 2014-03-28 13:32:35 +0000
@@ -639,3 +639,13 @@
639type APIHostPortsResult struct {639type APIHostPortsResult struct {
640 Servers [][]instance.HostPort640 Servers [][]instance.HostPort
641}641}
642
643// EnsureAvailability contains arguments for
644// the EnsureAvailability client API call.
645type EnsureAvailability struct {
646 NumStateServers int
647 Constraints constraints.Value
648 // Series is the series to associate with new state server machines.
649 // If this is empty, then the environment's default series is used.
650 Series string
651}
642652
=== modified file 'state/apiserver/client/client.go'
--- state/apiserver/client/client.go 2014-03-28 05:59:48 +0000
+++ state/apiserver/client/client.go 2014-03-28 13:32:35 +0000
@@ -984,3 +984,16 @@
984 }984 }
985 return result, nil985 return result, nil
986}986}
987
988// EnsureAvailability ensures the availability of Juju state servers.
989func (c *Client) EnsureAvailability(args params.EnsureAvailability) error {
990 series := args.Series
991 if series == "" {
992 cfg, err := c.api.state.EnvironConfig()
993 if err != nil {
994 return err
995 }
996 series = cfg.DefaultSeries()
997 }
998 return c.api.state.EnsureAvailability(args.NumStateServers, args.Constraints, series)
999}
9871000
=== modified file 'state/apiserver/client/client_test.go'
--- state/apiserver/client/client_test.go 2014-03-28 09:57:37 +0000
+++ state/apiserver/client/client_test.go 2014-03-28 13:32:35 +0000
@@ -2083,6 +2083,62 @@
2083 c.Assert(data["transient"], gc.Equals, true)2083 c.Assert(data["transient"], gc.Equals, true)
2084}2084}
20852085
2086func (s *clientSuite) TestClientEnsureAvailabilitySeries(c *gc.C) {
2087 apiParams := []params.EnsureAvailability{{
2088 NumStateServers: 1,
2089 }, {
2090 NumStateServers: 3,
2091 Series: "non-default",
2092 }}
2093 for _, p := range apiParams {
2094 err := s.APIState.Client().EnsureAvailability(p.NumStateServers, p.Constraints, p.Series)
2095 c.Assert(err, gc.IsNil)
2096 }
2097 machines, err := s.State.AllMachines()
2098 c.Assert(err, gc.IsNil)
2099 c.Assert(machines, gc.HasLen, 3)
2100 c.Assert(machines[0].Series(), gc.Equals, "precise")
2101 c.Assert(machines[1].Series(), gc.Equals, "non-default")
2102 c.Assert(machines[2].Series(), gc.Equals, "non-default")
2103}
2104
2105func (s *clientSuite) TestClientEnsureAvailabilityConstraints(c *gc.C) {
2106 apiParams := []params.EnsureAvailability{{
2107 NumStateServers: 1,
2108 }, {
2109 NumStateServers: 3,
2110 Constraints: constraints.MustParse("mem=4G"),
2111 }}
2112 for _, p := range apiParams {
2113 err := s.APIState.Client().EnsureAvailability(p.NumStateServers, p.Constraints, p.Series)
2114 c.Assert(err, gc.IsNil)
2115 }
2116 machines, err := s.State.AllMachines()
2117 c.Assert(err, gc.IsNil)
2118 c.Assert(machines, gc.HasLen, 3)
2119 expectedCons := []constraints.Value{
2120 constraints.Value{},
2121 constraints.MustParse("mem=4G"),
2122 constraints.MustParse("mem=4G"),
2123 }
2124 for i, m := range machines {
2125 cons, err := m.Constraints()
2126 c.Assert(err, gc.IsNil)
2127 c.Check(cons, gc.DeepEquals, expectedCons[i])
2128 }
2129}
2130
2131func (s *clientSuite) TestClientEnsureAvailabilityErrors(c *gc.C) {
2132 var emptyCons constraints.Value
2133 defaultSeries := ""
2134 err := s.APIState.Client().EnsureAvailability(0, emptyCons, defaultSeries)
2135 c.Assert(err, gc.ErrorMatches, "number of state servers must be odd and greater than zero")
2136 err = s.APIState.Client().EnsureAvailability(3, emptyCons, defaultSeries)
2137 c.Assert(err, gc.IsNil)
2138 err = s.APIState.Client().EnsureAvailability(1, emptyCons, defaultSeries)
2139 c.Assert(err, gc.ErrorMatches, "cannot reduce state server count")
2140}
2141
2086func (s *clientSuite) TestAPIHostPorts(c *gc.C) {2142func (s *clientSuite) TestAPIHostPorts(c *gc.C) {
2087 apiHostPorts, err := s.APIState.Client().APIHostPorts()2143 apiHostPorts, err := s.APIState.Client().APIHostPorts()
2088 c.Assert(err, gc.IsNil)2144 c.Assert(err, gc.IsNil)

Subscribers

People subscribed via source and target branches

to status/vote changes: