Skip to content

Commit 1fd4c66

Browse files
authored
Merge pull request juju#6321 from perrito666/fix_1604965
Fix 1604965: machine stays in pending state even though node has been marked failed deployment in MAAS Maas provider was missing an error state by the maas controller, it is now handled. Additionally juju machine status is updated upon failure. ### QA Steps * Deploy a maas controller * tamper with the machines power profiles * deploy a charm * within moments you will see a failed deployment and the machine will be down.
2 parents ec33a8d + 9ccbcf6 commit 1fd4c66

File tree

10 files changed

+56
-17
lines changed

10 files changed

+56
-17
lines changed

apiserver/instancepoller/instancepoller.go

+6
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,12 @@ func (a *InstancePollerAPI) SetInstanceStatus(args params.SetStatus) (params.Err
212212
Since: &now,
213213
}
214214
err = machine.SetInstanceStatus(s)
215+
if status.Status(arg.Status) == status.ProvisioningError {
216+
s.Status = status.Error
217+
if err == nil {
218+
err = machine.SetStatus(s)
219+
}
220+
}
215221
}
216222
result.Results[i].Error = common.ServerError(err)
217223
}

apiserver/instancepoller/state.go

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type StateMachine interface {
2020
SetProviderAddresses(...network.Address) error
2121
InstanceStatus() (status.StatusInfo, error)
2222
SetInstanceStatus(status.StatusInfo) error
23+
SetStatus(status.StatusInfo) error
2324
String() string
2425
Refresh() error
2526
Life() state.Life

apiserver/provisioner/provisioner.go

+6
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,12 @@ func (p *ProvisionerAPI) SetInstanceStatus(args params.SetStatus) (params.ErrorR
809809
Since: &now,
810810
}
811811
err = machine.SetInstanceStatus(s)
812+
if status.Status(arg.Status) == status.ProvisioningError {
813+
s.Status = status.Error
814+
if err == nil {
815+
err = machine.SetStatus(s)
816+
}
817+
}
812818
}
813819
result.Results[i].Error = common.ServerError(err)
814820
}

provider/maas/environ.go

+3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ var shortAttempt = utils.AttemptStrategy{
5454
Delay: 200 * time.Millisecond,
5555
}
5656

