Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sled agent: index running VMMs by VMM ID, not instance ID #6429

Merged
merged 16 commits into from
Aug 27, 2024
1 change: 0 additions & 1 deletion clients/nexus-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ impl From<omicron_common::api::internal::nexus::SledInstanceState>
s: omicron_common::api::internal::nexus::SledInstanceState,
) -> Self {
Self {
propolis_id: s.propolis_id,
vmm_state: s.vmm_state.into(),
migration_in: s.migration_in.map(Into::into),
migration_out: s.migration_out.map(Into::into),
Expand Down
24 changes: 12 additions & 12 deletions clients/sled-agent-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//! Interface for making API requests to a Sled Agent

use async_trait::async_trait;
use omicron_uuid_kinds::PropolisUuid;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
Expand Down Expand Up @@ -166,7 +167,6 @@ impl From<types::SledInstanceState>
{
fn from(s: types::SledInstanceState) -> Self {
Self {
propolis_id: s.propolis_id,
vmm_state: s.vmm_state.into(),
migration_in: s.migration_in.map(Into::into),
migration_out: s.migration_out.map(Into::into),
Expand Down Expand Up @@ -448,33 +448,33 @@ impl From<types::SledIdentifiers>
/// are bonus endpoints, not generated in the real client.
#[async_trait]
pub trait TestInterfaces {
async fn instance_single_step(&self, id: Uuid);
async fn instance_finish_transition(&self, id: Uuid);
async fn instance_simulate_migration_source(
async fn vmm_single_step(&self, id: PropolisUuid);
async fn vmm_finish_transition(&self, id: PropolisUuid);
async fn vmm_simulate_migration_source(
&self,
id: Uuid,
id: PropolisUuid,
params: SimulateMigrationSource,
);
async fn disk_finish_transition(&self, id: Uuid);
}

#[async_trait]
impl TestInterfaces for Client {
async fn instance_single_step(&self, id: Uuid) {
async fn vmm_single_step(&self, id: PropolisUuid) {
let baseurl = self.baseurl();
let client = self.client();
let url = format!("{}/instances/{}/poke-single-step", baseurl, id);
let url = format!("{}/vmms/{}/poke-single-step", baseurl, id);
client
.post(url)
.send()
.await
.expect("instance_single_step() failed unexpectedly");
}

async fn instance_finish_transition(&self, id: Uuid) {
async fn vmm_finish_transition(&self, id: PropolisUuid) {
let baseurl = self.baseurl();
let client = self.client();
let url = format!("{}/instances/{}/poke", baseurl, id);
let url = format!("{}/vmms/{}/poke", baseurl, id);
client
.post(url)
.send()
Expand All @@ -493,14 +493,14 @@ impl TestInterfaces for Client {
.expect("disk_finish_transition() failed unexpectedly");
}

async fn instance_simulate_migration_source(
async fn vmm_simulate_migration_source(
&self,
id: Uuid,
id: PropolisUuid,
params: SimulateMigrationSource,
) {
let baseurl = self.baseurl();
let client = self.client();
let url = format!("{baseurl}/instances/{id}/sim-migration-source");
let url = format!("{baseurl}/vmms/{id}/sim-migration-source");
client
.post(url)
.json(&params)
Expand Down
3 changes: 0 additions & 3 deletions common/src/api/internal/nexus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,6 @@ pub struct VmmRuntimeState {
/// specific VMM and the instance it incarnates.
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct SledInstanceState {
/// The ID of the VMM whose state is being reported.
pub propolis_id: PropolisUuid,

/// The most recent state of the sled's VMM process.
pub vmm_state: VmmRuntimeState,

Expand Down
5 changes: 0 additions & 5 deletions nexus/db-queries/src/db/datastore/vmm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
//! [`DataStore`] helpers for working with VMM records.

use super::DataStore;
use crate::authz;
use crate::context::OpContext;
use crate::db;
use crate::db::error::public_error_from_diesel;
Expand Down Expand Up @@ -108,14 +107,10 @@ impl DataStore {
pub async fn vmm_fetch(
&self,
opctx: &OpContext,
authz_instance: &authz::Instance,
vmm_id: &PropolisUuid,
) -> LookupResult<Vmm> {
opctx.authorize(authz::Action::Read, authz_instance).await?;

let vmm = dsl::vmm
.filter(dsl::id.eq(vmm_id.into_untyped_uuid()))
.filter(dsl::instance_id.eq(authz_instance.id()))
.filter(dsl::time_deleted.is_null())
.select(Vmm::as_select())
.get_result_async(&*self.pool_connection_authorized(opctx).await?)
Expand Down
16 changes: 11 additions & 5 deletions nexus/internal-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ use omicron_common::{
update::ArtifactId,
};
use omicron_uuid_kinds::{
DemoSagaUuid, DownstairsKind, SledUuid, TypedUuid, UpstairsKind,
UpstairsRepairKind,
DemoSagaUuid, DownstairsKind, PropolisUuid, SledUuid, TypedUuid,
UpstairsKind, UpstairsRepairKind,
};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -108,14 +108,14 @@ pub trait NexusInternalApi {
body: TypedBody<SwitchPutRequest>,
) -> Result<HttpResponseOk<SwitchPutResponse>, HttpError>;

/// Report updated state for an instance.
/// Report updated state for a VMM.
#[endpoint {
method = PUT,
path = "/instances/{instance_id}",
path = "/vmms/{propolis_id}",
}]
async fn cpapi_instances_put(
rqctx: RequestContext<Self::Context>,
path_params: Path<InstancePathParam>,
path_params: Path<VmmPathParam>,
new_runtime_state: TypedBody<SledInstanceState>,
) -> Result<HttpResponseUpdatedNoContent, HttpError>;

Expand Down Expand Up @@ -568,6 +568,12 @@ pub struct InstancePathParam {
pub instance_id: Uuid,
}

/// Path parameters for VMM requests (internal API)
#[derive(Deserialize, JsonSchema)]
pub struct VmmPathParam {
pub propolis_id: PropolisUuid,
}

#[derive(Clone, Copy, Debug, Deserialize, JsonSchema, Serialize)]
pub struct CollectorIdPathParams {
/// The ID of the oximeter collector.
Expand Down
2 changes: 1 addition & 1 deletion nexus/src/app/background/tasks/abandoned_vmm_reaper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
//! remains alive and continues to own its virtual provisioning resources.
//!
//! Cleanup of instance resources when an instance's *active* VMM is destroyed
//! is handled elsewhere, by `notify_instance_updated` and (eventually) the
//! is handled elsewhere, by `notify_vmm_updated` and (eventually) the
gjcolombo marked this conversation as resolved.
Show resolved Hide resolved
//! `instance-update` saga.

use crate::app::background::BackgroundTask;
Expand Down
12 changes: 5 additions & 7 deletions nexus/src/app/background/tasks/instance_watcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use omicron_common::api::external::Error;
use omicron_common::api::external::InstanceState;
use omicron_common::api::internal::nexus::SledInstanceState;
use omicron_uuid_kinds::GenericUuid;
use omicron_uuid_kinds::InstanceUuid;
use omicron_uuid_kinds::PropolisUuid;
use oximeter::types::ProducerRegistry;
use sled_agent_client::Client as SledAgentClient;
use std::borrow::Cow;
Expand Down Expand Up @@ -83,9 +83,7 @@ impl InstanceWatcher {
async move {
slog::trace!(opctx.log, "checking on instance...");
gjcolombo marked this conversation as resolved.
Show resolved Hide resolved
let rsp = client
.instance_get_state(&InstanceUuid::from_untyped_uuid(
target.instance_id,
))
.vmm_get_state(&PropolisUuid::from_untyped_uuid(target.vmm_id))
.await;
let mut check = Check {
target,
Expand Down Expand Up @@ -159,10 +157,10 @@ impl InstanceWatcher {
"updating instance state";
"state" => ?new_runtime_state.vmm_state.state,
);
match crate::app::instance::notify_instance_updated(
match crate::app::instance::process_vmm_update(
&datastore,
&opctx,
InstanceUuid::from_untyped_uuid(target.instance_id),
PropolisUuid::from_untyped_uuid(target.vmm_id),
&new_runtime_state,
)
.await
Expand All @@ -176,7 +174,7 @@ impl InstanceWatcher {
_ => Err(Incomplete::UpdateFailed),
};
}
Ok(Some(saga)) => {
Ok(Some((_, saga))) => {
check.update_saga_queued = true;
if let Err(e) = sagas.saga_start(saga).await {
warn!(opctx.log, "update saga failed"; "error" => ?e);
Expand Down
Loading
Loading