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

Extract storage manager related code from sled-agent #4332

Merged
merged 69 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
7facfdf
wip
andrewjstone Sep 28, 2023
f927d02
wip
andrewjstone Sep 28, 2023
9818c05
wip
andrewjstone Sep 28, 2023
ab57c46
wip
andrewjstone Sep 28, 2023
90ec972
wip
andrewjstone Sep 29, 2023
5c169ac
wip
andrewjstone Sep 29, 2023
255155c
wip
andrewjstone Sep 29, 2023
115510a
wip
andrewjstone Sep 29, 2023
0bc3aa0
wip
andrewjstone Oct 2, 2023
e2e7dc8
wip
andrewjstone Oct 2, 2023
9a1e916
wip
andrewjstone Oct 2, 2023
30e16c8
wip
andrewjstone Oct 2, 2023
51dcbcd
wip
andrewjstone Oct 3, 2023
9651217
wip
andrewjstone Oct 3, 2023
4a38f90
wip
andrewjstone Oct 3, 2023
98cc812
wip
andrewjstone Oct 4, 2023
8c38e8d
wip
andrewjstone Oct 4, 2023
b2f3146
wip
andrewjstone Oct 4, 2023
1352bcf
wip
andrewjstone Oct 5, 2023
12245d5
wip
andrewjstone Oct 5, 2023
e8afd42
wip
andrewjstone Oct 6, 2023
f540c08
wip
andrewjstone Oct 6, 2023
1e34e7c
wip
andrewjstone Oct 6, 2023
9a3380a
wip
andrewjstone Oct 6, 2023
b2c01e7
wip
andrewjstone Oct 6, 2023
327578c
wip
andrewjstone Oct 6, 2023
9593047
wip
andrewjstone Oct 6, 2023
e64b569
wip
andrewjstone Oct 6, 2023
e0b4b26
wip
andrewjstone Oct 10, 2023
950a1d4
wip
andrewjstone Oct 10, 2023
1a67b04
wip
andrewjstone Oct 10, 2023
1e61ea9
wip
andrewjstone Oct 11, 2023
6a81c2c
wip
andrewjstone Oct 12, 2023
e3b77cf
wip - FakeStorageManager
andrewjstone Oct 24, 2023
79bd794
fix zone bundle tests
andrewjstone Oct 24, 2023
91742c6
wip
andrewjstone Oct 24, 2023
34903bc
wip
andrewjstone Oct 24, 2023
bbddcb4
cargo check --all-targets works
andrewjstone Oct 24, 2023
56d11bf
Merge remote-tracking branch 'origin/main' into sled-storage
andrewjstone Oct 24, 2023
b44defa
feed hikari
andrewjstone Oct 24, 2023
d60994c
tests pass
andrewjstone Oct 25, 2023
564f44b
addendum
andrewjstone Oct 25, 2023
396fdda
clippy clean
andrewjstone Oct 25, 2023
56a614f
fix sim builds
andrewjstone Oct 25, 2023
5e74730
fix doc build
andrewjstone Oct 25, 2023
fa35e28
deadlock fix + logging
andrewjstone Oct 26, 2023
9997149
synthetic disk related fixes
andrewjstone Oct 26, 2023
82e2505
Fix M2 expected datasets
andrewjstone Oct 26, 2023
a622fec
actually poll nexus storage notifications
andrewjstone Oct 26, 2023
6de271b
better logging for nexus requests
andrewjstone Oct 27, 2023
adedecc
actually add zpools to nexus
andrewjstone Oct 27, 2023
c8db7c8
remove unnecessary prints
andrewjstone Oct 27, 2023
a7a1971
Some review fixes
andrewjstone Nov 8, 2023
7d457ce
Fix subtle bugs wrt watch channels
andrewjstone Nov 8, 2023
c895657
some more review fixes
andrewjstone Nov 9, 2023
ed7f059
Use oneshot channels for HardwareMonitor setup
andrewjstone Nov 9, 2023
c0e3c71
Use oneshot for UnderlayAccess
andrewjstone Nov 9, 2023
a7848f9
more review fixes
andrewjstone Nov 9, 2023
3998708
more review fixes
andrewjstone Nov 9, 2023
9b5816a
Some more review updates
andrewjstone Nov 9, 2023
34fe6cc
Review fixes
andrewjstone Nov 9, 2023
7884213
USE_MOCKS only exists during testing now
andrewjstone Nov 9, 2023
49f2656
remove unnecessary ref
andrewjstone Nov 9, 2023
80baaf1
Merge branch 'main' into sled-storage
andrewjstone Nov 9, 2023
35e252b
remove autogenerated file
andrewjstone Nov 9, 2023
11f1b36
More review cleanup
andrewjstone Nov 10, 2023
713243a
Merge branch 'main' into sled-storage
andrewjstone Nov 13, 2023
cfc3ef7
review fixes
andrewjstone Nov 14, 2023
6b7845c
fix nit
andrewjstone Nov 14, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ members = [
"rpaths",
"sled-agent",
"sled-hardware",
"sled-storage",
"sp-sim",
"test-utils",
"tufaceous-lib",
Expand Down Expand Up @@ -122,6 +123,7 @@ default-members = [
"rpaths",
"sled-agent",
"sled-hardware",
"sled-storage",
"sp-sim",
"test-utils",
"tufaceous-lib",
Expand Down Expand Up @@ -329,6 +331,7 @@ similar-asserts = "1.5.0"
sled = "0.34"
sled-agent-client = { path = "clients/sled-agent-client" }
sled-hardware = { path = "sled-hardware" }
sled-storage = { path = "sled-storage" }
slog = { version = "2.7", features = [ "dynamic-keys", "max_level_trace", "release_max_level_debug" ] }
slog-async = "2.8"
slog-dtrace = "0.2"
Expand Down
2 changes: 2 additions & 0 deletions clients/nexus-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ futures.workspace = true
ipnetwork.workspace = true
omicron-common.workspace = true
omicron-passwords.workspace = true
sled-hardware.workspace = true
sled-storage.workspace = true
progenitor.workspace = true
regress.workspace = true
reqwest = { workspace = true, features = ["rustls-tls", "stream"] }
Expand Down
33 changes: 33 additions & 0 deletions clients/nexus-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,3 +388,36 @@ impl From<omicron_common::api::internal::shared::ExternalPortDiscovery>
}
}
}

impl From<sled_hardware::DiskVariant> for types::PhysicalDiskKind {
fn from(value: sled_hardware::DiskVariant) -> Self {
match value {
sled_hardware::DiskVariant::U2 => types::PhysicalDiskKind::U2,
sled_hardware::DiskVariant::M2 => types::PhysicalDiskKind::M2,
}
}
}

impl From<sled_hardware::Baseboard> for types::Baseboard {
fn from(b: sled_hardware::Baseboard) -> types::Baseboard {
types::Baseboard {
serial_number: b.identifier().to_string(),
part_number: b.model().to_string(),
revision: b.revision(),
}
}
}

impl From<sled_storage::dataset::DatasetKind> for types::DatasetKind {
fn from(k: sled_storage::dataset::DatasetKind) -> Self {
use sled_storage::dataset::DatasetKind::*;
match k {
CockroachDb => Self::Cockroach,
Crucible => Self::Crucible,
Clickhouse => Self::Clickhouse,
ClickhouseKeeper => Self::ClickhouseKeeper,
ExternalDns => Self::ExternalDns,
InternalDns => Self::InternalDns,
}
}
}
1 change: 1 addition & 0 deletions clients/sled-agent-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ regress.workspace = true
reqwest = { workspace = true, features = [ "json", "rustls-tls", "stream" ] }
serde.workspace = true
slog.workspace = true
sled-storage.workspace = true
uuid.workspace = true
omicron-workspace-hack.workspace = true
25 changes: 25 additions & 0 deletions clients/sled-agent-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use async_trait::async_trait;
use std::convert::TryFrom;
use std::str::FromStr;
use uuid::Uuid;

progenitor::generate_api!(
Expand Down Expand Up @@ -528,3 +529,27 @@ impl TestInterfaces for Client {
.expect("disk_finish_transition() failed unexpectedly");
}
}

impl From<sled_storage::dataset::DatasetKind> for types::DatasetKind {
fn from(k: sled_storage::dataset::DatasetKind) -> Self {
use sled_storage::dataset::DatasetKind::*;
match k {
CockroachDb => Self::CockroachDb,
Crucible => Self::Crucible,
Clickhouse => Self::Clickhouse,
ClickhouseKeeper => Self::ClickhouseKeeper,
ExternalDns => Self::ExternalDns,
InternalDns => Self::InternalDns,
}
}
}

impl From<sled_storage::dataset::DatasetName> for types::DatasetName {
fn from(n: sled_storage::dataset::DatasetName) -> Self {
Self {
pool_name: types::ZpoolName::from_str(&n.pool().to_string())
.unwrap(),
kind: n.dataset().clone().into(),
}
}
}
2 changes: 1 addition & 1 deletion common/src/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! Disk related types shared among crates
/// Uniquely identifies a disk.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct DiskIdentity {
pub vendor: String,
pub serial: String,
Expand Down
3 changes: 3 additions & 0 deletions illumos-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,6 @@ toml.workspace = true
[features]
# Enable to generate MockZones
testing = ["mockall"]
# Useful for tests that want real functionality and ability to run without
# pfexec
tmp_keypath = []
33 changes: 32 additions & 1 deletion illumos-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

//! Wrappers around illumos-specific commands.
#[allow(unused)]
use std::sync::atomic::{AtomicBool, Ordering};

use cfg_if::cfg_if;

