Skip to content

Commit b5b97dc

Browse files
committed
Merge remote-tracking branch 'origin/main' into rest-core-identifiers
# Conflicts: # rest-api/docs/index.html # rest-api/openapi/oasdiff-breaking-changes-ignore.txt
2 parents d4cadd0 + f6baab8 commit b5b97dc

103 files changed

Lines changed: 2943 additions & 6188 deletions

File tree

Some content is hidden

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

.cargo/config.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ rustflags = [
3737
#[target.x86_64-unknown-linux-gnu]
3838
#rustflags = ["-C", "linker=clang", "-C", "link-arg=-fuse-ld=lld"]
3939

40+
# mold is selected by the build environment rather than from here, through
41+
# CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER pointing at a driver that
42+
# already passes -fuse-ld=mold. Setting the flag here as well reached every
43+
# aarch64 build, including ones whose image predates the mold install, and cc
44+
# rejects a linker it does not have: "unrecognized command-line option
45+
# '-fuse-ld=mold'". Keep linker selection with the toolchain that provides it.
46+
4047
[env]
4148
RUST_TEST_THREADS = "40"
4249

.envrc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ export TESTDB_HOST=localhost
44

55
export RUSTC_WRAPPER=sccache
66

7+
# Native ARM64 builds use Clang. Cross-build environments provide their own
8+
# target-aware compiler driver through the same Cargo environment variable.
9+
case "$(uname -s):$(uname -m)" in
10+
Linux:aarch64|Linux:arm64)
11+
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=clang
12+
;;
13+
esac
14+
715
# required for sqlx::test harnesses.
816
export DATABASE_URL=postgresql://${TESTDB_USER}:${TESTDB_PASSWORD}@${TESTDB_HOST}
917
export REPO_ROOT=$(git rev-parse --show-toplevel)

.github/workflows/rest-lint-and-test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ jobs:
264264
- nvswitch-manager
265265
- powershelf-manager
266266
- proto
267+
- sdk-simple
267268
- site-agent
268269
- site-manager
269270
- site-workflow

crates/admin-cli/src/os_image/create/args.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,22 @@ EXAMPLES:
2727
2828
Create an OS image entry in a tenant's catalog:
2929
$ nico-admin-cli os-image create --id 12345678-1234-5678-90ab-cdef01234567 \
30-
--url https://images.example.com/ubuntu.qcow2 --digest sha256:abcd… --tenant-org-id fds34511233a
30+
--url https://images.example.com/ubuntu.qcow2 --digest sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae --tenant-org-id fds34511233a
3131
3232
Create one with a name/description and a Bearer auth token for the image URL:
3333
$ nico-admin-cli os-image create --id 12345678-1234-5678-90ab-cdef01234567 \
34-
--url https://images.example.com/ubuntu.qcow2 --digest sha256:abcd… --tenant-org-id fds34511233a \
35-
--name ubuntu-22.04 --description \"Ubuntu 22.04 base\" --auth-type Bearer --auth-token <token>
34+
--url https://images.example.com/ubuntu.qcow2 --digest sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae --tenant-org-id fds34511233a \
35+
--name ubuntu-22.04 --description \"Ubuntu 22.04 base\" --auth-type Bearer --auth-token ZXhhbXBsZS1pbWFnZS10b2tlbg==
36+
37+
Overwrite the smallest whole disk, preferring an EFI disk to break a size tie:
38+
$ nico-admin-cli os-image create --id 12345678-1234-5678-90ab-cdef01234567 \
39+
--url https://images.example.com/ubuntu.qcow2 --digest sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae --tenant-org-id fds34511233a \
40+
--boot-disk smallest
41+
42+
Overwrite a disk selected by its stable Linux identifier:
43+
$ nico-admin-cli os-image create --id 12345678-1234-5678-90ab-cdef01234567 \
44+
--url https://images.example.com/ubuntu.qcow2 --digest sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae --tenant-org-id fds34511233a \
45+
--boot-disk /dev/disk/by-id/nvme-Dell_BOSS-N1_VNOWW56VFCV0055601UT
3646
3747
")]
3848
pub(crate) struct Args {
@@ -84,7 +94,11 @@ pub(crate) struct Args {
8494
help = "Label of the root filesystem of the OS image."
8595
)]
8696
rootfs_label: Option<String>,
87-
#[clap(short = 'b', long, help = "Boot device path if using local disk.")]
97+
#[clap(
98+
short = 'b',
99+
long,
100+
help = "Whole-disk target that the image overwrites. Accepts 'smallest', /dev/nvme<controller>n<namespace>, /dev/sd<letters>, or /dev/disk/by-id/<identifier>. If omitted or empty, selection prefers a disk with an EFI partition, then /dev/nvme0n1 or /dev/sda."
101+
)]
88102
boot_disk: Option<String>,
89103
#[clap(long, help = "UUID of the image boot filesystem (/boot)")]
90104
bootfs_id: Option<String>,

