Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .azure-pipelines/templates/Lint.Job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ parameters:
# macOS-only crates (mxc_darwin, seatbelt_common) β€” the workspace
# has Windows-only crates that do not compile on macOS, so we can't
# use --all-features here.
clippyArgs: --locked --release -p mxc_darwin -p seatbelt_common
clippyArgs: --locked --release -p mxc_darwin -p seatbelt_common -p apple_container_common

jobs:
- ${{ each item in parameters.matrix }}:
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/Build.MacOS.Job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ jobs:
# ships alongside mxc-exec-mac.
- name: Build
run: cargo build --locked --release --target aarch64-apple-darwin
-p mxc_darwin -p seatbelt_common -p wxc_common -p wxc_e2e_tests
-p mxc_darwin -p seatbelt_common -p apple_container_common
-p wxc_common -p wxc_e2e_tests
-p unix_test_proxy

# wxc_e2e_tests includes the Seatbelt executor characterization tests.
Expand All @@ -52,7 +53,8 @@ jobs:
# no elevation, so they run in this standard macOS job.
- name: Test
run: cargo test --locked --release --target aarch64-apple-darwin
-p mxc_darwin -p seatbelt_common -p wxc_common -p wxc_e2e_tests
-p mxc_darwin -p seatbelt_common -p apple_container_common
-p wxc_common -p wxc_e2e_tests

- name: Verify artifact payload
shell: bash
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/Lint.Job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
target: aarch64-apple-darwin
working-directory: src
# Workspace has Windows-only crates, so --all-features won't build on macOS.
clippy-args: --locked --release -p mxc_darwin -p seatbelt_common
clippy-args: --locked --release -p mxc_darwin -p seatbelt_common -p apple_container_common
runs-on: ${{ matrix.runner }}
defaults:
run:
Expand Down
1 change: 1 addition & 0 deletions src/Cargo.lock

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

1 change: 1 addition & 0 deletions src/backends/apple_container/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ description = "Typed Apple Container management primitives for the MXC macOS bac

[dependencies]
getrandom = { workspace = true }
libc = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
Expand Down
42 changes: 41 additions & 1 deletion src/backends/apple_container/common/src/availability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde::Deserialize;
use thiserror::Error;
use wxc_common::mxc_error::MxcError;

use crate::command::{CliArgument, CliCommand, CommandOutput, CommandRunner};
use crate::command::{CliArgument, CliCommand, CommandOutput, CommandRunner, SystemCommandRunner};

/// Fixed path where Apple's installer places the Container CLI.
pub const APPLE_CONTAINER_CLI_PATH: &str = "/usr/local/bin/container";
Expand Down Expand Up @@ -125,6 +125,46 @@ pub fn check_cli_installed() -> Result<(), AvailabilityError> {
check_cli_presence(Path::new(APPLE_CONTAINER_CLI_PATH).is_file())
}

/// Probe the current host using the production bounded command runner.
pub fn probe() -> Result<AppleContainerAvailability, AvailabilityError> {
probe_with(&SystemCommandRunner, &current_host_info())
}

/// Whether the current host passes the full read-only availability probe.
pub fn is_available() -> bool {
probe().is_ok()
}

fn current_host_info() -> HostInfo {
HostInfo::current(current_macos_major_version())
}

#[cfg(target_os = "macos")]
fn current_macos_major_version() -> Option<u32> {
let mut name = std::mem::MaybeUninit::<libc::utsname>::uninit();
// SAFETY: `uname` initializes the supplied `utsname` on success.
if unsafe { libc::uname(name.as_mut_ptr()) } != 0 {
return None;
}
// SAFETY: `uname` succeeded, so every field is initialized and the release
// field is a NUL-terminated C string.
let name = unsafe { name.assume_init() };
let release = unsafe { std::ffi::CStr::from_ptr(name.release.as_ptr()) };
let darwin_major = release
.to_str()
.ok()?
.split('.')
.next()?
.parse::<u32>()
.ok()?;
darwin_major.checked_add(1)
}

#[cfg(not(target_os = "macos"))]
fn current_macos_major_version() -> Option<u32> {
None
}

fn check_cli_presence(present: bool) -> Result<(), AvailabilityError> {
if present {
Ok(())
Expand Down
Loading
Loading