Merge lp:~axwalk/juju-core/agent-watch-apihostports 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: 2539
Proposed branch: lp:~axwalk/juju-core/agent-watch-apihostports
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 327 lines (+230/-0)
7 files modified
cmd/jujud/agent.go (+8/-0)
cmd/jujud/machine.go (+4/-0)
cmd/jujud/machine_test.go (+26/-0)
cmd/jujud/unit.go (+4/-0)
cmd/jujud/unit_test.go (+27/-0)
worker/apiaddressupdater/apiaddressupdater.go (+64/-0)
worker/apiaddressupdater/apiaddressupdater_test.go (+97/-0)
To merge this branch: bzr merge lp:~axwalk/juju-core/agent-watch-apihostports
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+213778@code.launchpad.net

Commit message

Introduce worker/apiaddressupdater

This proposal introduces a new worker that
watches changes to APIHostPorts, and then
updates agent config. The machine and unit
agents have both been updated to start this
worker.

https://codereview.appspot.com/83500043/

Description of the change

Introduce worker/apiaddressupdater

This proposal introduces a new worker that
watches changes to APIHostPorts, and then
updates agent config. The machine and unit
agents have both been updated to start this
worker.

https://codereview.appspot.com/83500043/

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

Reviewers: mp+213778_code.launchpad.net,

Message:
Please take a look.

Description:
Introduce worker/apiaddressupdater

This proposal introduces a new worker that
watches changes to APIHostPorts, and then
updates agent config. The machine and unit
agents have both been updated to start this
worker.

https://code.launchpad.net/~axwalk/juju-core/agent-watch-apihostports/+merge/213778

(do not edit description out of merge proposal)

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

Affected files (+242, -0 lines):
   A [revision details]
   M cmd/jujud/agent.go
   M cmd/jujud/machine.go
   M cmd/jujud/machine_test.go
   M cmd/jujud/unit.go
   M cmd/jujud/unit_test.go
   A worker/apiaddressupdater/apiaddressupdater.go
   A worker/apiaddressupdater/apiaddressupdater_test.go

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

LGTM with a few queries below, thanks!

https://codereview.appspot.com/83500043/diff/1/cmd/jujud/machine_test.go
File cmd/jujud/machine_test.go (right):

https://codereview.appspot.com/83500043/diff/1/cmd/jujud/machine_test.go#newcode851
cmd/jujud/machine_test.go:851: s.State.StartSync()
shouldn't this be BackingState? (i think the watcher is actually in the
API, right?)

https://codereview.appspot.com/83500043/diff/1/cmd/jujud/machine_test.go#newcode852
cmd/jujud/machine_test.go:852: timeout :=
time.After(coretesting.LongWait)
perhaps this might be better phrased as an attempt loop?

https://codereview.appspot.com/83500043/diff/1/cmd/jujud/unit_test.go
File cmd/jujud/unit_test.go (right):

https://codereview.appspot.com/83500043/diff/1/cmd/jujud/unit_test.go#newcode270
cmd/jujud/unit_test.go:270: s.State.StartSync()
shouldn't this be BackingState?

https://codereview.appspot.com/83500043/

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

Please take a look.

https://codereview.appspot.com/83500043/diff/1/cmd/jujud/machine_test.go
File cmd/jujud/machine_test.go (right):

https://codereview.appspot.com/83500043/diff/1/cmd/jujud/machine_test.go#newcode851
cmd/jujud/machine_test.go:851: s.State.StartSync()
On 2014/04/02 08:51:08, rog wrote:
> shouldn't this be BackingState? (i think the watcher is actually in
the API,
> right?)

Done.

https://codereview.appspot.com/83500043/diff/1/cmd/jujud/machine_test.go#newcode852
cmd/jujud/machine_test.go:852: timeout :=
time.After(coretesting.LongWait)
On 2014/04/02 08:51:08, rog wrote:
> perhaps this might be better phrased as an attempt loop?

Done, much nicer.

https://codereview.appspot.com/83500043/diff/1/cmd/jujud/unit_test.go
File cmd/jujud/unit_test.go (right):

https://codereview.appspot.com/83500043/diff/1/cmd/jujud/unit_test.go#newcode270
cmd/jujud/unit_test.go:270: s.State.StartSync()
On 2014/04/02 08:51:08, rog wrote:
> shouldn't this be BackingState?

