Merge lp:~wallyworld/juju-core/1302205-backport-1.18 into lp:juju-core/1.18

Proposed by Ian Booth
Status: Merged
Approved by: Ian Booth
Approved revision: no longer in the source branch.
Merged at revision: 2278
Proposed branch: lp:~wallyworld/juju-core/1302205-backport-1.18
Merge into: lp:juju-core/1.18
Diff against target: 315 lines (+119/-19)
5 files modified
provider/manual/config.go (+2/-2)
provider/manual/config_test.go (+16/-3)
worker/instancepoller/machine_test.go (+29/-9)
worker/instancepoller/updater.go (+20/-5)
worker/instancepoller/updater_test.go (+52/-0)
To merge this branch: bzr merge lp:~wallyworld/juju-core/1302205-backport-1.18
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+217646@code.launchpad.net

Commit message

Cherry pick trunk 2588,2589 to backport fix for bug 1302205 "
manual provisioned systems stuck in pending on arm64"

Description of the change

Cherry pick trunk 2588,2589 to backport fix for bug 1302205 "
manual provisioned systems stuck in pending on arm64"

To post a comment you must log in.
Revision history for this message
Go Bot (go-bot) wrote :
Download full text (564.4 KiB)

The attempt to merge lp:~wallyworld/juju-core/1302205-backport-1.18 into lp:juju-core/1.18 failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.012s
ok launchpad.net/juju-core/agent 1.085s
ok launchpad.net/juju-core/agent/mongo 0.562s
ok launchpad.net/juju-core/agent/tools 0.223s
ok launchpad.net/juju-core/bzr 5.046s
ok launchpad.net/juju-core/cert 2.759s
ok launchpad.net/juju-core/charm 0.445s
? 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.030s
ok launchpad.net/juju-core/cloudinit/sshinit 0.765s
ok launchpad.net/juju-core/cmd 0.161s
ok launchpad.net/juju-core/cmd/charm-admin 0.275s
? 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 212.049s
ok launchpad.net/juju-core/cmd/jujud 63.760s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 9.612s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/cmd/plugins/local 0.138s
? launchpad.net/juju-core/cmd/plugins/local/juju-local [no test files]
ok launchpad.net/juju-core/constraints 0.020s
ok launchpad.net/juju-core/container 0.038s
ok launchpad.net/juju-core/container/factory 0.039s
ok launchpad.net/juju-core/container/kvm 0.210s
ok launchpad.net/juju-core/container/kvm/mock 0.044s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 4.303s
? 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.223s
ok launchpad.net/juju-core/environs 2.295s
ok launchpad.net/juju-core/environs/bootstrap 10.368s
ok launchpad.net/juju-core/environs/cloudinit 0.529s
ok launchpad.net/juju-core/environs/config 1.636s
ok launchpad.net/juju-core/environs/configstore 0.028s
ok launchpad.net/juju-core/environs/filestorage 0.026s
ok launchpad.net/juju-core/environs/httpstorage 0.676s
ok launchpad.net/juju-core/environs/imagemetadata 0.463s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.045s
ok launchpad.net/juju-core/environs/jujutest 0.150s
ok launchpad.net/juju-core/environs/manual 11.457s
ok launchpad.net/juju-core/environs/simplestreams 0.322s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 0.829s
ok launchpad.net/juju-core/environs/storage 0.847s
ok launchpad.net/juju-core/environs/sync 45.998s
ok launchpad.net/juju-core/environs/testing 0.145s
ok launchpad.net/juju-core/environs/tools 4.689s
? launchpad.net/juju-core/environs/tools/testing [no test files]
ok launchpad.net/juju-core/errors 0.012s
ok launchpad.net/juju-core/instance 0.025s
? launchpad.net/juju-core/instance/testing [no test files]
ok launchpad.net/juju-core/juju 21.041s
ok launchpad.net/juju-core/juju/arc...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'provider/manual/config.go'
2--- provider/manual/config.go 2014-02-10 11:35:13 +0000
3+++ provider/manual/config.go 2014-04-29 17:12:19 +0000
4@@ -17,7 +17,7 @@
5 "bootstrap-host": schema.String(),
6 "bootstrap-user": schema.String(),
7 "storage-listen-ip": schema.String(),
8- "storage-port": schema.Int(),
9+ "storage-port": schema.ForceInt(),
10 "storage-auth-key": schema.String(),
11 "use-sshstorage": schema.Bool(),
12 }
13@@ -59,7 +59,7 @@
14 }
15
16 func (c *environConfig) storagePort() int {
17- return int(c.attrs["storage-port"].(int64))
18+ return c.attrs["storage-port"].(int)
19 }
20
21 func (c *environConfig) storageAuthKey() string {
22
23=== modified file 'provider/manual/config_test.go'
24--- provider/manual/config_test.go 2014-03-13 07:54:56 +0000
25+++ provider/manual/config_test.go 2014-04-29 17:12:19 +0000
26@@ -72,7 +72,7 @@
27 c.Assert(unknownAttrs["bootstrap-host"], gc.Equals, "hostname")
28 c.Assert(unknownAttrs["bootstrap-user"], gc.Equals, "")
29 c.Assert(unknownAttrs["storage-listen-ip"], gc.Equals, "")
30- c.Assert(unknownAttrs["storage-port"], gc.Equals, int64(8040))
31+ c.Assert(unknownAttrs["storage-port"], gc.Equals, int(8040))
32 }
33
34 func (s *configSuite) TestConfigMutability(c *gc.C) {
35@@ -89,7 +89,7 @@
36 "bootstrap-host": "new-hostname",
37 "bootstrap-user": "new-username",
38 "storage-listen-ip": "10.0.0.123",
39- "storage-port": int64(1234),
40+ "storage-port": 1234,
41 } {
42 testConfig = MinimalConfig(c)
43 testConfig, err = testConfig.Apply(map[string]interface{}{k: v})
44@@ -119,7 +119,7 @@
45 c.Assert(testConfig.storageAddr(), gc.Equals, "hostname:8040")
46 c.Assert(testConfig.storageListenAddr(), gc.Equals, ":8040")
47 values["storage-listen-ip"] = "10.0.0.123"
48- values["storage-port"] = int64(1234)
49+ values["storage-port"] = 1234
50 testConfig = getEnvironConfig(c, values)
51 c.Assert(testConfig.storageAddr(), gc.Equals, "hostname:1234")
52 c.Assert(testConfig.storageListenAddr(), gc.Equals, "10.0.0.123:1234")
53@@ -137,3 +137,16 @@
54 c.Assert(err, gc.IsNil)
55 c.Assert(envConfig.useSSHStorage(), jc.IsFalse)
56 }
57+
58+func (s *configSuite) TestValidateConfigWithFloatPort(c *gc.C) {
59+ // When the config values get serialized through JSON, the integers
60+ // get coerced to float64 values. The parsing needs to handle this.
61+ values := MinimalConfigValues()
62+ values["storage-port"] = float64(8040)
63+ cfg, err := config.New(config.UseDefaults, values)
64+ c.Assert(err, gc.IsNil)
65+ valid, err := ProviderInstance.Validate(cfg, nil)
66+ c.Assert(err, gc.IsNil)
67+ unknownAttrs := valid.UnknownAttrs()
68+ c.Assert(unknownAttrs["storage-port"], gc.Equals, int(8040))
69+}
70
71=== modified file 'worker/instancepoller/machine_test.go'
72--- worker/instancepoller/machine_test.go 2014-03-19 03:48:12 +0000
73+++ worker/instancepoller/machine_test.go 2014-04-29 17:12:19 +0000
74@@ -8,6 +8,7 @@
75 stderrors "errors"
76 "fmt"
77 "math"
78+ "strings"
79 "sync"
80 "sync/atomic"
81 "time"
82@@ -61,24 +62,31 @@
83 func (s *machineSuite) TestShortPollIntervalWhenNoAddress(c *gc.C) {
84 s.PatchValue(&ShortPoll, 1*time.Millisecond)
85 s.PatchValue(&LongPoll, coretesting.LongWait)
86- count := countPolls(c, nil, "running", params.StatusStarted)
87+ count := countPolls(c, nil, "i1234", "running", params.StatusStarted)
88 c.Assert(count, jc.GreaterThan, 2)
89 }
90
91 func (s *machineSuite) TestShortPollIntervalWhenNoStatus(c *gc.C) {
92 s.PatchValue(&ShortPoll, 1*time.Millisecond)
93 s.PatchValue(&LongPoll, coretesting.LongWait)
94- count := countPolls(c, testAddrs, "", params.StatusStarted)
95+ count := countPolls(c, testAddrs, "i1234", "", params.StatusStarted)
96 c.Assert(count, jc.GreaterThan, 2)
97 }
98
99 func (s *machineSuite) TestShortPollIntervalWhenNotStarted(c *gc.C) {
100 s.PatchValue(&ShortPoll, 1*time.Millisecond)
101 s.PatchValue(&LongPoll, coretesting.LongWait)
102- count := countPolls(c, testAddrs, "pending", params.StatusPending)
103+ count := countPolls(c, testAddrs, "i1234", "pending", params.StatusPending)
104 c.Assert(count, jc.GreaterThan, 2)
105 }
106
107+func (s *machineSuite) TestShortPollIntervalWhenNotProvisioned(c *gc.C) {
108+ s.PatchValue(&ShortPoll, 1*time.Millisecond)
109+ s.PatchValue(&LongPoll, coretesting.LongWait)
110+ count := countPolls(c, testAddrs, "", "pending", params.StatusPending)
111+ c.Assert(count, gc.Equals, 0)
112+}
113+
114 func (s *machineSuite) TestShortPollIntervalExponent(c *gc.C) {
115 s.PatchValue(&ShortPoll, 1*time.Microsecond)
116 s.PatchValue(&LongPoll, coretesting.LongWait)
117@@ -89,7 +97,7 @@
118 // ShortPollBackoff of ShortWait/ShortPoll, given that sleep will
119 // sleep for at least the requested interval.
120 maxCount := int(math.Log(float64(coretesting.ShortWait)/float64(ShortPoll))/math.Log(ShortPollBackoff) + 1)
121- count := countPolls(c, nil, "", params.StatusStarted)
122+ count := countPolls(c, nil, "i1234", "", params.StatusStarted)
123 c.Assert(count, jc.GreaterThan, 2)
124 c.Assert(count, jc.LessThan, maxCount)
125 c.Logf("actual count: %v; max %v", count, maxCount)
126@@ -98,7 +106,7 @@
127 func (s *machineSuite) TestLongPollIntervalWhenHasAllInstanceInfo(c *gc.C) {
128 s.PatchValue(&ShortPoll, coretesting.LongWait)
129 s.PatchValue(&LongPoll, 1*time.Millisecond)
130- count := countPolls(c, testAddrs, "running", params.StatusStarted)
131+ count := countPolls(c, testAddrs, "i1234", "running", params.StatusStarted)
132 c.Assert(count, jc.GreaterThan, 2)
133 }
134
135@@ -106,10 +114,10 @@
136 // addresses and status to be returned from getInstanceInfo,
137 // waits for coretesting.ShortWait, and returns the
138 // number of times the instance is polled.
139-func countPolls(c *gc.C, addrs []instance.Address, instStatus string, machineStatus params.Status) int {
140+func countPolls(c *gc.C, addrs []instance.Address, instId, instStatus string, machineStatus params.Status) int {
141 count := int32(0)
142 getInstanceInfo := func(id instance.Id) (instanceInfo, error) {
143- c.Check(id, gc.Equals, instance.Id("i1234"))
144+ c.Check(string(id), gc.Equals, instId)
145 atomic.AddInt32(&count, 1)
146 if addrs == nil {
147 return instanceInfo{}, fmt.Errorf("no instance addresses available")
148@@ -122,7 +130,7 @@
149 }
150 m := &testMachine{
151 id: "99",
152- instanceId: "i1234",
153+ instanceId: instance.Id(instId),
154 refresh: func() error { return nil },
155 addresses: addrs,
156 life: state.Alive,
157@@ -342,11 +350,23 @@
158 }
159
160 func (m *testMachine) InstanceId() (instance.Id, error) {
161+ if m.instanceId == "" {
162+ return "", state.NotProvisionedError(m.Id())
163+ }
164 return m.instanceId, m.instanceIdErr
165 }
166
167+// This is stubbed out for testing.
168+var MachineStatus = func(m *testMachine) (status params.Status, info string, data params.StatusData, err error) {
169+ return m.status, "", nil, nil
170+}
171+
172 func (m *testMachine) Status() (status params.Status, info string, data params.StatusData, err error) {
173- return m.status, "", nil, nil
174+ return MachineStatus(m)
175+}
176+
177+func (m *testMachine) IsManual() (bool, error) {
178+ return strings.HasPrefix(string(m.instanceId), "manual:"), nil
179 }
180
181 func (m *testMachine) InstanceStatus() (string, error) {
182
183=== modified file 'worker/instancepoller/updater.go'
184--- worker/instancepoller/updater.go 2014-03-05 19:41:34 +0000
185+++ worker/instancepoller/updater.go 2014-04-29 17:12:19 +0000
186@@ -42,6 +42,7 @@
187 Refresh() error
188 Life() state.Life
189 Status() (status params.Status, info string, data params.StatusData, err error)
190+ IsManual() (bool, error)
191 }
192
193 type instanceInfo struct {
194@@ -132,6 +133,14 @@
195 if err != nil {
196 return err
197 }
198+ // We don't poll manual machines.
199+ isManual, err := m.IsManual()
200+ if err != nil {
201+ return err
202+ }
203+ if isManual {
204+ continue
205+ }
206 c = make(chan struct{})
207 p.machines[id] = c
208 go runMachine(p.context.newMachineContext(), m, c, p.machineDead)
209@@ -171,7 +180,7 @@
210 for {
211 if pollInstance {
212 instInfo, err := pollInstanceInfo(context, m)
213- if err != nil {
214+ if err != nil && !state.IsNotProvisionedError(err) {
215 // If the provider doesn't implement Addresses/Status now,
216 // it never will until we're upgraded, so don't bother
217 // asking any more. We could use less resources
218@@ -185,9 +194,11 @@
219 return err
220 }
221 }
222- machineStatus, _, _, err := m.Status()
223- if err != nil {
224- logger.Warningf("cannot get current machine status for machine %v: %v", m.Id(), err)
225+ machineStatus := params.StatusPending
226+ if err == nil {
227+ if machineStatus, _, _, err = m.Status(); err != nil {
228+ logger.Warningf("cannot get current machine status for machine %v: %v", m.Id(), err)
229+ }
230 }
231 if len(instInfo.addresses) > 0 && instInfo.status != "" && machineStatus == params.StatusStarted {
232 // We've got at least one address and a status and instance is started, so poll infrequently.
233@@ -220,7 +231,11 @@
234 func pollInstanceInfo(context machineContext, m machine) (instInfo instanceInfo, err error) {
235 instInfo = instanceInfo{}
236 instId, err := m.InstanceId()
237- if err != nil && !state.IsNotProvisionedError(err) {
238+ // We can't ask the machine for its addresses if it isn't provisioned yet.
239+ if state.IsNotProvisionedError(err) {
240+ return instInfo, err
241+ }
242+ if err != nil {
243 return instInfo, fmt.Errorf("cannot get machine's instance id: %v", err)
244 }
245 instInfo, err = context.instanceInfo(instId)
246
247=== modified file 'worker/instancepoller/updater_test.go'
248--- worker/instancepoller/updater_test.go 2014-03-13 07:54:56 +0000
249+++ worker/instancepoller/updater_test.go 2014-04-29 17:12:19 +0000
250@@ -13,6 +13,7 @@
251 gc "launchpad.net/gocheck"
252
253 "launchpad.net/juju-core/state"
254+ "launchpad.net/juju-core/state/api/params"
255 coretesting "launchpad.net/juju-core/testing"
256 "launchpad.net/juju-core/testing/testbase"
257 )
258@@ -119,6 +120,57 @@
259 c.Assert(watcher.stopped, jc.IsTrue)
260 }
261
262+func (s *updaterSuite) TestManualMachinesIgnored(c *gc.C) {
263+ waitStatus := make(chan struct{})
264+ s.PatchValue(&MachineStatus, func(m *testMachine) (status params.Status, info string, data params.StatusData, err error) {
265+ // Signal that we're in Status.
266+ waitStatus <- struct{}{}
267+ return params.StatusPending, "", params.StatusData{}, nil
268+ })
269+ m := &testMachine{
270+ id: "99",
271+ instanceId: "manual:1234",
272+ life: state.Alive,
273+ }
274+ dyingc := make(chan struct{})
275+ context := &testUpdaterContext{
276+ dyingc: dyingc,
277+ newMachineContextFunc: func() machineContext {
278+ return &testMachineContext{
279+ getInstanceInfo: instanceInfoGetter(c, "manual:1234", testAddrs, "running", nil),
280+ dyingc: dyingc,
281+ }
282+ },
283+ getMachineFunc: func(id string) (machine, error) {
284+ c.Check(id, gc.Equals, m.id)
285+ return m, nil
286+ },
287+ }
288+ watcher := &testMachinesWatcher{
289+ changes: make(chan []string),
290+ }
291+ done := make(chan error)
292+ go func() {
293+ done <- watchMachinesLoop(context, watcher)
294+ }()
295+ // Send a change to start the machineLoop;
296+ watcher.changes <- []string{"99"}
297+ select {
298+ case <-waitStatus:
299+ c.Fatalf("poller called Status")
300+ case <-time.After(coretesting.ShortWait):
301+ c.Logf("status not called")
302+ }
303+ close(context.dyingc)
304+ select {
305+ case err := <-done:
306+ c.Assert(err, gc.IsNil)
307+ case <-time.After(coretesting.LongWait):
308+ c.Fatalf("timed out waiting for watchMachinesLoop to terminate")
309+ }
310+ c.Assert(watcher.stopped, jc.IsTrue)
311+}
312+
313 type testUpdaterContext struct {
314 newMachineContextFunc func() machineContext
315 getMachineFunc func(id string) (machine, error)

Subscribers

People subscribed via source and target branches

to all changes: