diff --git a/.github/buildomat/jobs/deploy.sh b/.github/buildomat/jobs/deploy.sh index 52c29fe342b..2ca565fdd28 100755 --- a/.github/buildomat/jobs/deploy.sh +++ b/.github/buildomat/jobs/deploy.sh @@ -429,18 +429,6 @@ do ACTUAL_ZPOOL_COUNT=$(pfexec zlogin oxz_switch /opt/oxide/omdb/bin/omdb db zpool list -i | wc -l) done -# The bootstrap command creates a disk, so before that: adjust the control plane -# storage buffer to 0 as the virtual hardware only creates 20G pools - -pfexec zlogin oxz_switch /opt/oxide/omdb/bin/omdb db zpool list - -for ZPOOL in $(pfexec zlogin oxz_switch /opt/oxide/omdb/bin/omdb db zpool list -i); -do - pfexec zlogin oxz_switch /opt/oxide/omdb/bin/omdb -w db zpool set-storage-buffer "${ZPOOL}" 0 -done - -pfexec zlogin oxz_switch /opt/oxide/omdb/bin/omdb db zpool list - export RUST_BACKTRACE=1 export E2E_TLS_CERT IPPOOL_START IPPOOL_END eval "$(./target/debug/bootstrap)" diff --git a/nexus/db-model/src/lib.rs b/nexus/db-model/src/lib.rs index a48d82bbf6d..75c6a0926c0 100644 --- a/nexus/db-model/src/lib.rs +++ b/nexus/db-model/src/lib.rs @@ -99,6 +99,7 @@ mod role_builtin; pub mod saga_types; mod schema_versions; mod service_kind; +mod setting; mod silo; mod silo_group; mod silo_user; @@ -218,6 +219,7 @@ pub use saga_types::*; pub use schema_versions::*; pub use semver_version::*; pub use service_kind::*; +pub use setting::*; pub use silo::*; pub use silo_auth_settings::*; pub use silo_group::*; diff --git a/nexus/db-model/src/schema_versions.rs b/nexus/db-model/src/schema_versions.rs index 4bbb118671b..56b5a2851dd 100644 --- a/nexus/db-model/src/schema_versions.rs +++ b/nexus/db-model/src/schema_versions.rs @@ -16,7 +16,7 @@ use std::{collections::BTreeMap, sync::LazyLock}; /// /// This must be updated when you change the database schema. Refer to /// schema/crdb/README.adoc in the root of this repository for details. -pub const SCHEMA_VERSION: Version = Version::new(153, 0, 0); +pub const SCHEMA_VERSION: Version = Version::new(154, 0, 0); /// List of all past database schema versions, in *reverse* order /// @@ -28,6 +28,7 @@ static KNOWN_VERSIONS: LazyLock> = LazyLock::new(|| { // | leaving the first copy as an example for the next person. // v // KnownVersion::new(next_int, "unique-dirname-with-the-sql-files"), + KnownVersion::new(154, "nexus-settings"), KnownVersion::new(153, "chicken-switches"), KnownVersion::new(152, "ereports"), KnownVersion::new(151, "zone-image-resolver-inventory"), diff --git a/nexus/db-model/src/setting.rs b/nexus/db-model/src/setting.rs new file mode 100644 index 00000000000..412ea3568d3 --- /dev/null +++ b/nexus/db-model/src/setting.rs @@ -0,0 +1,23 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +use super::impl_enum_type; +use nexus_db_schema::schema::setting; + +impl_enum_type!( + SettingNameEnum: + + #[derive(Copy, Clone, Debug, AsExpression, FromSqlRow, PartialEq)] + pub enum SettingName; + + // Enum values + ControlPlaneStorageBuffer => b"control_plane_storage_buffer" +); + +#[derive(Queryable, Insertable, Debug, Selectable, Clone)] +#[diesel(table_name = setting)] +pub struct Setting { + pub name: SettingName, + pub int_value: Option, +} diff --git a/nexus/db-queries/src/db/datastore/mod.rs b/nexus/db-queries/src/db/datastore/mod.rs index 80cb8f40650..7db6deffa57 100644 --- a/nexus/db-queries/src/db/datastore/mod.rs +++ b/nexus/db-queries/src/db/datastore/mod.rs @@ -91,6 +91,7 @@ pub mod region_snapshot_replacement; mod rendezvous_debug_dataset; mod role; mod saga; +mod setting; mod silo; mod silo_auth_settings; mod silo_group; diff --git a/nexus/db-queries/src/db/datastore/rack.rs b/nexus/db-queries/src/db/datastore/rack.rs index a121c51e043..87c53663e46 100644 --- a/nexus/db-queries/src/db/datastore/rack.rs +++ b/nexus/db-queries/src/db/datastore/rack.rs @@ -90,6 +90,7 @@ pub struct RackInit { pub recovery_user_password_hash: omicron_passwords::PasswordHashString, pub dns_update: DnsVersionUpdateBuilder, pub allowed_source_ips: AllowedSourceIps, + pub control_plane_storage_buffer_gib: u32, } /// Possible errors while trying to initialize rack @@ -112,6 +113,8 @@ enum RackInitError { Database(DieselError), // Error adding initial allowed source IP list AllowedSourceIpError(Error), + // Error changing a Nexus setting + ChangeSetting(Error), } // Catch-all for Diesel error conversion into RackInitError, which @@ -175,6 +178,7 @@ impl From for Error { err )), RackInitError::AllowedSourceIpError(err) => err, + RackInitError::ChangeSetting(err) => err, } } } @@ -911,6 +915,17 @@ impl DataStore { DieselError::RollbackTransaction })?; + Self::set_control_plane_storage_buffer_gib_impl( + opctx, + &conn, + rack_init.control_plane_storage_buffer_gib, + ) + .await + .map_err(|e| { + err.set(RackInitError::ChangeSetting(e)).unwrap(); + DieselError::RollbackTransaction + })?; + let rack = diesel::update(rack_dsl::rack) .filter(rack_dsl::id.eq(rack_id)) .set(( @@ -1118,6 +1133,7 @@ mod test { "test suite".to_string(), ), allowed_source_ips: AllowedSourceIps::Any, + control_plane_storage_buffer_gib: 0, } } } diff --git a/nexus/db-queries/src/db/datastore/setting.rs b/nexus/db-queries/src/db/datastore/setting.rs new file mode 100644 index 00000000000..e9ac846ddac --- /dev/null +++ b/nexus/db-queries/src/db/datastore/setting.rs @@ -0,0 +1,97 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +//! [`DataStore`] methods on [`Setting`]s. + +// Settings are dynamically controlled values for Nexus + +use super::DataStore; +use crate::authz; +use crate::context::OpContext; +use crate::db::datastore::ErrorHandler; +use crate::db::datastore::public_error_from_diesel; +use async_bb8_diesel::AsyncRunQueryDsl; +use diesel::prelude::*; +use nexus_db_lookup::DbConnection; +use nexus_db_model::Setting; +use nexus_db_model::SettingName; +use omicron_common::api::external::ByteCount; +use omicron_common::api::external::Error; + +impl DataStore { + pub(crate) async fn set_control_plane_storage_buffer_gib_impl( + opctx: &OpContext, + conn: &async_bb8_diesel::Connection, + gibibytes: u32, + ) -> Result<(), Error> { + opctx.authorize(authz::Action::Modify, &authz::FLEET).await?; + + use nexus_db_schema::schema::setting::dsl; + + let name = SettingName::ControlPlaneStorageBuffer; + let value: i64 = ByteCount::from_gibibytes_u32(gibibytes).into(); + + let maybe_existing = + Self::get_control_plane_storage_buffer_impl(opctx, conn).await?; + + if maybe_existing.is_some() { + diesel::update(dsl::setting) + .filter(dsl::name.eq(name)) + .set(dsl::int_value.eq(value)) + .execute_async(conn) + .await + .map(|_| ()) + .map_err(|e| public_error_from_diesel(e, ErrorHandler::Server)) + } else { + let setting = Setting { name, int_value: Some(value) }; + + diesel::insert_into(dsl::setting) + .values(setting) + .execute_async(conn) + .await + .map(|_| ()) + .map_err(|e| public_error_from_diesel(e, ErrorHandler::Server)) + } + } + + pub(crate) async fn get_control_plane_storage_buffer_impl( + opctx: &OpContext, + conn: &async_bb8_diesel::Connection, + ) -> Result, Error> { + opctx.authorize(authz::Action::Modify, &authz::FLEET).await?; + + use nexus_db_schema::schema::setting::dsl; + + let name = SettingName::ControlPlaneStorageBuffer; + + let result = dsl::setting + .filter(dsl::name.eq(name)) + .select(Setting::as_select()) + .first_async(conn) + .await + .optional() + .map_err(|e| public_error_from_diesel(e, ErrorHandler::Server))?; + + Ok(match result { + Some(setting) => { + // A row exists with this setting's name + match setting.int_value { + Some(value) => Some(ByteCount::try_from(value).unwrap()), + + None => None, + } + } + + None => None, + }) + } + + pub async fn get_control_plane_storage_buffer( + &self, + opctx: &OpContext, + ) -> Result, Error> { + let conn = self.pool_connection_authorized(opctx).await?; + Self::get_control_plane_storage_buffer_impl(opctx, &conn).await + } +} diff --git a/nexus/db-schema/src/enums.rs b/nexus/db-schema/src/enums.rs index f75d40beb3d..33abbec5e14 100644 --- a/nexus/db-schema/src/enums.rs +++ b/nexus/db-schema/src/enums.rs @@ -23,8 +23,8 @@ define_enums! { AddressLotKindEnum => "address_lot_kind", AffinityPolicyEnum => "affinity_policy", AlertClassEnum => "alert_class", - AlertDeliveryTriggerEnum => "alert_delivery_trigger", AlertDeliveryStateEnum => "alert_delivery_state", + AlertDeliveryTriggerEnum => "alert_delivery_trigger", AuthenticationModeEnum => "authentication_mode", BfdModeEnum => "bfd_mode", BlockSizeEnum => "block_size", @@ -44,8 +44,8 @@ define_enums! { IdentityProviderTypeEnum => "provider_type", IdentityTypeEnum => "identity_type", InstanceAutoRestartPolicyEnum => "instance_auto_restart", - InstanceStateEnum => "instance_state_v2", InstanceIntendedStateEnum => "instance_intended_state", + InstanceStateEnum => "instance_state_v2", InvConfigReconcilerStatusKindEnum => "inv_config_reconciler_status_kind", InvZoneImageSourceEnum => "inv_zone_image_source", InvZoneManifestSourceEnum => "inv_zone_manifest_source", @@ -70,6 +70,7 @@ define_enums! { RouterRouteKindEnum => "router_route_kind", SagaStateEnum => "saga_state", ServiceKindEnum => "service_kind", + SettingNameEnum => "setting_name", SledPolicyEnum => "sled_policy", SledRoleEnum => "sled_role", SledStateEnum => "sled_state", diff --git a/nexus/db-schema/src/schema.rs b/nexus/db-schema/src/schema.rs index 33e8e06353e..f747d56cf98 100644 --- a/nexus/db-schema/src/schema.rs +++ b/nexus/db-schema/src/schema.rs @@ -2528,3 +2528,10 @@ table! { report -> Jsonb, } } + +table! { + setting (name) { + name -> crate::enums::SettingNameEnum, + int_value -> Nullable, + } +} diff --git a/nexus/src/app/background/tasks/physical_disk_adoption.rs b/nexus/src/app/background/tasks/physical_disk_adoption.rs index 35c72437ebc..d01da775a47 100644 --- a/nexus/src/app/background/tasks/physical_disk_adoption.rs +++ b/nexus/src/app/background/tasks/physical_disk_adoption.rs @@ -11,7 +11,6 @@ //! //! In the future, this may become more explicitly operator-controlled. -use crate::app::CONTROL_PLANE_STORAGE_BUFFER; use crate::app::background::BackgroundTask; use futures::FutureExt; use futures::future::BoxFuture; @@ -20,6 +19,7 @@ use nexus_db_model::Zpool; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::DataStore; use nexus_types::identity::Asset; +use omicron_common::api::external::ByteCount; use omicron_common::api::external::DataPageParams; use omicron_uuid_kinds::CollectionUuid; use omicron_uuid_kinds::GenericUuid; @@ -62,6 +62,25 @@ impl BackgroundTask for PhysicalDiskAdoption { return json!({ "error": "task disabled" }); } + let control_plane_storage_buffer: ByteCount = match self + .datastore + .get_control_plane_storage_buffer(opctx) + .await { + Ok(value) => match value { + Some(value) => value, + None => { + // If no setting is in the database, use 0 + ByteCount::from(0) + } + }, + + Err(e) => { + return json!({ "error": format!( + "error getting control plane storage buffer: {e}" + )}); + } + }; + // Only adopt physical disks after rack handoff has completed. // // This prevents a race condition where the same physical disks @@ -140,7 +159,7 @@ impl BackgroundTask for PhysicalDiskAdoption { Uuid::new_v4(), inv_disk.sled_id.into_untyped_uuid(), disk.id(), - CONTROL_PLANE_STORAGE_BUFFER.into(), + control_plane_storage_buffer.into(), ); let result = self.datastore.physical_disk_and_zpool_insert( diff --git a/nexus/src/app/mod.rs b/nexus/src/app/mod.rs index c1916dc2763..c4a95983c44 100644 --- a/nexus/src/app/mod.rs +++ b/nexus/src/app/mod.rs @@ -31,7 +31,6 @@ use nexus_types::deployment::PendingMgsUpdates; use omicron_common::address::DENDRITE_PORT; use omicron_common::address::MGD_PORT; use omicron_common::address::MGS_PORT; -use omicron_common::api::external::ByteCount; use omicron_common::api::external::Error; use omicron_common::api::internal::shared::SwitchLocation; use omicron_uuid_kinds::OmicronZoneUuid; @@ -151,14 +150,6 @@ pub const MAX_DISK_SIZE_BYTES: u64 = 1023 * (1 << 30); // 1023 GiB /// This value is aribtrary pub const MAX_SSH_KEYS_PER_INSTANCE: u32 = 100; -/// The amount of disk space to reserve for non-Crucible / control plane -/// storage. This amount represents a buffer that the region allocation query -/// will not use for each U2. -/// -/// See oxidecomputer/omicron#7875 for the 250G determination. -pub const CONTROL_PLANE_STORAGE_BUFFER: ByteCount = - ByteCount::from_gibibytes_u32(250); - /// Manages an Oxide fleet -- the heart of the control plane pub struct Nexus { /// uuid for this nexus instance. diff --git a/nexus/src/app/rack.rs b/nexus/src/app/rack.rs index 6f71055e8dc..e498323e99d 100644 --- a/nexus/src/app/rack.rs +++ b/nexus/src/app/rack.rs @@ -4,7 +4,6 @@ //! Rack management -use crate::app::CONTROL_PLANE_STORAGE_BUFFER; use crate::external_api::params; use crate::external_api::params::CertificateCreate; use crate::external_api::shared::ServiceUsingCertificate; @@ -49,6 +48,7 @@ use nexus_types::silo::silo_dns_name; use omicron_common::address::{Ipv6Subnet, RACK_PREFIX, get_64_subnet}; use omicron_common::api::external::AddressLotKind; use omicron_common::api::external::BgpPeer; +use omicron_common::api::external::ByteCount; use omicron_common::api::external::DataPageParams; use omicron_common::api::external::Error; use omicron_common::api::external::IdentityMetadataCreateParams; @@ -133,7 +133,10 @@ impl super::Nexus { pool.id, pool.sled_id, pool.physical_disk_id, - CONTROL_PLANE_STORAGE_BUFFER.into(), + ByteCount::from_gibibytes_u32( + request.control_plane_storage_buffer_gib, + ) + .into(), ) }) .collect(); @@ -731,6 +734,8 @@ impl super::Nexus { .into(), dns_update, allowed_source_ips: request.allowed_source_ips, + control_plane_storage_buffer_gib: request + .control_plane_storage_buffer_gib, }, ) .await?; diff --git a/nexus/src/lib.rs b/nexus/src/lib.rs index cd6ba1393ea..88a18be5fb7 100644 --- a/nexus/src/lib.rs +++ b/nexus/src/lib.rs @@ -326,6 +326,7 @@ impl nexus_test_interface::NexusServer for Server { bfd: Vec::new(), }, allowed_source_ips: AllowedSourceIps::Any, + control_plane_storage_buffer_gib: 0, }, ) .await diff --git a/nexus/types/src/internal_api/params.rs b/nexus/types/src/internal_api/params.rs index a1a707d12a9..70823656ea5 100644 --- a/nexus/types/src/internal_api/params.rs +++ b/nexus/types/src/internal_api/params.rs @@ -189,6 +189,10 @@ pub struct RackInitializationRequest { pub rack_network_config: RackNetworkConfig, /// IPs or subnets allowed to make requests to user-facing services pub allowed_source_ips: AllowedSourceIps, + /// The amount of space to reserve per-disk for non-Crucible storage (i.e. + /// control plane storage) in gibibytes. This amount represents a buffer + /// that the region allocation query will not use for each U2. + pub control_plane_storage_buffer_gib: u32, } pub type DnsConfigParams = internal_dns_types::config::DnsConfigParams; diff --git a/openapi/bootstrap-agent.json b/openapi/bootstrap-agent.json index ce16f185800..49bfa887532 100644 --- a/openapi/bootstrap-agent.json +++ b/openapi/bootstrap-agent.json @@ -944,6 +944,13 @@ } ] }, + "control_plane_storage_buffer_gib": { + "description": "The amount of space to reserve per-disk for non-Crucible storage (i.e. control plane storage) in gibibytes. This amount represents a buffer that the region allocation query will not use for each U2.", + "default": 0, + "type": "integer", + "format": "uint32", + "minimum": 0 + }, "dns_servers": { "description": "The external DNS server addresses.", "type": "array", diff --git a/openapi/nexus-internal.json b/openapi/nexus-internal.json index 99acd5d7253..c4158ba431e 100644 --- a/openapi/nexus-internal.json +++ b/openapi/nexus-internal.json @@ -6439,6 +6439,12 @@ "$ref": "#/components/schemas/Certificate" } }, + "control_plane_storage_buffer_gib": { + "description": "The amount of space to reserve per-disk for non-Crucible storage (i.e. control plane storage) in gibibytes. This amount represents a buffer that the region allocation query will not use for each U2.", + "type": "integer", + "format": "uint32", + "minimum": 0 + }, "crucible_datasets": { "description": "Crucible datasets on the rack which have been provisioned by RSS.", "type": "array", @@ -6508,6 +6514,7 @@ "allowed_source_ips", "blueprint", "certs", + "control_plane_storage_buffer_gib", "crucible_datasets", "external_dns_zone_name", "external_port_count", diff --git a/schema/crdb/dbinit.sql b/schema/crdb/dbinit.sql index 11d32d1ae8f..7db7c81d647 100644 --- a/schema/crdb/dbinit.sql +++ b/schema/crdb/dbinit.sql @@ -5916,6 +5916,16 @@ ON omicron.public.webhook_delivery_attempt ( rx_id ); +CREATE TYPE IF NOT EXISTS omicron.public.setting_name AS ENUM ( + 'control_plane_storage_buffer' +); + +/* A table of Nexus' dynamic settings */ +CREATE TABLE IF NOT EXISTS omicron.public.setting ( + name omicron.public.setting_name PRIMARY KEY, + int_value INT +); + /* * Ereports * @@ -6095,7 +6105,7 @@ INSERT INTO omicron.public.db_metadata ( version, target_version ) VALUES - (TRUE, NOW(), NOW(), '153.0.0', NULL) + (TRUE, NOW(), NOW(), '154.0.0', NULL) ON CONFLICT DO NOTHING; COMMIT; diff --git a/schema/crdb/nexus-settings/up01.sql b/schema/crdb/nexus-settings/up01.sql new file mode 100644 index 00000000000..1821e337b30 --- /dev/null +++ b/schema/crdb/nexus-settings/up01.sql @@ -0,0 +1,3 @@ +CREATE TYPE IF NOT EXISTS omicron.public.setting_name AS ENUM ( + 'control_plane_storage_buffer' +); diff --git a/schema/crdb/nexus-settings/up02.sql b/schema/crdb/nexus-settings/up02.sql new file mode 100644 index 00000000000..9251b1d9f73 --- /dev/null +++ b/schema/crdb/nexus-settings/up02.sql @@ -0,0 +1,4 @@ +CREATE TABLE IF NOT EXISTS omicron.public.setting ( + name omicron.public.setting_name PRIMARY KEY, + int_value INT +); diff --git a/sled-agent/src/rack_setup/plan/service.rs b/sled-agent/src/rack_setup/plan/service.rs index 3732bca059a..972196c0e56 100644 --- a/sled-agent/src/rack_setup/plan/service.rs +++ b/sled-agent/src/rack_setup/plan/service.rs @@ -1257,6 +1257,7 @@ mod tests { bfd: Vec::new(), }, allowed_source_ips: AllowedSourceIps::Any, + control_plane_storage_buffer_gib: 0, } } diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index 55d5eb15e76..b05a4659230 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -1044,6 +1044,8 @@ impl ServiceInner { rack_network_config, external_port_count: port_discovery_mode.into(), allowed_source_ips, + control_plane_storage_buffer_gib: config + .control_plane_storage_buffer_gib, }; let notify_nexus = || async { diff --git a/sled-agent/src/sim/server.rs b/sled-agent/src/sim/server.rs index 05c75e18c0e..8d0bbce9ef2 100644 --- a/sled-agent/src/sim/server.rs +++ b/sled-agent/src/sim/server.rs @@ -595,6 +595,7 @@ pub async fn run_standalone_server( bfd: Vec::new(), }, allowed_source_ips: NexusTypes::AllowedSourceIps::Any, + control_plane_storage_buffer_gib: 0, }; handoff_to_nexus(&log, &config, &rack_init_request).await?; diff --git a/sled-agent/types/src/rack_init.rs b/sled-agent/types/src/rack_init.rs index 0f047734c10..54a83cc610d 100644 --- a/sled-agent/types/src/rack_init.rs +++ b/sled-agent/types/src/rack_init.rs @@ -110,6 +110,7 @@ pub mod back_compat { recovery_silo: v1.recovery_silo, rack_network_config: v1.rack_network_config.into(), allowed_source_ips: v1.allowed_source_ips, + control_plane_storage_buffer_gib: 0, } } } @@ -131,6 +132,8 @@ struct UnvalidatedRackInitializeRequest { rack_network_config: RackNetworkConfig, #[serde(default = "default_allowed_source_ips")] allowed_source_ips: AllowedSourceIps, + #[serde(default)] + control_plane_storage_buffer_gib: u32, } fn validate_external_dns( @@ -177,6 +180,8 @@ impl TryFrom for RackInitializeRequest { recovery_silo: value.recovery_silo, rack_network_config: value.rack_network_config, allowed_source_ips: value.allowed_source_ips, + control_plane_storage_buffer_gib: value + .control_plane_storage_buffer_gib, }) } } @@ -229,6 +234,12 @@ pub struct RackInitializeRequest { /// IPs or subnets allowed to make requests to user-facing services #[serde(default = "default_allowed_source_ips")] pub allowed_source_ips: AllowedSourceIps, + + /// The amount of space to reserve per-disk for non-Crucible storage (i.e. + /// control plane storage) in gibibytes. This amount represents a buffer + /// that the region allocation query will not use for each U2. + #[serde(default)] + pub control_plane_storage_buffer_gib: u32, } impl RackInitializeRequest { @@ -386,6 +397,7 @@ impl std::fmt::Debug for RackInitializeRequest { recovery_silo, rack_network_config, allowed_source_ips, + control_plane_storage_buffer_gib, } = &self; f.debug_struct("RackInitializeRequest") @@ -403,6 +415,10 @@ impl std::fmt::Debug for RackInitializeRequest { .field("recovery_silo", recovery_silo) .field("rack_network_config", rack_network_config) .field("allowed_source_ips", allowed_source_ips) + .field( + "control_plane_storage_buffer_gib", + control_plane_storage_buffer_gib, + ) .finish() } } @@ -502,6 +518,7 @@ mod tests { bfd: Vec::new(), }, allowed_source_ips: AllowedSourceIps::Any, + control_plane_storage_buffer_gib: 0, }; // Valid configs: all external DNS IPs are contained in the IP pool @@ -631,6 +648,7 @@ mod tests { bfd: Vec::new(), }, allowed_source_ips: AllowedSourceIps::Any, + control_plane_storage_buffer_gib: 0, }; assert_eq!( diff --git a/wicketd/src/rss_config.rs b/wicketd/src/rss_config.rs index 0223a565dfa..30d21228e86 100644 --- a/wicketd/src/rss_config.rs +++ b/wicketd/src/rss_config.rs @@ -314,6 +314,10 @@ impl CurrentRssConfig { .allowed_source_ips .clone() .unwrap_or(AllowedSourceIps::Any), + // Reserve a set amount of space for non-Crucible (i.e. control + // plane) storage. See oxidecomputer/omicron#7875 for the size + // determination. + control_plane_storage_buffer_gib: 250, }; Ok(request)