From f0bbc519e864d546bc3d43de9a4dbb145ac342c1 Mon Sep 17 00:00:00 2001 From: Joseph Phillips Date: Thu, 5 Dec 2024 12:16:49 +0100 Subject: [PATCH] fix: allow setting provisioning info for dying machine We have a potential race where a machine can transition to "dying" while it is being provisioned. When this happens the provisioner can not record provisioning info against the machine. If this occurs during model destruction, we are effectively blocked, because the provisioner can't come back around to deprovisioning the machine and allowing its life cycle to advance. This softens the SetProvisioned checks to ensure a machine is not dead, instead of not dying or dead. This should give the provisioner the change to record the instance data, then come around immediately to deprovision. --- state/machine.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/state/machine.go b/state/machine.go index d676aac4f97..1a78e6212b1 100644 --- a/state/machine.go +++ b/state/machine.go @@ -1380,7 +1380,7 @@ func (m *Machine) SetProvisioned( { C: machinesC, Id: m.doc.DocID, - Assert: append(isAliveDoc, bson.DocElem{Name: "nonce", Value: ""}), + Assert: append(notDeadDoc, bson.DocElem{Name: "nonce", Value: ""}), Update: bson.D{{"$set", bson.D{{"nonce", nonce}}}}, }, { C: instanceDataC, @@ -1395,10 +1395,10 @@ func (m *Machine) SetProvisioned( return nil } else if err != txn.ErrAborted { return err - } else if alive, err := isAlive(m.st, machinesC, m.doc.DocID); err != nil { + } else if aliveOrDying, err := isNotDead(m.st, machinesC, m.doc.DocID); err != nil { return err - } else if !alive { - return machineNotAliveErr + } else if !aliveOrDying { + return errDeadOrGone } return fmt.Errorf("already set") }