From d76c2f041bcfcd1abfa74ff0fb5224f54df7bed7 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 16 Nov 2023 00:58:32 +0000 Subject: [PATCH] reject old generations and also ignore that on the client side --- sled-agent/src/rack_setup/service.rs | 27 +++++++++++++++++++++------ sled-agent/src/services.rs | 12 +++++++++--- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index 8c333b4294..a4f3cef936 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -275,11 +275,27 @@ impl ServiceInner { self.log, "attempting to set up sled's Omicron zones: {:?}", zones_config ); - client - .omicron_zones_put(&zones_config.clone().into()) - .await - .map_err(BackoffError::transient)?; - Ok::<(), BackoffError>>(()) + let result = + client.omicron_zones_put(&zones_config.clone().into()).await; + let Err(error) = result else { + return Ok::< + (), + BackoffError>, + >(()); + }; + + if let sled_agent_client::Error::ErrorResponse(response) = &error { + if let Some(code) = &response.error_code { + if code == "RequestedConfigOutdated" { + // XXX-dap is this really how to do this? look at what + // nexus does when propagating DNS maybe? or maybe the + // DNS tests? + return Ok(()); + } + } + } + + return Err(BackoffError::transient(error)); }; let log_failure = |error, delay| { warn!( @@ -315,7 +331,6 @@ impl ServiceInner { ) -> Result<(), SetupServiceError> { futures::future::join_all(configs.iter().map( |(sled_address, zones_config)| async move { - // XXX-dap check for the error indicating an older generation self.initialize_zones_on_sled(*sled_address, zones_config) .await?; Ok(()) diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index ddfe84573b..7d92d12d3f 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -196,9 +196,6 @@ pub enum Error { #[error("Could not initialize service {service} as requested: {message}")] BadServiceRequest { service: String, message: String }, - #[error("Services already configured for this Sled Agent")] - ServicesAlreadyConfigured, - #[error("Failed to get address: {0}")] GetAddressFailure(#[from] illumos_utils::zone::GetAddressError), @@ -223,6 +220,9 @@ pub enum Error { #[error("Error querying simnet devices")] Simnet(#[from] GetSimnetError), + #[error("Requested generation ({0}) is older than current ({0})")] + RequestedConfigOutdated(Generation, Generation), + #[error("Error migrating old-format services ledger")] ServicesMigration(anyhow::Error), } @@ -2601,6 +2601,12 @@ impl ServiceManager { }; let ledger_zone_config = ledger.data_mut(); + if ledger_zone_config.generation > request.generation { + return Err(Error::RequestedConfigOutdated( + request.generation, + ledger_zone_config.generation, + )); + } let new_config = self .ensure_all_omicron_zones(