crates/agent/src/ethernet_virtualization.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,9 @@ impl NvueClientContext {
231231
}
232232

233233
// Wrap the inner nvue_client's `push_config()` and try to avoid re-applying
234-
// a configuration we're already using. Returns Ok(Some(revision_id)) on
235-
// a change, Ok(None) if the config was unchanged, and otherwise passes
236-
// through errors from the inner client.
234+
// a configuration we're already using. Returns Ok(Some(revision_id)) when
235+
// a revision was applied, Ok(None) if the config was unchanged, and
236+
// otherwise passes through errors from the inner client.
237237
async fn update_config(
238238
&mut self,
239239
config: &NvueConfig,
@@ -245,13 +245,9 @@ impl NvueClientContext {
245245
{
246246
Ok(None)
247247
} else {
248-
self.nvue_client
249-
.push_config(config)
250-
.await
251-
.map(|revision_id| {
252-
self.last_applied_hash.replace(new_hash);
253-
Some(revision_id)
254-
})
248+
let revision_id = self.nvue_client.push_config(config).await?;
249+
self.last_applied_hash.replace(new_hash);
250+
Ok(revision_id)
255251
}
256252
}
257253
}

crates/api-core/src/api.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use carbide_secrets::certificates::CertificateProvider;
3939
use carbide_secrets::credentials::{
4040
BmcCredentialType, CredentialKey, CredentialManager, CredentialType, Credentials,
4141
};
42-
use carbide_site_explorer::{EndpointExplorationService, EndpointExplorer};
42+
use carbide_site_explorer::{AuthenticatedBmc, EndpointExplorationService, EndpointExplorer};
4343
use carbide_uuid::machine::{MachineId, MachineIdSubtypeTrait, MachineInterfaceId};
4444
use db::db_read::PgPoolReader;
4545
use db::work_lock_manager::WorkLockManagerHandle;
@@ -83,6 +83,9 @@ pub struct Api {
8383
pub(crate) dpu_health_log_limiter: LogLimiter<MachineId>,
8484
pub dynamic_settings: DynamicSettings,
8585
pub(crate) endpoint_explorer: Arc<dyn EndpointExplorer>,
86+
/// Authenticated BMC client for admin operations, supplied independently of
87+
/// endpoint exploration.
88+
pub(crate) bmc_client: Arc<dyn AuthenticatedBmc>,
8689
pub(crate) endpoint_exploration_service: Arc<EndpointExplorationService>,
8790
pub(crate) scout_stream_registry: ConnectionRegistry,
8891
#[allow(unused)]

crates/api-core/src/handlers/bmc_endpoint_explorer.rs

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ pub(crate) async fn disable_secure_boot(
512512
let (bmc_addr, bmc_mac_address) = resolve_bmc_interface(api, &bmc_endpoint_request).await?;
513513
let machine_interface = MachineInterfaceSnapshot::mock_with_mac(bmc_mac_address);
514514

515-
api.endpoint_explorer
515+
api.bmc_client
516516
.disable_secure_boot(bmc_addr, &machine_interface)
517517
.await
518518
.map_err(|e| CarbideError::internal(e.to_string()))?;
@@ -552,7 +552,7 @@ pub(crate) async fn lockdown(
552552
let (bmc_addr, bmc_mac_address) = resolve_bmc_interface(api, &bmc_endpoint_request).await?;
553553
let machine_interface = MachineInterfaceSnapshot::mock_with_mac(bmc_mac_address);
554554

555-
api.endpoint_explorer
555+
api.bmc_client
556556
.lockdown(bmc_addr, &machine_interface, action)
557557
.await
558558
.map_err(|e| CarbideError::internal(e.to_string()))?;
@@ -589,7 +589,7 @@ pub(crate) async fn lockdown_status(
589589
let machine_interface = MachineInterfaceSnapshot::mock_with_mac(bmc_mac_address);
590590

591591
let response = api
592-
.endpoint_explorer
592+
.bmc_client
593593
.lockdown_status(bmc_addr, &machine_interface)
594594
.await
595595
.map_err(|e| CarbideError::internal(e.to_string()))?;
@@ -622,7 +622,7 @@ pub(crate) async fn enable_infinite_boot(
622622
let (bmc_addr, bmc_mac_address) = resolve_bmc_interface(api, &bmc_endpoint_request).await?;
623623
let machine_interface = MachineInterfaceSnapshot::mock_with_mac(bmc_mac_address);
624624

625-
api.endpoint_explorer
625+
api.bmc_client
626626
.enable_infinite_boot(bmc_addr, &machine_interface)
627627
.await
628628
.map_err(|e| CarbideError::internal(e.to_string()))?;
@@ -662,7 +662,7 @@ pub(crate) async fn is_infinite_boot_enabled(
662662
let machine_interface = MachineInterfaceSnapshot::mock_with_mac(bmc_mac_address);
663663

664664
let is_enabled = api
665-
.endpoint_explorer
665+
.bmc_client
666666
.is_infinite_boot_enabled(bmc_addr, &machine_interface)
667667
.await
668668
.map_err(|e| CarbideError::internal(e.to_string()))?;
@@ -754,7 +754,7 @@ pub(crate) async fn machine_setup(
754754
entered_mac,
755755
);
756756

757-
api.endpoint_explorer
757+
api.bmc_client
758758
.machine_setup(bmc_addr, &machine_interface, boot_interface.as_ref())
759759
.await
760760
.map_err(|e| CarbideError::internal(e.to_string()))?;
@@ -844,7 +844,7 @@ pub(crate) async fn set_dpu_first_boot_order(
844844
)
845845
})?;
846846

847-
api.endpoint_explorer
847+
api.bmc_client
848848
.set_boot_order_dpu_first(bmc_addr, &machine_interface, &boot_interface)
849849
.await
850850
.map_err(|e| CarbideError::internal(e.to_string()))?;
@@ -1000,7 +1000,7 @@ async fn redfish_reset_bmc(
10001000
let (bmc_addr, bmc_mac_address) = resolve_bmc_interface(api, &request).await?;
10011001
let machine_interface = MachineInterfaceSnapshot::mock_with_mac(bmc_mac_address);
10021002

1003-
api.endpoint_explorer
1003+
api.bmc_client
10041004
.redfish_reset_bmc(bmc_addr, &machine_interface, reset_type)
10051005
.await
10061006
.map_err(|e| CarbideError::internal(e.to_string()))?;
@@ -1015,7 +1015,7 @@ async fn ipmitool_reset_bmc(
10151015
let (bmc_addr, bmc_mac_address) = resolve_bmc_interface(api, &request).await?;
10161016
let machine_interface = MachineInterfaceSnapshot::mock_with_mac(bmc_mac_address);
10171017

1018-
api.endpoint_explorer
1018+
api.bmc_client
10191019
.ipmitool_reset_bmc(bmc_addr, &machine_interface)
10201020
.await
10211021
.map_err(|e| CarbideError::internal(e.to_string()))?;
@@ -1031,7 +1031,7 @@ async fn redfish_power_control(
10311031
let (bmc_addr, bmc_mac_address) = resolve_bmc_interface(api, &request).await?;
10321032
let machine_interface = MachineInterfaceSnapshot::mock_with_mac(bmc_mac_address);
10331033

1034-
api.endpoint_explorer
1034+
api.bmc_client
10351035
.redfish_power_control(bmc_addr, &machine_interface, action)
10361036
.await
10371037
.map_err(|e| CarbideError::internal(e.to_string()))?;
@@ -1048,10 +1048,7 @@ pub(crate) async fn bmc_credential_status(
10481048
let (_bmc_addr, bmc_mac_address) = resolve_bmc_interface(api, &req).await?;
10491049

10501050
let machine_interface = MachineInterfaceSnapshot::mock_with_mac(bmc_mac_address);
1051-
let have_credentials = api
1052-
.endpoint_explorer
1053-
.have_credentials(&machine_interface)
1054-
.await;
1051+
let have_credentials = api.bmc_client.have_credentials(&machine_interface).await;
10551052

10561053
Ok(Response::new(rpc::BmcCredentialStatusResponse {
10571054
have_credentials,
@@ -1341,7 +1338,7 @@ pub(crate) async fn set_bmc_root_password(
13411338

13421339
tracing::info!(bmc_address = %bmc_addr, "Setting BMC root password");
13431340

1344-
api.endpoint_explorer
1341+
api.bmc_client
13451342
.set_bmc_root_password(bmc_addr, &machine_interface, &req.new_password)
13461343
.await
13471344
.map_err(|e| CarbideError::internal(e.to_string()))?;
@@ -1374,7 +1371,7 @@ pub(crate) async fn probe_bmc_vendor(
13741371
let machine_interface = MachineInterfaceSnapshot::mock_with_mac(bmc_mac_address);
13751372

13761373
let vendor = api
1377-
.endpoint_explorer
1374+
.bmc_client
13781375
.probe_bmc_vendor(bmc_addr, &machine_interface)
13791376
.await
13801377
.map_err(|e| CarbideError::internal(e.to_string()))?;
@@ -1396,7 +1393,7 @@ async fn do_create_bmc_user(
13961393
let (bmc_addr, bmc_mac_address) = resolve_bmc_interface(api, request).await?;
13971394
let machine_interface = MachineInterfaceSnapshot::mock_with_mac(bmc_mac_address);
13981395

1399-
api.endpoint_explorer
1396+
api.bmc_client
14001397
.create_bmc_user(
14011398
bmc_addr,
14021399
&machine_interface,
@@ -1418,7 +1415,7 @@ async fn do_delete_bmc_user(
14181415
let (bmc_addr, bmc_mac_address) = resolve_bmc_interface(api, request).await?;
14191416
let machine_interface = MachineInterfaceSnapshot::mock_with_mac(bmc_mac_address);
14201417

1421-
api.endpoint_explorer
1418+
api.bmc_client
14221419
.delete_bmc_user(bmc_addr, &machine_interface, delete_user)
14231420
.await
14241421
.map_err(|e| CarbideError::internal(e.to_string()))?;

crates/api-core/src/handlers/gpu_reset.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ pub(crate) async fn admin_gpu_reset(
9393
let (bmc_addr, bmc_mac_address) = resolve_bmc_interface(api, &bmc_endpoint_request).await?;
9494
let machine_interface = MachineInterfaceSnapshot::mock_with_mac(bmc_mac_address);
9595

96-
api.endpoint_explorer
96+
api.bmc_client
9797
.redfish_chassis_reset(bmc_addr, &machine_interface, &chassis_id, action)
9898
.await
9999
.map_err(|e| CarbideError::internal(e.to_string()))?;

0 commit comments

Comments
 (0)