Skip to content

Commit

Permalink
[nexus] Add Physical Disk Policy, State (#5335)
Browse files Browse the repository at this point in the history
- Adds physical disk state, policy as defined in RFD 457
- Does not expose any way to modify this information
- In the future, these values will toggled by both sled expungement, and
explicitly through a physical disk API

Fixes #5153
  • Loading branch information
smklein authored Mar 29, 2024
1 parent 4eb8153 commit e762510
Show file tree
Hide file tree
Showing 29 changed files with 689 additions and 51 deletions.
4 changes: 4 additions & 0 deletions nexus/db-model/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ mod network_interface;
mod oximeter_info;
mod physical_disk;
mod physical_disk_kind;
mod physical_disk_policy;
mod physical_disk_state;
mod probe;
mod producer_endpoint;
mod project;
Expand Down Expand Up @@ -150,6 +152,8 @@ pub use network_interface::*;
pub use oximeter_info::*;
pub use physical_disk::*;
pub use physical_disk_kind::*;
pub use physical_disk_policy::*;
pub use physical_disk_state::*;
pub use probe::*;
pub use producer_endpoint::*;
pub use project::*;
Expand Down
11 changes: 10 additions & 1 deletion nexus/db-model/src/physical_disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// 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::{Generation, PhysicalDiskKind};
use super::{
Generation, PhysicalDiskKind, PhysicalDiskPolicy, PhysicalDiskState,
};
use crate::collection::DatastoreCollectionConfig;
use crate::schema::{physical_disk, zpool};
use chrono::{DateTime, Utc};
Expand All @@ -25,9 +27,12 @@ pub struct PhysicalDisk {

pub variant: PhysicalDiskKind,
pub sled_id: Uuid,
pub disk_policy: PhysicalDiskPolicy,
pub disk_state: PhysicalDiskState,
}

impl PhysicalDisk {
/// Creates a new in-service, active disk
pub fn new(
id: Uuid,
vendor: String,
Expand All @@ -45,6 +50,8 @@ impl PhysicalDisk {
model,
variant,
sled_id,
disk_policy: PhysicalDiskPolicy::InService,
disk_state: PhysicalDiskState::Active,
}
}

Expand All @@ -61,6 +68,8 @@ impl From<PhysicalDisk> for views::PhysicalDisk {
fn from(disk: PhysicalDisk) -> Self {
Self {
identity: disk.identity(),
policy: disk.disk_policy.into(),
state: disk.disk_state.into(),
sled_id: Some(disk.sled_id),
vendor: disk.vendor,
serial: disk.serial,
Expand Down
54 changes: 54 additions & 0 deletions nexus/db-model/src/physical_disk_policy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// 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/.

//! Database representation of a disks's operator-defined policy.
//!
//! This is related to, but different from `PhysicalDiskState`: a disk's **policy** is
//! its disposition as specified by the operator, while its **state** refers to
//! what's currently on it, as determined by Nexus.
//!
//! For example, a disk might be in the `Active` state, but have a policy of
//! `Expunged` -- this would mean that Nexus knows about resources currently
//! provisioned on the disk, but the operator has said that it should be marked
//! as gone.

use super::impl_enum_type;
use nexus_types::external_api::views;
use serde::{Deserialize, Serialize};

impl_enum_type!(
#[derive(Clone, SqlType, Debug, QueryId)]
#[diesel(postgres_type(name = "physical_disk_policy", schema = "public"))]
pub struct PhysicalDiskPolicyEnum;

#[derive(Clone, Copy, Debug, AsExpression, FromSqlRow, Serialize, Deserialize, PartialEq)]
#[diesel(sql_type = PhysicalDiskPolicyEnum)]
pub enum PhysicalDiskPolicy;

// Enum values
InService => b"in_service"
Expunged => b"expunged"
);

impl From<PhysicalDiskPolicy> for views::PhysicalDiskPolicy {
fn from(policy: PhysicalDiskPolicy) -> Self {
match policy {
PhysicalDiskPolicy::InService => {
views::PhysicalDiskPolicy::InService
}
PhysicalDiskPolicy::Expunged => views::PhysicalDiskPolicy::Expunged,
}
}
}

impl From<views::PhysicalDiskPolicy> for PhysicalDiskPolicy {
fn from(policy: views::PhysicalDiskPolicy) -> Self {
match policy {
views::PhysicalDiskPolicy::InService => {
PhysicalDiskPolicy::InService
}
views::PhysicalDiskPolicy::Expunged => PhysicalDiskPolicy::Expunged,
}
}
}
54 changes: 54 additions & 0 deletions nexus/db-model/src/physical_disk_state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// 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/.

//! Database representation of a physical disk's state as understood by Nexus.

use super::impl_enum_type;
use nexus_types::external_api::views;
use serde::{Deserialize, Serialize};
use std::fmt;
use strum::EnumIter;

impl_enum_type!(
#[derive(Clone, SqlType, Debug, QueryId)]
#[diesel(postgres_type(name = "physical_disk_state", schema = "public"))]
pub struct PhysicalDiskStateEnum;

#[derive(Clone, Copy, Debug, AsExpression, FromSqlRow, Serialize, Deserialize, PartialEq, Eq, EnumIter)]
#[diesel(sql_type = PhysicalDiskStateEnum)]
pub enum PhysicalDiskState;

// Enum values
Active => b"active"
Decommissioned => b"decommissioned"
);

impl fmt::Display for PhysicalDiskState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Forward to the canonical implementation in nexus-types.
views::PhysicalDiskState::from(*self).fmt(f)
}
}

impl From<PhysicalDiskState> for views::PhysicalDiskState {
fn from(state: PhysicalDiskState) -> Self {
match state {
PhysicalDiskState::Active => views::PhysicalDiskState::Active,
PhysicalDiskState::Decommissioned => {
views::PhysicalDiskState::Decommissioned
}
}
}
}

impl From<views::PhysicalDiskState> for PhysicalDiskState {
fn from(state: views::PhysicalDiskState) -> Self {
match state {
views::PhysicalDiskState::Active => PhysicalDiskState::Active,
views::PhysicalDiskState::Decommissioned => {
PhysicalDiskState::Decommissioned
}
}
}
}
2 changes: 2 additions & 0 deletions nexus/db-model/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,8 @@ table! {
model -> Text,

variant -> crate::PhysicalDiskKindEnum,
disk_policy -> crate::PhysicalDiskPolicyEnum,
disk_state -> crate::PhysicalDiskStateEnum,
sled_id -> Uuid,
}
}
Expand Down
3 changes: 2 additions & 1 deletion nexus/db-model/src/schema_versions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::collections::BTreeMap;
///
/// 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: SemverVersion = SemverVersion::new(48, 0, 0);
pub const SCHEMA_VERSION: SemverVersion = SemverVersion::new(49, 0, 0);

/// List of all past database schema versions, in *reverse* order
///
Expand All @@ -29,6 +29,7 @@ static KNOWN_VERSIONS: Lazy<Vec<KnownVersion>> = Lazy::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(49, "physical-disk-state-and-policy"),
KnownVersion::new(48, "add-metrics-producers-time-modified-index"),
KnownVersion::new(47, "add-view-for-bgp-peer-configs"),
KnownVersion::new(46, "first-named-migration"),
Expand Down
Loading

0 comments on commit e762510

Please sign in to comment.