Description:
worker/provisioner: no tools is an error
We were treating no tools found as an error of the Provisioner, rather
than an error with the machine we were trying to provision (bug
#1311676). This now sets the status of the machine to an error state,
which lets us continue with our lives.
In the original bug about not having tools, it was shown that in the
local provider, doing
juju bootstrap -e local
juju deploy -e local precise/ubuntu
juju deploy -e local trusty/ubuntu ubuntu-t
Would end up with both machines stuck in Pending. Now it says:
$ juju status -e local
environment: local
machines:
"0":
agent-state: started
agent-version: 1.18.2.1
dns-name: localhost
instance-id: localhost
series: trusty
"1":
agent-state-info: '(error: no matching tools available)'
instance-id: pending
series: precise
"2":
agent-state: started
agent-version: 1.18.2.1
dns-name: 10.0.3.194
instance-id: jameinel-local-machine-2
series: trusty
hardware: arch=amd64
And you can see that it succeeded in deploying trusty because it put
precise into an error state.
+func (s *ProvisionerSuite)
TestProvisionerSetsErrorStatusWhenNoToolsAreAvailable(c *gc.C) {
+ p := s.newEnvironProvisioner(c)
+ defer stop(c, p)
+
+ // Check that an instance is not provisioned when the machine is
created...
+ m, err := s.BackingState.AddOneMachine(state.MachineTemplate{
+ // We need a valid series that has no tools uploaded
+ Series: "raring",
+ Jobs: []state.MachineJob{state.JobHostUnits},
+ Constraints: s.defaultConstraints,
+ })
+ c.Assert(err, gc.IsNil)
+ s.checkNoOperations(c)
+
+ t0 := time.Now()
+ for time.Since(t0) < coretesting.LongWait {
+ // And check the machine status is set to error.
+ status, info, _, err := m.Status()
+ c.Assert(err, gc.IsNil)
+ if status == params.StatusPending {
+ time.Sleep(coretesting.ShortWait)
+ continue
+ }
+ c.Assert(status, gc.Equals, params.StatusError)
+ c.Assert(info, gc.Equals, "no matching tools available")
+ break
+ }
+
+ // Restart the PA to make sure the machine is skipped again.
+ stop(c, p)
+ p = s.newEnvironProvisioner(c)
+ defer stop(c, p)
+ s.checkNoOperations(c)
+}
+
func (s *ProvisionerSuite)
TestProvisionerSetsErrorStatusWhenStartInstanceFailed(c *gc.C) {
brokenMsg := breakDummyProvider(c, s.State, "StartInstance")
p := s.newEnvironProvisioner(c)
Reviewers: mp+217011_ code.launchpad. net,
Message:
Please take a look.
Description:
worker/provisioner: no tools is an error
We were treating no tools found as an error of the Provisioner, rather
than an error with the machine we were trying to provision (bug
#1311676). This now sets the status of the machine to an error state,
which lets us continue with our lives.
In the original bug about not having tools, it was shown that in the
local provider, doing
juju bootstrap -e local
juju deploy -e local precise/ubuntu
juju deploy -e local trusty/ubuntu ubuntu-t
Would end up with both machines stuck in Pending. Now it says: state-info: '(error: no matching tools available)' local-machine- 2
$ juju status -e local
environment: local
machines:
"0":
agent-state: started
agent-version: 1.18.2.1
dns-name: localhost
instance-id: localhost
series: trusty
"1":
agent-
instance-id: pending
series: precise
"2":
agent-state: started
agent-version: 1.18.2.1
dns-name: 10.0.3.194
instance-id: jameinel-
series: trusty
hardware: arch=amd64
And you can see that it succeeded in deploying trusty because it put
precise into an error state.
https:/ /code.launchpad .net/~jameinel/ juju-core/ 1.18-provisione r-no-tools- is-fatal- 1311676/ +merge/ 217011
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/93720044/
Affected files (+44, -1 lines): provisioner/ provisioner_ task.go provisioner/ provisioner_ test.go
A [revision details]
M worker/
M worker/
Index: [revision details] 20140412095413- 8rps4bhva01cu0o 9
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision: tarmac-
+New revision: <email address hidden>
Index: worker/ provisioner/ provisioner_ task.go provisioner/ provisioner_ task.go' provisioner/ provisioner_ task.go 2014-04-02 08:44:20 +0000 provisioner/ provisioner_ task.go 2014-04-24 09:10:44 +0000 ols(series, cons) Errorf( "cannot find tools for machine %q: %v", machine, err) SetStatus( params. StatusError, err.Error(), nil); Errorf( "cannot set error status for machine %q: %v", machine, fig(machine)
=== modified file 'worker/
--- worker/
+++ worker/
@@ -419,7 +419,13 @@
}
possibleTools, err := task.possibleTo
if err != nil {
- return err
+ logger.
+ if err1 := machine.
err1 != nil {
+ // Something is wrong with this machine, better report it back.
+ logger.
err1)
+ return err1
+ }
+ return nil
}
machineConfig, err := task.machineCon
if err != nil {
Index: worker/ provisioner/ provisioner_ test.go provisioner/ provisioner_ test.go' provisioner/ provisioner_ test.go 2014-04-03 19:11:11 +0000 provisioner/ provisioner_ test.go 2014-04-24 09:10:44 +0000 InstanceCustom( c, m, "pork", cons)
=== modified file 'worker/
--- worker/
+++ worker/
@@ -390,6 +390,41 @@
s.checkStart
}
+func (s *ProvisionerSuite) SetsErrorStatus WhenNoToolsAreA vailable( c *gc.C) { visioner( c) AddOneMachine( state.MachineTe mplate{ MachineJob{ state.JobHostUn its}, aints, ions(c) LongWait { StatusPending { coretesting. ShortWait) visioner( c) ions(c) SetsErrorStatus WhenStartInstan ceFailed( c *gc.C) { der(c, s.State, "StartInstance") visioner( c)
TestProvisioner
+ p := s.newEnvironPro
+ defer stop(c, p)
+
+ // Check that an instance is not provisioned when the machine is
created...
+ m, err := s.BackingState.
+ // We need a valid series that has no tools uploaded
+ Series: "raring",
+ Jobs: []state.
+ Constraints: s.defaultConstr
+ })
+ c.Assert(err, gc.IsNil)
+ s.checkNoOperat
+
+ t0 := time.Now()
+ for time.Since(t0) < coretesting.
+ // And check the machine status is set to error.
+ status, info, _, err := m.Status()
+ c.Assert(err, gc.IsNil)
+ if status == params.
+ time.Sleep(
+ continue
+ }
+ c.Assert(status, gc.Equals, params.StatusError)
+ c.Assert(info, gc.Equals, "no matching tools available")
+ break
+ }
+
+ // Restart the PA to make sure the machine is skipped again.
+ stop(c, p)
+ p = s.newEnvironPro
+ defer stop(c, p)
+ s.checkNoOperat
+}
+
func (s *ProvisionerSuite)
TestProvisioner
brokenMsg := breakDummyProvi
p := s.newEnvironPro