Done.

https://codereview.appspot.com/83500043/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'cmd/jujud/agent.go'
--- cmd/jujud/agent.go 2014-03-28 13:24:36 +0000
+++ cmd/jujud/agent.go 2014-04-02 09:44:43 +0000
@@ -13,6 +13,7 @@
1313
14 "launchpad.net/juju-core/agent"14 "launchpad.net/juju-core/agent"
15 "launchpad.net/juju-core/cmd"15 "launchpad.net/juju-core/cmd"
16 "launchpad.net/juju-core/instance"
16 "launchpad.net/juju-core/log"17 "launchpad.net/juju-core/log"
17 "launchpad.net/juju-core/state"18 "launchpad.net/juju-core/state"
18 "launchpad.net/juju-core/state/api"19 "launchpad.net/juju-core/state/api"
@@ -82,6 +83,13 @@
82 return ch._config.Clone()83 return ch._config.Clone()
83}84}
8485
86// SetAPIHostPorts satisfies worker/apiaddressupdater/APIAddressSetter.
87func (a *AgentConf) SetAPIHostPorts(servers [][]instance.HostPort) error {
88 return a.ChangeConfig(func(c agent.ConfigSetter) {
89 c.SetAPIHostPorts(servers)
90 })
91}
92
85func importance(err error) int {93func importance(err error) int {
86 switch {94 switch {
87 case err == nil:95 case err == nil:
8896
=== modified file 'cmd/jujud/machine.go'
--- cmd/jujud/machine.go 2014-03-28 10:11:59 +0000
+++ cmd/jujud/machine.go 2014-04-02 09:44:43 +0000
@@ -33,6 +33,7 @@
33 "launchpad.net/juju-core/utils"33 "launchpad.net/juju-core/utils"
34 "launchpad.net/juju-core/version"34 "launchpad.net/juju-core/version"
35 "launchpad.net/juju-core/worker"35 "launchpad.net/juju-core/worker"
36 "launchpad.net/juju-core/worker/apiaddressupdater"
36 "launchpad.net/juju-core/worker/authenticationworker"37 "launchpad.net/juju-core/worker/authenticationworker"
37 "launchpad.net/juju-core/worker/charmrevisionworker"38 "launchpad.net/juju-core/worker/charmrevisionworker"
38 "launchpad.net/juju-core/worker/cleaner"39 "launchpad.net/juju-core/worker/cleaner"
@@ -212,6 +213,9 @@
212 a.startWorkerAfterUpgrade(runner, "machiner", func() (worker.Worker, error) {213 a.startWorkerAfterUpgrade(runner, "machiner", func() (worker.Worker, error) {
213 return machiner.NewMachiner(st.Machiner(), agentConfig), nil214 return machiner.NewMachiner(st.Machiner(), agentConfig), nil
214 })215 })
216 a.startWorkerAfterUpgrade(runner, "apiaddressupdater", func() (worker.Worker, error) {
217 return apiaddressupdater.NewAPIAddressUpdater(st.Machiner(), a), nil
218 })
215 a.startWorkerAfterUpgrade(runner, "logger", func() (worker.Worker, error) {219 a.startWorkerAfterUpgrade(runner, "logger", func() (worker.Worker, error) {
216 return workerlogger.NewLogger(st.Logger(), agentConfig), nil220 return workerlogger.NewLogger(st.Logger(), agentConfig), nil
217 })221 })
218222
=== modified file 'cmd/jujud/machine_test.go'
--- cmd/jujud/machine_test.go 2014-04-01 00:12:08 +0000
+++ cmd/jujud/machine_test.go 2014-04-02 09:44:43 +0000
@@ -833,6 +833,32 @@
833 })833 })
834}834}
835835
836func (s *MachineSuite) TestMachineAgentRunsAPIAddressUpdaterWorker(c *gc.C) {
837 // Start the machine agent.
838 m, _, _ := s.primeAgent(c, version.Current, state.JobHostUnits)
839 a := s.newAgent(c, m)
840 go func() { c.Check(a.Run(nil), gc.IsNil) }()
841 defer func() { c.Check(a.Stop(), gc.IsNil) }()
842
843 // Update the API addresses.
844 updatedServers := [][]instance.HostPort{instance.AddressesWithPort(
845 instance.NewAddresses("localhost"), 1234,
846 )}
847 err := s.BackingState.SetAPIHostPorts(updatedServers)
848 c.Assert(err, gc.IsNil)
849
850 // Wait for config to be updated.
851 s.BackingState.StartSync()
852 for attempt := coretesting.LongAttempt.Start(); attempt.Next(); {
853 addrs, err := a.CurrentConfig().APIAddresses()
854 c.Assert(err, gc.IsNil)
855 if reflect.DeepEqual(addrs, []string{"localhost:1234"}) {
856 return
857 }
858 }
859 c.Fatalf("timeout while waiting for agent config to change")
860}
861
836// MachineWithCharmsSuite provides infrastructure for tests which need to862// MachineWithCharmsSuite provides infrastructure for tests which need to
837// work with charms.863// work with charms.
838type MachineWithCharmsSuite struct {864type MachineWithCharmsSuite struct {
839865
=== modified file 'cmd/jujud/unit.go'
--- cmd/jujud/unit.go 2014-03-27 18:25:41 +0000
+++ cmd/jujud/unit.go 2014-04-02 09:44:43 +0000
@@ -15,6 +15,7 @@
15 "launchpad.net/juju-core/names"15 "launchpad.net/juju-core/names"
16 "launchpad.net/juju-core/version"16 "launchpad.net/juju-core/version"
17 "launchpad.net/juju-core/worker"17 "launchpad.net/juju-core/worker"
18 "launchpad.net/juju-core/worker/apiaddressupdater"
18 workerlogger "launchpad.net/juju-core/worker/logger"19 workerlogger "launchpad.net/juju-core/worker/logger"
19 "launchpad.net/juju-core/worker/rsyslog"20 "launchpad.net/juju-core/worker/rsyslog"
20 "launchpad.net/juju-core/worker/uniter"21 "launchpad.net/juju-core/worker/uniter"
@@ -96,6 +97,9 @@
96 runner.StartWorker("uniter", func() (worker.Worker, error) {97 runner.StartWorker("uniter", func() (worker.Worker, error) {
97 return uniter.NewUniter(st.Uniter(), entity.Tag(), dataDir), nil98 return uniter.NewUniter(st.Uniter(), entity.Tag(), dataDir), nil
98 })99 })
100 runner.StartWorker("apiaddressupdater", func() (worker.Worker, error) {
101 return apiaddressupdater.NewAPIAddressUpdater(st.Uniter(), a), nil
102 })
99 runner.StartWorker("rsyslog", func() (worker.Worker, error) {103 runner.StartWorker("rsyslog", func() (worker.Worker, error) {
100 return newRsyslogConfigWorker(st.Rsyslog(), agentConfig, rsyslog.RsyslogModeForwarding)104 return newRsyslogConfigWorker(st.Rsyslog(), agentConfig, rsyslog.RsyslogModeForwarding)
101 })105 })
102106
=== modified file 'cmd/jujud/unit_test.go'
--- cmd/jujud/unit_test.go 2014-03-28 08:28:04 +0000
+++ cmd/jujud/unit_test.go 2014-04-02 09:44:43 +0000
@@ -4,6 +4,7 @@
4package main4package main
55
6import (6import (
7 "reflect"
7 "time"8 "time"
89
9 gc "launchpad.net/gocheck"10 gc "launchpad.net/gocheck"
@@ -11,6 +12,7 @@
11 "launchpad.net/juju-core/agent"12 "launchpad.net/juju-core/agent"
12 "launchpad.net/juju-core/cmd"13 "launchpad.net/juju-core/cmd"
13 envtesting "launchpad.net/juju-core/environs/testing"14 envtesting "launchpad.net/juju-core/environs/testing"
15 "launchpad.net/juju-core/instance"
14 jujutesting "launchpad.net/juju-core/juju/testing"16 jujutesting "launchpad.net/juju-core/juju/testing"
15 "launchpad.net/juju-core/names"17 "launchpad.net/juju-core/names"
16 "launchpad.net/juju-core/state"18 "launchpad.net/juju-core/state"
@@ -250,3 +252,28 @@
250 c.Assert(mode, gc.Equals, rsyslog.RsyslogModeForwarding)252 c.Assert(mode, gc.Equals, rsyslog.RsyslogModeForwarding)
251 }253 }
252}254}
255
256func (s *UnitSuite) TestUnitAgentRunsAPIAddressUpdaterWorker(c *gc.C) {
257 _, unit, _, _ := s.primeAgent(c)
258 a := s.newAgent(c, unit)
259 go func() { c.Check(a.Run(nil), gc.IsNil) }()
260 defer func() { c.Check(a.Stop(), gc.IsNil) }()
261
262 // Update the API addresses.
263 updatedServers := [][]instance.HostPort{instance.AddressesWithPort(
264 instance.NewAddresses("localhost"), 1234,
265 )}
266 err := s.BackingState.SetAPIHostPorts(updatedServers)
267 c.Assert(err, gc.IsNil)
268
269 // Wait for config to be updated.
270 s.BackingState.StartSync()
271 for attempt := coretesting.LongAttempt.Start(); attempt.Next(); {
272 addrs, err := a.CurrentConfig().APIAddresses()
273 c.Assert(err, gc.IsNil)
274 if reflect.DeepEqual(addrs, []string{"localhost:1234"}) {
275 return
276 }
277 }
278 c.Fatalf("timeout while waiting for agent config to change")
279}
253280
=== added directory 'worker/apiaddressupdater'
=== added file 'worker/apiaddressupdater/apiaddressupdater.go'
--- worker/apiaddressupdater/apiaddressupdater.go 1970-01-01 00:00:00 +0000
+++ worker/apiaddressupdater/apiaddressupdater.go 2014-04-02 09:44:43 +0000
@@ -0,0 +1,64 @@
1// Copyright 2014 Canonical Ltd.
2// Licensed under the AGPLv3, see LICENCE file for details.
3
4package apiaddressupdater
5
6import (
7 "fmt"
8
9 "github.com/juju/loggo"
10
11 "launchpad.net/juju-core/instance"
12 "launchpad.net/juju-core/state/api/watcher"
13 "launchpad.net/juju-core/worker"
14)
15
16var logger = loggo.GetLogger("juju.worker.apiaddressupdater")
17
18// APIAddressUpdater is responsible for cleaning up the state.
19type APIAddressUpdater struct {
20 addresser APIAddresser
21 setter APIAddressSetter
22}
23
24// APIAddresser is an interface that is provided to NewAPIAddressUpdater
25// which can be used to watch for API address changes.
26type APIAddresser interface {
27 APIHostPorts() ([][]instance.HostPort, error)
28 WatchAPIHostPorts() (watcher.NotifyWatcher, error)
29}
30
31// APIAddressSetter is an interface that is provided to NewAPIAddressUpdater
32// whose SetAPIHostPorts method will be invoked whenever address changes occur.
33type APIAddressSetter interface {
34 SetAPIHostPorts(servers [][]instance.HostPort) error
35}
36
37// NewAPIAddressUpdater returns a worker.Worker that runs state.Cleanup()
38// if the CleanupWatcher signals documents marked for deletion.
39func NewAPIAddressUpdater(addresser APIAddresser, setter APIAddressSetter) worker.Worker {
40 return worker.NewNotifyWorker(&APIAddressUpdater{
41 addresser: addresser,
42 setter: setter,
43 })
44}
45
46func (c *APIAddressUpdater) SetUp() (watcher.NotifyWatcher, error) {
47 return c.addresser.WatchAPIHostPorts()
48}
49
50func (c *APIAddressUpdater) Handle() error {
51 addresses, err := c.addresser.APIHostPorts()
52 if err != nil {
53 return fmt.Errorf("error getting addresses: %v", err)
54 }
55 if err := c.setter.SetAPIHostPorts(addresses); err != nil {
56 return fmt.Errorf("error setting addresses: %v", err)
57 }
58 logger.Infof("API addresses updated to %q", addresses)
59 return nil
60}
61
62func (c *APIAddressUpdater) TearDown() error {
63 return nil
64}
065
=== added file 'worker/apiaddressupdater/apiaddressupdater_test.go'
--- worker/apiaddressupdater/apiaddressupdater_test.go 1970-01-01 00:00:00 +0000
+++ worker/apiaddressupdater/apiaddressupdater_test.go 2014-04-02 09:44:43 +0000
@@ -0,0 +1,97 @@
1// Copyright 2014 Canonical Ltd.
2// Licensed under the AGPLv3, see LICENCE file for details.
3
4package apiaddressupdater_test
5
6import (
7 stdtesting "testing"
8 "time"
9
10 gc "launchpad.net/gocheck"
11
12 "launchpad.net/juju-core/instance"
13 jujutesting "launchpad.net/juju-core/juju/testing"
14 "launchpad.net/juju-core/state"
15 coretesting "launchpad.net/juju-core/testing"
16 "launchpad.net/juju-core/worker/apiaddressupdater"
17)
18
19func TestPackage(t *stdtesting.T) {
20 coretesting.MgoTestPackage(t)
21}
22
23type APIAddressUpdaterSuite struct {
24 jujutesting.JujuConnSuite
25}
26
27var _ = gc.Suite(&APIAddressUpdaterSuite{})
28
29type apiAddressSetter struct {
30 servers chan [][]instance.HostPort
31 err error
32}
33
34func (s *apiAddressSetter) SetAPIHostPorts(servers [][]instance.HostPort) error {
35 s.servers <- servers
36 return s.err
37}
38
39func (s *APIAddressUpdaterSuite) TestStartStop(c *gc.C) {
40 st, _ := s.OpenAPIAsNewMachine(c, state.JobHostUnits)
41 worker := apiaddressupdater.NewAPIAddressUpdater(st.Machiner(), &apiAddressSetter{})
42 worker.Kill()
43 c.Assert(worker.Wait(), gc.IsNil)
44}
45
46func (s *APIAddressUpdaterSuite) TestAddressInitialUpdate(c *gc.C) {
47 updatedServers := [][]instance.HostPort{instance.AddressesWithPort(
48 instance.NewAddresses("localhost", "127.0.0.1"),
49 1234,
50 )}
51 err := s.State.SetAPIHostPorts(updatedServers)
52 c.Assert(err, gc.IsNil)
53
54 setter := &apiAddressSetter{servers: make(chan [][]instance.HostPort, 1)}
55 st, _ := s.OpenAPIAsNewMachine(c, state.JobHostUnits)
56 worker := apiaddressupdater.NewAPIAddressUpdater(st.Machiner(), setter)
57 defer func() { c.Assert(worker.Wait(), gc.IsNil) }()
58 defer worker.Kill()
59
60 // SetAPIHostPorts should be called with the initial value.
61 select {
62 case <-time.After(coretesting.LongWait):
63 c.Fatalf("timed out waiting for SetAPIHostPorts to be called")
64 case servers := <-setter.servers:
65 c.Assert(servers, gc.DeepEquals, updatedServers)
66 }
67}
68
69func (s *APIAddressUpdaterSuite) TestAddressChange(c *gc.C) {
70 setter := &apiAddressSetter{servers: make(chan [][]instance.HostPort, 1)}
71 st, _ := s.OpenAPIAsNewMachine(c, state.JobHostUnits)
72 worker := apiaddressupdater.NewAPIAddressUpdater(st.Machiner(), setter)
73 defer func() { c.Assert(worker.Wait(), gc.IsNil) }()
74 defer worker.Kill()
75
76 updatedServers := [][]instance.HostPort{instance.AddressesWithPort(
77 instance.NewAddresses("localhost", "127.0.0.1"),
78 1234,
79 )}
80 err := s.State.SetAPIHostPorts(updatedServers)
81 c.Assert(err, gc.IsNil)
82
83 // SetAPIHostPorts should be called with the initial value (empty),
84 // and then the updated value.
85 n := 0
86 select {
87 case <-time.After(coretesting.LongWait):
88 c.Fatalf("timed out waiting for SetAPIHostPorts to be called")
89 case servers := <-setter.servers:
90 if n == 0 {
91 c.Assert(servers, gc.HasLen, 0)
92 } else {
93 c.Assert(servers, gc.DeepEquals, updatedServers)
94 }
95 n++
96 }
97}

Subscribers

People subscribed via source and target branches

to status/vote changes: