diff --git a/nexus/db-model/src/instance.rs b/nexus/db-model/src/instance.rs index 83f44a4e57b..37268d94642 100644 --- a/nexus/db-model/src/instance.rs +++ b/nexus/db-model/src/instance.rs @@ -110,9 +110,7 @@ impl Instance { ncpus: params.ncpus.into(), memory: params.memory.into(), hostname: params.hostname.to_string(), - // TODO(eliza): allow this to be configured via the instance-create - // params... - auto_restart_policy: None, + auto_restart_policy: params.auto_restart_policy.clone().into(), runtime_state, updater_gen: Generation::new(), diff --git a/nexus/db-model/src/instance_auto_restart.rs b/nexus/db-model/src/instance_auto_restart.rs index ae546a46903..19e7465eab9 100644 --- a/nexus/db-model/src/instance_auto_restart.rs +++ b/nexus/db-model/src/instance_auto_restart.rs @@ -3,6 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use super::impl_enum_type; +use nexus_types::external_api::params; use serde::Deserialize; use serde::Serialize; use std::fmt; @@ -34,7 +35,29 @@ impl InstanceAutoRestart { impl fmt::Display for InstanceAutoRestart { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.label()) + self.label().fmt(f) + } +} + +impl From for params::InstanceAutoRestart { + fn from(value: InstanceAutoRestart) -> Self { + match value { + InstanceAutoRestart::Never => Self::Never, + InstanceAutoRestart::SledFailuresOnly => Self::SledFailuresOnly, + InstanceAutoRestart::AllFailures => Self::AllFailures, + } + } +} + +impl From for InstanceAutoRestart { + fn from(value: params::InstanceAutoRestart) -> Self { + match value { + params::InstanceAutoRestart::Never => Self::Never, + params::InstanceAutoRestart::SledFailuresOnly => { + Self::SledFailuresOnly + } + params::InstanceAutoRestart::AllFailures => Self::AllFailures, + } } } diff --git a/nexus/db-queries/src/db/datastore/vpc.rs b/nexus/db-queries/src/db/datastore/vpc.rs index b21a7cf6aa0..51460f2253e 100644 --- a/nexus/db-queries/src/db/datastore/vpc.rs +++ b/nexus/db-queries/src/db/datastore/vpc.rs @@ -2838,6 +2838,7 @@ mod tests { disks: vec![], ssh_public_keys: None, start: false, + ..Default::default() }, ), ) diff --git a/nexus/types/src/external_api/params.rs b/nexus/types/src/external_api/params.rs index 691f36534d4..55784c10c0c 100644 --- a/nexus/types/src/external_api/params.rs +++ b/nexus/types/src/external_api/params.rs @@ -982,6 +982,32 @@ pub enum ExternalIpDetach { Floating { floating_ip: NameOrId }, } +/// A policy determining when an instance should be automatically restarted by +/// the control plane. +#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema)] +#[serde(tag = "type", rename_all = "snake_case")] +pub enum InstanceAutoRestart { + /// The instance should not be automatically restarted by the control plane + /// if it failures. + Never, + /// The instance should be automatically restarted by the control plane if + /// the sled that it's running on reboots or fails, but it should not be + /// restarted automatically if the individual instance fails. This policy + /// will only automatically restart an instance if the control plane is able + /// to definitively determine that the instance failed due to a sled reboot + /// or fault. + /// + /// This is the default policy for instances that don't specify an + /// auto-restart policy. + #[default] + SledFailuresOnly, + /// The instance should be automatically restarted by the control plane in + /// the event of any failure. If the instance crashes, or if the sled it's + /// running on reboots, the control plane will always attempt to + /// automatically restart this instance. + AllFailures, +} + /// Create-time parameters for an `Instance` #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] pub struct InstanceCreate { @@ -1032,6 +1058,14 @@ pub struct InstanceCreate { /// Should this instance be started upon creation; true by default. #[serde(default = "bool_true")] pub start: bool, + + /// A policy that indicates whether the control plane should automatically + /// restart this instance if it fails. + /// + /// If this is not provided, it defaults to the "sled_failures_only" + /// auto-restart policy. + #[serde(default)] + pub auto_restart_policy: InstanceAutoRestart, } #[inline] diff --git a/openapi/nexus.json b/openapi/nexus.json index ac437b7c970..f0e732805f8 100644 --- a/openapi/nexus.json +++ b/openapi/nexus.json @@ -15182,6 +15182,56 @@ "time_run_state_updated" ] }, + "InstanceAutoRestart": { + "description": "A policy determining when an instance should be automatically restarted by the control plane.", + "oneOf": [ + { + "description": "The instance should not be automatically restarted by the control plane if it failures.", + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "never" + ] + } + }, + "required": [ + "type" + ] + }, + { + "description": "The instance should be automatically restarted by the control plane if the sled that it's running on reboots or fails, but it should not be restarted automatically if the individual instance fails. This policy will only automatically restart an instance if the control plane is able to definitively determine that the instance failed due to a sled reboot or fault.\n\nThis is the default policy for instances that don't specify an auto-restart policy.", + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "sled_failures_only" + ] + } + }, + "required": [ + "type" + ] + }, + { + "description": "The instance should be automatically restarted by the control plane in the event of any failure. If the instance crashes, or if the sled it's running on reboots, the control plane will always attempt to automatically restart this instance.", + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "all_failures" + ] + } + }, + "required": [ + "type" + ] + } + ] + }, "InstanceCpuCount": { "description": "The number of CPUs in an Instance", "type": "integer", @@ -15192,6 +15242,17 @@ "description": "Create-time parameters for an `Instance`", "type": "object", "properties": { + "auto_restart_policy": { + "description": "A policy that indicates whether the control plane should automatically restart this instance if it fails.\n\nIf this is not provided, it defaults to the \"sled_failures_only\" auto-restart policy.", + "default": { + "type": "sled_failures_only" + }, + "allOf": [ + { + "$ref": "#/components/schemas/InstanceAutoRestart" + } + ] + }, "description": { "type": "string" },