pub mod addrobj;
Expand Down Expand Up @@ -93,7 +96,7 @@ mod inner {

// Helper function for starting the process and checking the
// exit code result.
pub fn execute(
pub fn execute_helper(
andrewjstone marked this conversation as resolved.
Show resolved Hide resolved
command: &mut std::process::Command,
) -> Result<std::process::Output, ExecutionError> {
let output = command.output().map_err(|err| {
Expand All @@ -108,6 +111,34 @@ mod inner {
}
}

// Due to feature unification, the `testing` feature is enabled when some tests
// don't actually want to use it. We allow them to opt out of the use of the
// free function here. We also explicitly opt-in where mocks are used.
//
// Note that this only works if the tests that use mocks and those that don't
// are run sequentially. However, this is how we do things in CI with nextest,
// so there is no problem currently.
//
// We can remove all this when we get rid of the mocks.
#[cfg(any(test, feature = "testing"))]
pub static USE_MOCKS: AtomicBool = AtomicBool::new(false);

pub fn execute(
command: &mut std::process::Command,
) -> Result<std::process::Output, ExecutionError> {
cfg_if! {
if #[cfg(any(test, feature = "testing"))] {
if USE_MOCKS.load(Ordering::SeqCst) {
mock_inner::execute_helper(command)
} else {
inner::execute_helper(command)
}
} else {
inner::execute_helper(command)
}
}
}

cfg_if! {
if #[cfg(any(test, feature = "testing"))] {
pub use mock_inner::*;
Expand Down
33 changes: 25 additions & 8 deletions illumos-utils/src/zfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,16 @@ pub const ZONE_ZFS_RAMDISK_DATASET_MOUNTPOINT: &str = "/zone";
pub const ZONE_ZFS_RAMDISK_DATASET: &str = "rpool/zone";

pub const ZFS: &str = "/usr/sbin/zfs";

/// This path is intentionally on a `tmpfs` to prevent copy-on-write behavior
/// and to ensure it goes away on power off.
///
/// We want minimize the time the key files are in memory, and so we rederive
/// the keys and recreate the files on demand when creating and mounting
/// encrypted filesystems. We then zero them and unlink them.
pub const KEYPATH_ROOT: &str = "/var/run/oxide/";
// Use /tmp so we don't have to worry about running tests with pfexec
pub const TEST_KEYPATH_ROOT: &str = "/tmp";

/// Error returned by [`Zfs::list_datasets`].
#[derive(thiserror::Error, Debug)]
Expand Down Expand Up @@ -158,19 +167,27 @@ impl fmt::Display for Keypath {
}
}

#[cfg(not(feature = "tmp_keypath"))]
impl From<&DiskIdentity> for Keypath {
fn from(id: &DiskIdentity) -> Self {
build_keypath(id, KEYPATH_ROOT)
}
}

#[cfg(feature = "tmp_keypath")]
impl From<&DiskIdentity> for Keypath {
fn from(id: &DiskIdentity) -> Self {
let filename = format!(
"{}-{}-{}-zfs-aes-256-gcm.key",
id.vendor, id.serial, id.model
);
let mut path = Utf8PathBuf::new();
path.push(KEYPATH_ROOT);
path.push(filename);
Keypath(path)
build_keypath(id, TEST_KEYPATH_ROOT)
}
}

fn build_keypath(id: &DiskIdentity, root: &str) -> Keypath {
let filename =
format!("{}-{}-{}-zfs-aes-256-gcm.key", id.vendor, id.serial, id.model);
let path: Utf8PathBuf = [root, &filename].iter().collect();
Keypath(path)
}

#[derive(Debug)]
pub struct EncryptionDetails {
pub keypath: Keypath,
Expand Down
37 changes: 34 additions & 3 deletions illumos-utils/src/zpool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ pub struct CreateError {
err: Error,
}

#[derive(thiserror::Error, Debug)]
#[error("Failed to destroy zpool: {err}")]
pub struct DestroyError {
#[from]
err: Error,
}

#[derive(thiserror::Error, Debug)]
#[error("Failed to list zpools: {err}")]
pub struct ListError {
Expand Down Expand Up @@ -89,7 +96,7 @@ impl FromStr for ZpoolHealth {
}

/// Describes a Zpool.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ZpoolInfo {
name: String,
size: u64,
Expand Down Expand Up @@ -121,6 +128,17 @@ impl ZpoolInfo {
pub fn health(&self) -> ZpoolHealth {
self.health
}

#[cfg(any(test, feature = "testing"))]
pub fn new_hardcoded(name: String) -> ZpoolInfo {
ZpoolInfo {
name,
size: 1024 * 1024 * 64,
allocated: 1024,
free: 1024 * 1023 * 64,
health: ZpoolHealth::Online,
}
}
}

impl FromStr for ZpoolInfo {
Expand Down Expand Up @@ -167,7 +185,10 @@ pub struct Zpool {}

#[cfg_attr(any(test, feature = "testing"), mockall::automock, allow(dead_code))]
impl Zpool {
pub fn create(name: ZpoolName, vdev: &Utf8Path) -> Result<(), CreateError> {
pub fn create(
name: &ZpoolName,
vdev: &Utf8Path,
) -> Result<(), CreateError> {
let mut cmd = std::process::Command::new(PFEXEC);
cmd.env_clear();
cmd.env("LC_ALL", "C.UTF-8");
Expand All @@ -189,7 +210,17 @@ impl Zpool {
Ok(())
}

pub fn import(name: ZpoolName) -> Result<(), Error> {
pub fn destroy(name: &ZpoolName) -> Result<(), DestroyError> {
let mut cmd = std::process::Command::new(PFEXEC);
cmd.env_clear();
cmd.env("LC_ALL", "C.UTF-8");
cmd.arg(ZPOOL).arg("destroy");
cmd.arg(&name.to_string());
execute(&mut cmd).map_err(Error::from)?;
Ok(())
}

pub fn import(name: &ZpoolName) -> Result<(), Error> {
let mut cmd = std::process::Command::new(PFEXEC);
cmd.env_clear();
cmd.env("LC_ALL", "C.UTF-8");
Expand Down
1 change: 1 addition & 0 deletions installinator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ omicron-common.workspace = true
reqwest.workspace = true
sha2.workspace = true
sled-hardware.workspace = true
sled-storage.workspace = true
slog.workspace = true
slog-async.workspace = true
slog-envlogger.workspace = true
Expand Down
Loading
Loading