diff --git a/nexus/Cargo.toml b/nexus/Cargo.toml index 4d55a134c1b..fb6a07969d6 100644 --- a/nexus/Cargo.toml +++ b/nexus/Cargo.toml @@ -51,7 +51,7 @@ num-integer.workspace = true once_cell.workspace = true openssl.workspace = true oximeter-client.workspace = true -oximeter-db.workspace = true +oximeter-db = { workspace = true, default-features = false, features = [ "oxql" ] } oxnet.workspace = true parse-display.workspace = true paste.workspace = true diff --git a/oximeter/db/Cargo.toml b/oximeter/db/Cargo.toml index 3811f45be05..253015287bc 100644 --- a/oximeter/db/Cargo.toml +++ b/oximeter/db/Cargo.toml @@ -19,6 +19,7 @@ clap.workspace = true dropshot.workspace = true futures.workspace = true highway.workspace = true +num.workspace = true omicron-common.workspace = true omicron-workspace-hack.workspace = true oximeter.workspace = true @@ -45,10 +46,6 @@ optional = true workspace = true optional = true -[dependencies.num] -workspace = true -optional = true - [dependencies.peg] workspace = true optional = true @@ -91,6 +88,7 @@ indexmap.workspace = true itertools.workspace = true omicron-test-utils.workspace = true slog-dtrace.workspace = true +sqlformat.workspace = true sqlparser.workspace = true strum.workspace = true tempfile.workspace = true @@ -107,7 +105,6 @@ sql = [ ] oxql = [ "dep:crossterm", - "dep:num", "dep:peg", "dep:reedline", "dep:tabled", diff --git a/oximeter/db/src/bin/oxdb/main.rs b/oximeter/db/src/bin/oxdb/main.rs index 871135fb16f..32ca2acb3c8 100644 --- a/oximeter/db/src/bin/oxdb/main.rs +++ b/oximeter/db/src/bin/oxdb/main.rs @@ -14,7 +14,7 @@ use oximeter::{ types::{Cumulative, Sample}, Metric, Target, }; -use oximeter_db::{query, shells::make_client, Client, DbWrite}; +use oximeter_db::{make_client, query, Client, DbWrite}; use slog::{debug, info, o, Drain, Level, Logger}; use std::net::IpAddr; use uuid::Uuid; @@ -148,6 +148,7 @@ enum Subcommand { }, /// Enter the Oximeter Query Language shell for interactive querying. + #[cfg(feature = "oxql")] Oxql { #[clap(flatten)] opts: oximeter_db::shells::oxql::ShellOptions, @@ -350,6 +351,7 @@ async fn main() -> anyhow::Result<()> { oximeter_db::shells::sql::shell(args.address, args.port, log, opts) .await? } + #[cfg(feature = "oxql")] Subcommand::Oxql { opts } => { oximeter_db::shells::oxql::shell(args.address, args.port, log, opts) .await? diff --git a/oximeter/db/src/client/mod.rs b/oximeter/db/src/client/mod.rs index 0c372cedae4..2d6212971e4 100644 --- a/oximeter/db/src/client/mod.rs +++ b/oximeter/db/src/client/mod.rs @@ -7,6 +7,7 @@ // Copyright 2024 Oxide Computer Company pub(crate) mod dbwrite; +#[cfg(any(feature = "oxql", test))] pub(crate) mod oxql; pub(crate) mod query_summary; #[cfg(any(feature = "sql", test))] diff --git a/oximeter/db/src/lib.rs b/oximeter/db/src/lib.rs index bbf29653e9c..c3d2014ad16 100644 --- a/oximeter/db/src/lib.rs +++ b/oximeter/db/src/lib.rs @@ -7,6 +7,7 @@ // Copyright 2024 Oxide Computer Company use crate::query::StringFieldSelector; +use anyhow::Context as _; use chrono::DateTime; use chrono::Utc; use dropshot::EmptyScanParams; @@ -23,9 +24,11 @@ pub use oximeter::Sample; use schemars::JsonSchema; use serde::Deserialize; use serde::Serialize; +use slog::Logger; use std::collections::BTreeMap; use std::convert::TryFrom; use std::io; +use std::net::{IpAddr, SocketAddr}; use std::num::NonZeroU32; use std::path::PathBuf; use thiserror::Error; @@ -40,6 +43,7 @@ pub mod shells; #[cfg(any(feature = "sql", test))] pub mod sql; +#[cfg(any(feature = "oxql", test))] pub use client::oxql::OxqlResult; pub use client::query_summary::QuerySummary; pub use client::Client; @@ -142,10 +146,12 @@ pub enum Error { #[error("SQL error")] Sql(#[from] sql::Error), + #[cfg(any(feature = "oxql", test))] #[error(transparent)] Oxql(oxql::Error), } +#[cfg(any(feature = "oxql", test))] impl From for Error { fn from(e: crate::oxql::Error) -> Self { Error::Oxql(e) @@ -239,6 +245,21 @@ pub struct TimeseriesPageSelector { pub offset: NonZeroU32, } +/// Create a client to the timeseries database, and ensure the database exists. +pub async fn make_client( + address: IpAddr, + port: u16, + log: &Logger, +) -> Result { + let address = SocketAddr::new(address, port); + let client = Client::new(address, &log); + client + .init_single_node_db() + .await + .context("Failed to initialize timeseries database")?; + Ok(client) +} + pub(crate) type TimeseriesKey = u64; // TODO-cleanup: Add the timeseries version in to the computation of the key. diff --git a/oximeter/db/src/oxql/mod.rs b/oximeter/db/src/oxql/mod.rs index b93d75b859a..3961fae1cce 100644 --- a/oximeter/db/src/oxql/mod.rs +++ b/oximeter/db/src/oxql/mod.rs @@ -19,7 +19,7 @@ pub use self::table::Table; pub use self::table::Timeseries; pub use anyhow::Error; -// Format a PEG parsing error into a nice anyhow error. +/// Format a PEG parsing error into a nice anyhow error. fn fmt_parse_error(source: &str, err: PegError) -> Error { use std::fmt::Write; let mut out = diff --git a/oximeter/db/src/query.rs b/oximeter/db/src/query.rs index 7b622920ffb..ceabf008883 100644 --- a/oximeter/db/src/query.rs +++ b/oximeter/db/src/query.rs @@ -371,10 +371,12 @@ impl FieldSelector { } } -/// A stringly-typed selector for finding fields by name and comparsion with a given value. +/// A stringly-typed selector for finding fields by name and comparsion with a +/// given value. /// -/// This is used internally to parse comparisons written as strings, such as from the `oxdb` -/// command-line tool or from another external source (Nexus API, for example). +/// This is used internally to parse comparisons written as strings, such as +/// from the `oxdb` command-line tool or from another external +/// source (Nexus API, for example). #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct StringFieldSelector { name: String, diff --git a/oximeter/db/src/shells/mod.rs b/oximeter/db/src/shells/mod.rs index 86ac053c80d..8f653ffcd5a 100644 --- a/oximeter/db/src/shells/mod.rs +++ b/oximeter/db/src/shells/mod.rs @@ -7,14 +7,9 @@ // Copyright 2024 Oxide Computer Company use crate::Client; -use crate::DbWrite as _; -use anyhow::Context as _; use dropshot::EmptyScanParams; use dropshot::WhichPage; use oximeter::TimeseriesSchema; -use slog::Logger; -use std::net::IpAddr; -use std::net::SocketAddr; #[cfg(any(feature = "oxql", test))] pub mod oxql; @@ -130,21 +125,6 @@ pub async fn describe_timeseries( Ok(()) } -/// Create a client to the timeseries database, and ensure the database exists. -pub async fn make_client( - address: IpAddr, - port: u16, - log: &Logger, -) -> Result { - let address = SocketAddr::new(address, port); - let client = Client::new(address, &log); - client - .init_single_node_db() - .await - .context("Failed to initialize timeseries database")?; - Ok(client) -} - /// Prepare the columns for a timeseries or virtual table. pub(crate) fn prepare_columns( schema: &TimeseriesSchema, diff --git a/oximeter/db/src/shells/oxql.rs b/oximeter/db/src/shells/oxql.rs index 3e81a0f6ec1..0f23ea7d64a 100644 --- a/oximeter/db/src/shells/oxql.rs +++ b/oximeter/db/src/shells/oxql.rs @@ -6,8 +6,8 @@ // Copyright 2024 Oxide Computer -use super::{list_timeseries, make_client, prepare_columns}; -use crate::{oxql::Table, Client, OxqlResult}; +use super::{list_timeseries, prepare_columns}; +use crate::{make_client, oxql::Table, Client, OxqlResult}; use clap::Args; use crossterm::style::Stylize; use reedline::DefaultPrompt; diff --git a/oximeter/db/src/shells/sql.rs b/oximeter/db/src/shells/sql.rs index 389ebd5019c..f75713da3b9 100644 --- a/oximeter/db/src/shells/sql.rs +++ b/oximeter/db/src/shells/sql.rs @@ -6,9 +6,9 @@ // Copyright 2024 Oxide Computer Company -use super::{make_client, prepare_columns}; +use super::prepare_columns; use crate::sql::{function_allow_list, QueryResult, Table}; -use crate::{Client, QuerySummary}; +use crate::{make_client, Client, QuerySummary}; use clap::Args; use dropshot::EmptyScanParams; use dropshot::WhichPage; diff --git a/oximeter/instruments/Cargo.toml b/oximeter/instruments/Cargo.toml index d5dcac411a3..831f102c662 100644 --- a/oximeter/instruments/Cargo.toml +++ b/oximeter/instruments/Cargo.toml @@ -36,6 +36,7 @@ http-instruments = [ "dep:oximeter", "dep:schemars", "dep:serde", + "dep:slog", "dep:uuid" ] kstat = [ diff --git a/sled-storage/src/manager_test_harness.rs b/sled-storage/src/manager_test_harness.rs index 74c2967a847..44092750178 100644 --- a/sled-storage/src/manager_test_harness.rs +++ b/sled-storage/src/manager_test_harness.rs @@ -123,6 +123,7 @@ impl Drop for StorageManagerTestHarness { impl StorageManagerTestHarness { /// Creates a new StorageManagerTestHarness with no associated disks. pub async fn new(log: &Logger) -> Self { + #[cfg(all(test, feature = "testing"))] illumos_utils::USE_MOCKS.store(false, Ordering::SeqCst); let tmp = camino_tempfile::tempdir_in("/var/tmp") .expect("Failed to make temporary directory"); diff --git a/sled-storage/src/pool.rs b/sled-storage/src/pool.rs index cc71aeb19d2..13ffe48e452 100644 --- a/sled-storage/src/pool.rs +++ b/sled-storage/src/pool.rs @@ -27,7 +27,7 @@ impl Pool { } /// Return a Pool consisting of fake info - #[cfg(feature = "testing")] + #[cfg(all(test, feature = "testing"))] pub fn new_with_fake_info(name: ZpoolName, parent: DiskIdentity) -> Pool { let info = ZpoolInfo::new_hardcoded(name.to_string()); Pool { name, info, parent } diff --git a/uuid-kinds/Cargo.toml b/uuid-kinds/Cargo.toml index e39017c2bfc..9ea2f8223cc 100644 --- a/uuid-kinds/Cargo.toml +++ b/uuid-kinds/Cargo.toml @@ -19,6 +19,6 @@ paste.workspace = true [features] default = ["std"] serde = ["newtype-uuid/serde"] -schemars08 = ["newtype-uuid/schemars08", "schemars"] +schemars08 = ["newtype-uuid/schemars08", "schemars", "std"] std = ["newtype-uuid/std"] uuid-v4 = ["newtype-uuid/v4"] diff --git a/uuid-kinds/src/lib.rs b/uuid-kinds/src/lib.rs index 430b3f7f9fb..53acc9c1ede 100644 --- a/uuid-kinds/src/lib.rs +++ b/uuid-kinds/src/lib.rs @@ -2,12 +2,12 @@ // 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/. -#![cfg_attr(not(feature = "std"), no_std)] - //! A registry for UUID kinds used in Omicron and related projects. //! //! See this crate's `README.adoc` for more information. +#![cfg_attr(not(feature = "std"), no_std)] + // Export these types so that other users don't have to pull in newtype-uuid. #[doc(no_inline)] pub use newtype_uuid::{