Skip to content

Commit dc85999

Browse files
committed
Merge branch 'nexus_generation' into dap/handoff-quiesce-1
2 parents 912ea8f + 4d7235b commit dc85999

File tree

153 files changed

+11971
-1926
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

153 files changed

+11971
-1926
lines changed

Cargo.lock

Lines changed: 63 additions & 56 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ dns-server-api = { path = "dns-server-api" }
430430
dns-service-client = { path = "clients/dns-service-client" }
431431
dpd-client = { git = "https://github.com/oxidecomputer/dendrite", rev = "6e666520620e26432333d9060bc7d249ba9fa92e" }
432432
dropshot = { version = "0.16.3", features = [ "usdt-probes" ] }
433-
dyn-clone = "1.0.19"
433+
dyn-clone = "1.0.20"
434434
either = "1.15.0"
435435
ereport-types = { path = "ereport/types" }
436436
expectorate = "1.2.0"
@@ -639,12 +639,12 @@ propolis-mock-server = { git = "https://github.com/oxidecomputer/propolis", rev
639639
proptest = "1.7.0"
640640
qorb = "0.4.1"
641641
quote = "1.0"
642-
rand = "0.8.5"
643-
# We're still in the middle of migrating to rand 0.9.
644-
rand09 = { package = "rand", version = "0.9.1" }
645-
rand_core = "0.6.4"
646-
rand_distr = "0.4.3"
647-
rand_seeder = "0.3.0"
642+
# Some dependencies still require rand 0.8.x.
643+
rand08 = { package = "rand", version = "0.8.5" }
644+
rand = "0.9.2"
645+
rand_core = "0.9.3"
646+
rand_distr = "0.5.1"
647+
rand_seeder = "0.4.0"
648648
range-requests = { path = "range-requests" }
649649
ratatui = "0.29.0"
650650
rayon = "1.10"

bootstore/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ derive_more.workspace = true
2020
hex.workspace = true
2121
hkdf.workspace = true
2222
omicron-common.workspace = true
23-
rand = { workspace = true, features = ["getrandom"] }
23+
# vsss-rs requires rand 0.8
24+
rand08 = { workspace = true, features = ["getrandom"] }
2425
secrecy.workspace = true
2526
serde.workspace = true
2627
serde_with.workspace = true

bootstore/src/schemes/v0/share_pkg.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::Sha3_256Digest;
88
use crate::trust_quorum::{RackSecret, TrustQuorumError};
99
use chacha20poly1305::{ChaCha20Poly1305, Key, KeyInit, aead::Aead};
1010
use hkdf::Hkdf;
11-
use rand::{RngCore, rngs::OsRng};
11+
use rand08::{RngCore, rngs::OsRng};
1212
use secrecy::{ExposeSecret, SecretBox};
1313
use serde::{Deserialize, Serialize};
1414
use sha3::{Digest, Sha3_256};
@@ -129,7 +129,7 @@ pub fn create_pkgs(
129129
let shares = rack_secret.split(threshold, total_shares)?;
130130
let share_digests = share_digests(&shares);
131131
let mut salt = [0u8; 32];
132-
OsRng.fill_bytes(&mut salt);
132+
OsRng.try_fill_bytes(&mut salt).expect("fetched random bytes");
133133
let cipher = derive_encryption_key(&rack_uuid, &rack_secret, &salt);
134134
let mut pkgs = Vec::with_capacity(n as usize);
135135
for i in 0..n {
@@ -181,7 +181,7 @@ pub fn create_pkgs(
181181
// a counter.
182182
fn new_nonce(i: u8) -> [u8; 12] {
183183
let mut nonce = [0u8; 12];
184-
OsRng.fill_bytes(&mut nonce[..11]);
184+
OsRng.try_fill_bytes(&mut nonce[..11]).expect("fetched random bytes");
185185
nonce[11] = i;
186186
nonce
187187
}
@@ -266,8 +266,7 @@ impl fmt::Debug for SharePkg {
266266
#[cfg(test)]
267267
mod tests {
268268
use super::*;
269-
use rand::seq::SliceRandom;
270-
use rand::thread_rng;
269+
use rand08::seq::SliceRandom;
271270
use secrecy::ExposeSecret;
272271

273272
#[test]
@@ -335,7 +334,7 @@ mod tests {
335334

336335
// Grab a threshold of random shares and ensure that we can recompute
337336
// the rack secret
338-
let mut rng = &mut thread_rng();
337+
let mut rng = &mut rand08::thread_rng();
339338
let random_shares: Vec<_> =
340339
decrypted_shares.choose_multiple(&mut rng, 3).cloned().collect();
341340
let rack_secret2 = RackSecret::combine_shares(&random_shares).unwrap();

bootstore/src/trust_quorum/rack_secret.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// License, v. 2.0. If a copy of the MPL was not distributed with this
33
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
44

5-
use rand::rngs::OsRng;
5+
use rand08::rngs::OsRng;
66
use secrecy::{ExposeSecret, SecretBox};
77
use std::fmt::Debug;
88
use vsss_rs::curve25519::WrappedScalar;
@@ -63,6 +63,7 @@ impl RackSecret {
6363
/// Create a secret based on Curve25519
6464
pub fn new() -> RackSecret {
6565
let mut rng = OsRng;
66+
6667
RackSecret {
6768
secret: SecretBox::new(Box::new(Scalar::random(&mut rng))),
6869
}

clients/sled-agent-client/src/lib.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,19 @@ impl From<omicron_common::api::internal::shared::NetworkInterfaceKind>
331331
}
332332
}
333333

334+
// TODO-cleanup This is icky; can we move these methods to a separate client so
335+
// we don't need to add this header by hand?
336+
// https://github.com/oxidecomputer/omicron/issues/8900
337+
trait ApiVersionHeader {
338+
fn api_version_header(self, api_version: &'static str) -> Self;
339+
}
340+
341+
impl ApiVersionHeader for reqwest::RequestBuilder {
342+
fn api_version_header(self, api_version: &'static str) -> Self {
343+
self.header("api-version", api_version)
344+
}
345+
}
346+
334347
/// Exposes additional [`Client`] interfaces for use by the test suite. These
335348
/// are bonus endpoints, not generated in the real client.
336349
#[async_trait]
@@ -353,6 +366,7 @@ impl TestInterfaces for Client {
353366
let url = format!("{}/vmms/{}/poke-single-step", baseurl, id);
354367
client
355368
.post(url)
369+
.api_version_header(self.api_version())
356370
.send()
357371
.await
358372
.expect("instance_single_step() failed unexpectedly");
@@ -364,6 +378,7 @@ impl TestInterfaces for Client {
364378
let url = format!("{}/vmms/{}/poke", baseurl, id);
365379
client
366380
.post(url)
381+
.api_version_header(self.api_version())
367382
.send()
368383
.await
369384
.expect("instance_finish_transition() failed unexpectedly");
@@ -375,6 +390,7 @@ impl TestInterfaces for Client {
375390
let url = format!("{}/disks/{}/poke", baseurl, id);
376391
client
377392
.post(url)
393+
.api_version_header(self.api_version())
378394
.send()
379395
.await
380396
.expect("disk_finish_transition() failed unexpectedly");
@@ -390,6 +406,7 @@ impl TestInterfaces for Client {
390406
let url = format!("{baseurl}/vmms/{id}/sim-migration-source");
391407
client
392408
.post(url)
409+
.api_version_header(self.api_version())
393410
.json(&params)
394411
.send()
395412
.await

cockroach-admin/types/src/lib.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,97 @@ pub enum DecommissionError {
4242
ParseRow(#[from] csv::Error),
4343
}
4444

45+
/// CockroachDB Node ID
46+
///
47+
/// This field is stored internally as a String to avoid questions
48+
/// about size, signedness, etc - it can be treated as an arbitrary
49+
/// unique identifier.
50+
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize)]
51+
pub struct NodeId(pub String);
52+
53+
impl NodeId {
54+
pub fn new(id: String) -> Self {
55+
Self(id)
56+
}
57+
58+
pub fn as_str(&self) -> &str {
59+
&self.0
60+
}
61+
}
62+
63+
impl std::fmt::Display for NodeId {
64+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65+
write!(f, "{}", self.0)
66+
}
67+
}
68+
69+
impl std::str::FromStr for NodeId {
70+
type Err = std::convert::Infallible;
71+
72+
fn from_str(s: &str) -> Result<Self, Self::Err> {
73+
Ok(Self(s.to_string()))
74+
}
75+
}
76+
77+
// When parsing the underlying NodeId, we force it to be interpreted
78+
// as a String. Without this custom Deserialize implementation, we
79+
// encounter parsing errors when querying endpoints which return the
80+
// NodeId as an integer.
81+
impl<'de> serde::Deserialize<'de> for NodeId {
82+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
83+
where
84+
D: serde::Deserializer<'de>,
85+
{
86+
use serde::de::{Error, Visitor};
87+
use std::fmt;
88+
89+
struct NodeIdVisitor;
90+
91+
impl<'de> Visitor<'de> for NodeIdVisitor {
92+
type Value = NodeId;
93+
94+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
95+
formatter
96+
.write_str("a string or integer representing a node ID")
97+
}
98+
99+
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
100+
where
101+
E: Error,
102+
{
103+
Ok(NodeId(value.to_string()))
104+
}
105+
106+
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
107+
where
108+
E: Error,
109+
{
110+
Ok(NodeId(value))
111+
}
112+
113+
fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
114+
where
115+
E: Error,
116+
{
117+
Ok(NodeId(value.to_string()))
118+
}
119+
120+
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
121+
where
122+
E: Error,
123+
{
124+
Ok(NodeId(value.to_string()))
125+
}
126+
}
127+
128+
deserializer.deserialize_any(NodeIdVisitor)
129+
}
130+
}
131+
45132
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)]
46133
#[serde(rename_all = "snake_case")]
47134
pub struct NodeStatus {
135+
// TODO use NodeId
48136
pub node_id: String,
49137
pub address: SocketAddr,
50138
pub sql_address: SocketAddr,

cockroach-metrics/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ license = "MPL-2.0"
88
anyhow.workspace = true
99
chrono.workspace = true
1010
cockroach-admin-client.workspace = true
11+
cockroach-admin-types.workspace = true
1112
futures.workspace = true
1213
parallel-task-set.workspace = true
1314
reqwest.workspace = true

cockroach-metrics/src/lib.rs

Lines changed: 5 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use anyhow::{Context, Result};
1111
use chrono::{DateTime, Utc};
1212
use cockroach_admin_client::Client;
13+
use cockroach_admin_types::NodeId;
1314
use futures::stream::{FuturesUnordered, StreamExt};
1415
use parallel_task_set::ParallelTaskSet;
1516
use serde::{Deserialize, Serialize};
@@ -760,93 +761,6 @@ impl PrometheusMetrics {
760761
}
761762
}
762763

763-
/// CockroachDB Node ID
764-
///
765-
/// This field is stored internally as a String to avoid questions
766-
/// about size, signedness, etc - it can be treated as an arbitrary
767-
/// unique identifier.
768-
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize)]
769-
pub struct NodeId(pub String);
770-
771-
impl NodeId {
772-
pub fn new(id: String) -> Self {
773-
Self(id)
774-
}
775-
776-
pub fn as_str(&self) -> &str {
777-
&self.0
778-
}
779-
}
780-
781-
impl std::fmt::Display for NodeId {
782-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
783-
write!(f, "{}", self.0)
784-
}
785-
}
786-
787-
impl std::str::FromStr for NodeId {
788-
type Err = std::convert::Infallible;
789-
790-
fn from_str(s: &str) -> Result<Self, Self::Err> {
791-
Ok(Self(s.to_string()))
792-
}
793-
}
794-
795-
// When parsing the underlying NodeId, we force it to be interpreted
796-
// as a String. Without this custom Deserialize implementation, we
797-
// encounter parsing errors when querying endpoints which return the
798-
// NodeId as an integer.
799-
impl<'de> serde::Deserialize<'de> for NodeId {
800-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
801-
where
802-
D: serde::Deserializer<'de>,
803-
{
804-
use serde::de::{Error, Visitor};
805-
use std::fmt;
806-
807-
struct NodeIdVisitor;
808-
809-
impl<'de> Visitor<'de> for NodeIdVisitor {
810-
type Value = NodeId;
811-
812-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
813-
formatter
814-
.write_str("a string or integer representing a node ID")
815-
}
816-
817-
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
818-
where
819-
E: Error,
820-
{
821-
Ok(NodeId(value.to_string()))
822-
}
823-
824-
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
825-
where
826-
E: Error,
827-
{
828-
Ok(NodeId(value))
829-
}
830-
831-
fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
832-
where
833-
E: Error,
834-
{
835-
Ok(NodeId(value.to_string()))
836-
}
837-
838-
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
839-
where
840-
E: Error,
841-
{
842-
Ok(NodeId(value.to_string()))
843-
}
844-
}
845-
846-
deserializer.deserialize_any(NodeIdVisitor)
847-
}
848-
}
849-
850764
/// CockroachDB node liveness status
851765
///
852766
/// From CockroachDB's [NodeLivenessStatus protobuf enum](https://github.com/cockroachdb/cockroach/blob/release-21.1/pkg/kv/kvserver/liveness/livenesspb/liveness.proto#L107-L138)
@@ -1281,16 +1195,16 @@ sql_exec_latency_bucket{le="0.01"} 25
12811195
assert!(result.unwrap().metrics.is_empty());
12821196

12831197
// Malformed lines (missing values, extra spaces, etc.)
1284-
let malformed_input = r#"
1198+
let malformed_input = "
12851199
metric_name_no_value
1286-
metric_name_with_space
1200+
metric_name_with_space\x20
12871201
metric_name_multiple spaces here
12881202
= value_no_name
12891203
leading_space_metric 123
1290-
trailing_space_metric 456
1204+
trailing_space_metric 456\x20
12911205
metric{label=value} 789
12921206
metric{malformed=label value} 999
1293-
"#;
1207+
";
12941208
let result = PrometheusMetrics::parse(malformed_input);
12951209
assert!(result.is_ok());
12961210
// Should ignore malformed lines gracefully

0 commit comments

Comments
 (0)