57+
const statusPollInterval = 5 * time.Second
58+
5759
var (
5860
ReleaseNodes = releaseNodes
5961
DeploymentStatusCall = deploymentStatusCall
@@ -948,6 +950,7 @@ func (environ *maasEnviron) StartInstance(args environs.StartInstanceParams) (
948950
return nil, errors.Annotatef(err, "cannot run instances")
949951
}
950952
}
953+
951954
defer func() {
952955
if err != nil {
953956
if err := environ.StopInstances(inst.Id()); err != nil {

provider/maas/instance.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,24 @@ func maasObjectId(maasObject *gomaasapi.MAASObject) instance.Id {
5151
return instance.Id(maasObject.URI().String())
5252
}
5353

54+
func normalizeStatus(statusMsg string) string {
55+
return strings.ToLower(strings.TrimSpace(statusMsg))
56+
}
57+
5458
func convertInstanceStatus(statusMsg, substatus string, id instance.Id) instance.InstanceStatus {
5559
maasInstanceStatus := status.Empty
56-
switch statusMsg {
60+
switch normalizeStatus(statusMsg) {
5761
case "":
5862
logger.Debugf("unable to obtain status of instance %s", id)
5963
statusMsg = "error in getting status"
60-
case "Deployed":
64+
case "deployed":
6165
maasInstanceStatus = status.Running
62-
case "Deploying":
66+
case "deploying":
6367
maasInstanceStatus = status.Allocating
6468
if substatus != "" {
6569
statusMsg = fmt.Sprintf("%s: %s", statusMsg, substatus)
6670
}
67-
case "Failed Deployment":
71+
case "failed deployment":
6872
maasInstanceStatus = status.ProvisioningError
6973
if substatus != "" {
7074
statusMsg = fmt.Sprintf("%s: %s", statusMsg, substatus)

provider/maas/interfaces_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -923,8 +923,8 @@ func (s *interfacesSuite) TestMAAS2NetworkInterfaces(c *gc.C) {
923923
MTU: 1500,
924924
GatewayAddress: newAddressOnSpaceWithId("storage", network.Id("3"), "10.250.19.2"),
925925
}}
926-
927-
instance := &maas2Instance{machine: &fakeMachine{interfaceSet: exampleInterfaces}}
926+
machine := &fakeMachine{interfaceSet: exampleInterfaces}
927+
instance := &maas2Instance{machine: machine}
928928

929929
infos, err := maas2NetworkInterfaces(instance, subnetsMap)
930930
c.Assert(err, jc.ErrorIsNil)
@@ -965,8 +965,8 @@ func (s *interfacesSuite) TestMAAS2InterfacesNilVLAN(c *gc.C) {
965965
children: []string{"eth0.100", "eth0.250", "eth0.50"},
966966
},
967967
}
968-
969-
instance := &maas2Instance{machine: &fakeMachine{interfaceSet: exampleInterfaces}}
968+
machine := &fakeMachine{interfaceSet: exampleInterfaces}
969+
instance := &maas2Instance{machine: machine}
970970

971971
expected := []network.InterfaceInfo{{
972972
DeviceIndex: 0,

provider/maas/maas2_test.go

+8
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,14 @@ func (c *fakeController) ReleaseMachines(args gomaasapi.ReleaseMachinesArgs) err
184184
return c.NextErr()
185185
}
186186

187+
type fakeMachineOnlyController struct {
188+
machines []gomaasapi.Machine
189+
}
190+
191+
func (f *fakeMachineOnlyController) Machines(gomaasapi.MachinesArgs) ([]gomaasapi.Machine, error) {
192+
return f.machines, nil
193+
}
194+
187195
type fakeBootResource struct {
188196
gomaasapi.BootResource
189197
name string

provider/maas/maas2instance.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ func (mi *maas2Instance) Addresses() ([]network.Address, error) {
6565
// Status returns a juju status based on the maas instance returned
6666
// status message.
6767
func (mi *maas2Instance) Status() instance.InstanceStatus {
68-
// TODO (babbageclunk): this should rerequest to get live status.
68+
// A fresh status is not obtained here because the interface it is intended
69+
// to satisfy gets a new maas2Instance before each call, using a fresh status
70+
// would cause us to mask errors since this interface does not contemplate
71+
// returing them.
6972
statusName := mi.machine.StatusName()
7073
statusMsg := mi.machine.StatusMessage()
7174
return convertInstanceStatus(statusName, statusMsg, mi.Id())

provider/maas/maas2instance_test.go

+15-8
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,24 @@ type maas2InstanceSuite struct {
1919
var _ = gc.Suite(&maas2InstanceSuite{})
2020

2121
func (s *maas2InstanceSuite) TestString(c *gc.C) {
22-
instance := &maas2Instance{machine: &fakeMachine{hostname: "peewee", systemID: "herman"}}
22+
machine := &fakeMachine{hostname: "peewee", systemID: "herman"}
23+
instance := &maas2Instance{machine: machine}
2324
c.Assert(instance.String(), gc.Equals, "peewee:herman")
2425
}
2526

2627
func (s *maas2InstanceSuite) TestID(c *gc.C) {
27-
thing := &maas2Instance{machine: &fakeMachine{systemID: "herman"}}
28+
machine := &fakeMachine{systemID: "herman"}
29+
thing := &maas2Instance{machine: machine}
2830
c.Assert(thing.Id(), gc.Equals, instance.Id("herman"))
2931
}
3032

3133
func (s *maas2InstanceSuite) TestAddresses(c *gc.C) {
32-
instance := &maas2Instance{machine: &fakeMachine{ipAddresses: []string{
34+
machine := &fakeMachine{ipAddresses: []string{
3335
"0.0.0.0",
3436
"1.2.3.4",
3537
"127.0.0.1",
36-
}}}
38+
}}
39+
instance := &maas2Instance{machine: machine}
3740
expectedAddresses := []network.Address{
3841
network.NewAddress("0.0.0.0"),
3942
network.NewAddress("1.2.3.4"),
@@ -45,26 +48,30 @@ func (s *maas2InstanceSuite) TestAddresses(c *gc.C) {
4548
}
4649

4750
func (s *maas2InstanceSuite) TestZone(c *gc.C) {
48-
instance := &maas2Instance{machine: &fakeMachine{zoneName: "inflatable"}}
51+
machine := &fakeMachine{zoneName: "inflatable"}
52+
instance := &maas2Instance{machine: machine}
4953
zone, err := instance.zone()
5054
c.Assert(err, jc.ErrorIsNil)
5155
c.Assert(zone, gc.Equals, "inflatable")
5256
}
5357

5458
func (s *maas2InstanceSuite) TestStatusSuccess(c *gc.C) {
55-
thing := &maas2Instance{machine: &fakeMachine{statusMessage: "Wexler", statusName: "Deploying"}}
59+
machine := &fakeMachine{statusMessage: "Wexler", statusName: "Deploying"}
60+
thing := &maas2Instance{machine: machine}
5661
result := thing.Status()
5762
c.Assert(result, jc.DeepEquals, instance.InstanceStatus{status.Allocating, "Deploying: Wexler"})
5863
}
5964

6065
func (s *maas2InstanceSuite) TestStatusError(c *gc.C) {
61-
thing := &maas2Instance{machine: &fakeMachine{statusMessage: "", statusName: ""}}
66+
machine := &fakeMachine{statusMessage: "", statusName: ""}
67+
thing := &maas2Instance{machine: machine}
6268
result := thing.Status()
6369
c.Assert(result, jc.DeepEquals, instance.InstanceStatus{"", "error in getting status"})
6470
}
6571

6672
func (s *maas2InstanceSuite) TestHostname(c *gc.C) {
67-
thing := &maas2Instance{machine: &fakeMachine{hostname: "saul-goodman"}}
73+
machine := &fakeMachine{hostname: "saul-goodman"}
74+
thing := &maas2Instance{machine: machine}
6875
result, err := thing.hostname()
6976
c.Assert(err, jc.ErrorIsNil)
7077
c.Assert(result, gc.Equals, "saul-goodman")

worker/instancepoller/updater.go

+1
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ func pollInstanceInfo(context machineContext, m machine) (instInfo instanceInfo,
271271
return instanceInfo{}, err
272272
}
273273
}
274+
274275
}
275276
if m.Life() != params.Dead {
276277
providerAddresses, err := m.ProviderAddresses()

0 commit comments

Comments
 (0)