-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[nexus] Support Bundles Datastore methods (#7021)
PR 2 / ??? Adds Support Bundles to the database, along with datastore-specific tests. These implementations are necessary to implement both the Support Bundle background task, in #7063 , as well as the HTTP interface for support bundles, in #7187
- Loading branch information
Showing
12 changed files
with
1,706 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
// 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 crate::schema::support_bundle; | ||
use crate::typed_uuid::DbTypedUuid; | ||
|
||
use chrono::{DateTime, Utc}; | ||
use nexus_types::external_api::shared::SupportBundleInfo as SupportBundleView; | ||
use nexus_types::external_api::shared::SupportBundleState as SupportBundleStateView; | ||
use omicron_uuid_kinds::DatasetKind; | ||
use omicron_uuid_kinds::DatasetUuid; | ||
use omicron_uuid_kinds::OmicronZoneKind; | ||
use omicron_uuid_kinds::OmicronZoneUuid; | ||
use omicron_uuid_kinds::SupportBundleKind; | ||
use omicron_uuid_kinds::SupportBundleUuid; | ||
use omicron_uuid_kinds::ZpoolKind; | ||
use omicron_uuid_kinds::ZpoolUuid; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
impl_enum_type!( | ||
#[derive(SqlType, Debug, QueryId)] | ||
#[diesel(postgres_type(name = "support_bundle_state", schema = "public"))] | ||
pub struct SupportBundleStateEnum; | ||
|
||
#[derive(Copy, Clone, Debug, AsExpression, FromSqlRow, Serialize, Deserialize, PartialEq)] | ||
#[diesel(sql_type = SupportBundleStateEnum)] | ||
pub enum SupportBundleState; | ||
|
||
// Enum values | ||
Collecting => b"collecting" | ||
Active => b"active" | ||
Destroying => b"destroying" | ||
Failing => b"failing" | ||
Failed => b"failed" | ||
); | ||
|
||
impl SupportBundleState { | ||
/// Returns the list of valid prior states. | ||
/// | ||
/// This is used to confirm that state updates are performed legally, | ||
/// and defines the possible state transitions. | ||
pub fn valid_old_states(&self) -> Vec<SupportBundleState> { | ||
use SupportBundleState::*; | ||
|
||
match self { | ||
Collecting => vec![], | ||
Active => vec![Collecting], | ||
// The "Destroying" state is terminal. | ||
Destroying => vec![Active, Collecting, Failing], | ||
Failing => vec![Collecting, Active], | ||
// The "Failed" state is terminal. | ||
Failed => vec![Active, Collecting, Failing], | ||
} | ||
} | ||
} | ||
|
||
impl From<SupportBundleState> for SupportBundleStateView { | ||
fn from(state: SupportBundleState) -> Self { | ||
use SupportBundleState::*; | ||
|
||
match state { | ||
Collecting => SupportBundleStateView::Collecting, | ||
Active => SupportBundleStateView::Active, | ||
Destroying => SupportBundleStateView::Destroying, | ||
// The distinction between "failing" and "failed" should not be | ||
// visible to end-users. This is internal book-keeping to decide | ||
// whether or not the bundle record can be safely deleted. | ||
// | ||
// Either way, it should be possible to delete the bundle. | ||
// If a user requests that we delete a bundle in these states: | ||
// - "Failing" bundles will become "Destroying" | ||
// - "Failed" bundles can be deleted immediately | ||
Failing => SupportBundleStateView::Failed, | ||
Failed => SupportBundleStateView::Failed, | ||
} | ||
} | ||
} | ||
|
||
#[derive( | ||
Queryable, | ||
Insertable, | ||
Debug, | ||
Clone, | ||
Selectable, | ||
Deserialize, | ||
Serialize, | ||
PartialEq, | ||
)] | ||
#[diesel(table_name = support_bundle)] | ||
pub struct SupportBundle { | ||
pub id: DbTypedUuid<SupportBundleKind>, | ||
pub time_created: DateTime<Utc>, | ||
pub reason_for_creation: String, | ||
pub reason_for_failure: Option<String>, | ||
pub state: SupportBundleState, | ||
pub zpool_id: DbTypedUuid<ZpoolKind>, | ||
pub dataset_id: DbTypedUuid<DatasetKind>, | ||
pub assigned_nexus: Option<DbTypedUuid<OmicronZoneKind>>, | ||
} | ||
|
||
impl SupportBundle { | ||
pub fn new( | ||
reason_for_creation: &'static str, | ||
zpool_id: ZpoolUuid, | ||
dataset_id: DatasetUuid, | ||
nexus_id: OmicronZoneUuid, | ||
) -> Self { | ||
Self { | ||
id: SupportBundleUuid::new_v4().into(), | ||
time_created: Utc::now(), | ||
reason_for_creation: reason_for_creation.to_string(), | ||
reason_for_failure: None, | ||
state: SupportBundleState::Collecting, | ||
zpool_id: zpool_id.into(), | ||
dataset_id: dataset_id.into(), | ||
assigned_nexus: Some(nexus_id.into()), | ||
} | ||
} | ||
} | ||
|
||
impl From<SupportBundle> for SupportBundleView { | ||
fn from(bundle: SupportBundle) -> Self { | ||
Self { | ||
id: bundle.id.into(), | ||
time_created: bundle.time_created, | ||
reason_for_creation: bundle.reason_for_creation, | ||
reason_for_failure: bundle.reason_for_failure, | ||
state: bundle.state.into(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.