mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-20 11:21:49 +00:00
35 lines
1.3 KiB
Go
35 lines
1.3 KiB
Go
package daemon
|
|
|
|
import (
|
|
"fmt"
|
|
"log/slog"
|
|
|
|
"github.com/mulgadc/hive/hive/vm"
|
|
)
|
|
|
|
// TransitionState validates and applies a state transition on the given instance.
|
|
// It sets instance.Status, persists via WriteState, and logs.
|
|
// On validation failure, the instance status is unchanged and an error is returned.
|
|
// If WriteState fails, the in-memory status retains the new value (the VM has
|
|
// physically changed state regardless) and an error is returned.
|
|
// The caller must NOT hold d.Instances.Mu; this method acquires it internally.
|
|
func (d *Daemon) TransitionState(instance *vm.VM, target vm.InstanceState) error {
|
|
d.Instances.Mu.Lock()
|
|
current := instance.Status
|
|
if !vm.IsValidTransition(current, target) {
|
|
d.Instances.Mu.Unlock()
|
|
return fmt.Errorf("invalid state transition: %s -> %s for instance %s", current, target, instance.ID)
|
|
}
|
|
instance.Status = target
|
|
d.Instances.Mu.Unlock()
|
|
|
|
slog.Info("Instance state transition", "instanceId", instance.ID, "from", string(current), "to", string(target))
|
|
|
|
if err := d.WriteState(); err != nil {
|
|
slog.Error("Failed to persist state after transition", "instanceId", instance.ID,
|
|
"from", string(current), "to", string(target), "err", err)
|
|
return fmt.Errorf("state transition applied but write failed: %w", err)
|
|
}
|
|
return nil
|
|
}
|