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
13 changes: 7 additions & 6 deletions .azure-pipelines/templates/Mac.Build.Job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,31 +65,31 @@ jobs:
targetTriple: $(targetTriple)
workingDirectory: $(workingDirectory)
# macOS-only crate set; the rest of the workspace has Windows-only
# crates that do not compile on macOS. unix_test_proxy backs
# network.proxy.builtinTestServer and ships next to mxc-exec-mac.
cargoPackages: mxc_darwin,seatbelt_common,wxc_common,unix_test_proxy
# crates that do not compile on macOS. unix_test_proxy and mxc_ffi
# ship next to mxc-exec-mac.
cargoPackages: mxc_darwin,seatbelt_common,wxc_common,unix_test_proxy,mxc_ffi

- ${{ else }}:
- template: Rust.Build.Steps.Unofficial.yml@self
parameters:
targetTriple: $(targetTriple)
workingDirectory: $(workingDirectory)
cargoArgs: -p mxc_darwin -p seatbelt_common -p wxc_common -p unix_test_proxy
cargoArgs: -p mxc_darwin -p seatbelt_common -p wxc_common -p unix_test_proxy -p mxc_ffi

# --- macOS Code Signing + Notarization (official builds only) ---
# ESRP handles the full signing flow using Microsoft's Developer ID
# certificate (CP-401337-Apple). No local cert or codesign needed.
#
# ESRP's Mac signing requires a .zip (or .dmg) input β€” raw Mach-O
# binaries are rejected. We zip before signing and unzip afterward. Both
# the executor and the testing-only unix-test-proxy are signed together.
# All three native runtime files are signed together.
#
# Flow: (1) zip β†’ (2) ESRP sign (hardened runtime) β†’ (3) ESRP notarize β†’ (4) unzip
# Stapling is impossible for standalone Mach-O binaries (Apple limitation);
# Gatekeeper checks the notarization ticket online instead.
- script: |
cd "$(targetTripleDir)"
zip mxc-exec-mac.zip mxc-exec-mac unix-test-proxy
zip mxc-exec-mac.zip mxc-exec-mac unix-test-proxy libmxc_ffi.dylib
displayName: 'Zip binaries for ESRP signing'
condition: and(succeeded(), eq(${{ parameters.isOfficialBuild }}, true))

Expand Down Expand Up @@ -161,6 +161,7 @@ jobs:
contents: |
mxc-exec-mac
unix-test-proxy
libmxc_ffi.dylib
targetFolder: $(outputDirectory)/$(targetTriple)

# Copy the .dSYM bundle into a sibling `symbols/` subdir, mirroring the
Expand Down
12 changes: 6 additions & 6 deletions .azure-pipelines/templates/Rust.Build.Job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ jobs:
wxc-wslc-daemon.exe
wxc-test-proxy.exe
mxc-diagnostic-console.exe
mxc_ffi.dll

# Linux specific variables
${{ if eq(item.os, 'linux') }}:
Expand All @@ -67,6 +68,7 @@ jobs:
signPattern: |
lxc-exec
unix-test-proxy
libmxc_ffi.so

# Paths
targetTriple: $(triplet)
Expand Down Expand Up @@ -127,13 +129,11 @@ jobs:
${{ else }}:
enableTest: 'false'

# unix_test_proxy is a separate workspace member (not a dep of lxc), so
# the workspace-member-scoped build above doesn't pick it up. Build it
# explicitly here so it lands alongside lxc-exec in the target dir and
# gets copied into the artifact via signPattern.
# These are separate workspace members (not deps of lxc), so the
# workspace-member-scoped build above doesn't pick them up.
- script: |
cargo build --release --target $(triplet) -p unix_test_proxy --manifest-path $(Build.SourcesDirectory)/src/Cargo.toml
displayName: Build unix-test-proxy
cargo build --release --target $(triplet) -p unix_test_proxy -p mxc_ffi --manifest-path $(Build.SourcesDirectory)/src/Cargo.toml
displayName: Build Node runtime dependencies
condition: eq('${{ item.os }}', 'linux')

# plm (Permissive Learning Mode) is functionally Windows-only, but it
Expand Down
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ The Rust workspace (`src/`) implements multiple sandboxing backends behind the `

- **SDK** (`sdk/node/`, `@microsoft/mxc-sdk`) β€” the public API. The one-shot surface (`spawnSandbox` / `spawnSandboxFromConfig` / `spawnSandboxAsync`) builds a `ContainerConfig` from a `SandboxPolicy`, serialises to base64, and spawns the correct native binary (`wxc-exec.exe`, `lxc-exec`, or `mxc-exec-mac`) via `node-pty`. The state-aware surface (`provisionSandbox` / `startSandbox` / `execInSandbox` / `execInSandboxAsync` / `stopSandbox` / `deprovisionSandbox`, in `sdk/node/src/state-aware.ts`) drives a sandbox through a multi-call lifecycle against `StateAwareContainmentBackend` backends; per-(backend, phase) typed `*Config` interfaces and a branded `SandboxId<C>` live in `sdk/node/src/state-aware-types.ts`. Typed wire-format errors live in `sdk/node/src/errors.ts` (closed `ErrorCode` union plus a single `MxcError` class carrying `code: ErrorCode`, mirroring the Rust `MxcError` shape). Platform detection is in `platform.ts`.

The SDK auto-discovers native binaries by checking `sdk/node/bin/<target-triple>/` (npm-packaged) and `src/target/<target-triple>/{release,debug}/` (local dev). The `build.bat`/`build.sh`/`build-mac.sh` scripts copy binaries into the SDK bin directory.
The SDK auto-discovers native binaries by checking `sdk/node/bin/<target-triple>/` (npm-packaged) and `src/target/<target-triple>/{release,debug}/` (local dev). The `build.bat`/`build.sh`/`build-mac.sh` scripts copy the executor and `mxc_ffi` shared library into the SDK bin directory; the platform CI workflows publish both in their per-target artifacts.

### C# SDK

Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/Build.Linux.Job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ jobs:
working-directory: src
run: cargo test --locked --release --target ${{ matrix.target }} -p plm

# unix_test_proxy is a separate workspace member, not a dep of lxc.
- name: Build unix-test-proxy
# These are separate workspace members, not dependencies of lxc.
- name: Build Node runtime dependencies
working-directory: src
run: cargo build --locked --release --target ${{ matrix.target }}
-p unix_test_proxy
-p unix_test_proxy -p mxc_ffi

# Exercises the real binary against the real dependencies: launches the
# slirp4netns supervisor, joins its user namespace, and asserts the
Expand All @@ -147,5 +147,6 @@ jobs:
path: |
src/target/${{ matrix.target }}/release/lxc-exec
src/target/${{ matrix.target }}/release/unix-test-proxy
src/target/${{ matrix.target }}/release/libmxc_ffi.so
if-no-files-found: error
retention-days: 1
8 changes: 4 additions & 4 deletions .github/workflows/Build.MacOS.Job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,11 @@ jobs:

# Mac uses package selection rather than feature selection β€” the
# workspace has Windows-only crates that won't compile here.
# unix_test_proxy backs network.proxy.builtinTestServer on Seatbelt and
# ships alongside mxc-exec-mac.
# unix_test_proxy and mxc_ffi ship 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 unix_test_proxy
-p unix_test_proxy -p mxc_ffi

# wxc_e2e_tests includes the Seatbelt executor characterization tests.
# mxc-exec-mac (built above via -p mxc_darwin) is what they drive; the
Expand All @@ -59,7 +58,7 @@ jobs:
run: |
set -euo pipefail
bin_dir="target/aarch64-apple-darwin/release"
for file in mxc-exec-mac unix-test-proxy; do
for file in mxc-exec-mac unix-test-proxy libmxc_ffi.dylib; do
if [[ ! -f "$bin_dir/$file" ]]; then
echo "Missing artifact file: $file" >&2
exit 1
Expand All @@ -73,5 +72,6 @@ jobs:
path: |
src/target/aarch64-apple-darwin/release/mxc-exec-mac
src/target/aarch64-apple-darwin/release/unix-test-proxy
src/target/aarch64-apple-darwin/release/libmxc_ffi.dylib
if-no-files-found: error
retention-days: 1
1 change: 1 addition & 0 deletions .github/workflows/Build.Windows.Job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ jobs:
src/target/${{ matrix.target }}/release/wxc-wslc-daemon.exe
src/target/${{ matrix.target }}/release/wxc-test-proxy.exe
src/target/${{ matrix.target }}/release/mxc-diagnostic-console.exe
src/target/${{ matrix.target }}/release/mxc_ffi.dll
src/target/${{ matrix.target }}/release/wslcsdk.dll
src/target/${{ matrix.target }}/release/wxc-ui-probe.exe
src/target/${{ matrix.target }}/release/wxc-test-driver.exe
Expand Down
10 changes: 9 additions & 1 deletion build-mac.sh
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ cd "$SRC_DIR"
# mxc-exec-mac is the seatbelt executor. unix-test-proxy is the bundled,
# testing-only HTTP proxy that backs `network.proxy.builtinTestServer`; it is
# spawned as a sibling of mxc-exec-mac by the proxy coordinator.
CARGO_FLAGS=("-p" "mxc_darwin" "-p" "unix_test_proxy")
CARGO_FLAGS=("-p" "mxc_darwin" "-p" "unix_test_proxy" "-p" "mxc_ffi")
if [ "$BUILD_TYPE" = "release" ]; then
CARGO_FLAGS+=("--release")
fi
Expand Down Expand Up @@ -133,6 +133,14 @@ copy_binary_for_target() {
echo "Warning: $src not found, skipping copy"
fi

local ffi_src="$SRC_DIR/target/$triple/$BUILD_TYPE/libmxc_ffi.dylib"
if [ -f "$ffi_src" ]; then
cp "$ffi_src" "$bin_dir/libmxc_ffi.dylib"
echo "Copied $ffi_src -> $bin_dir/libmxc_ffi.dylib"
else
echo "Warning: $ffi_src not found, skipping copy"
fi

# unix-test-proxy backs network.proxy.builtinTestServer (testing only).
# It must sit next to mxc-exec-mac so the proxy coordinator can resolve it.
local proxy_src="$SRC_DIR/target/$triple/$BUILD_TYPE/unix-test-proxy"
Expand Down
4 changes: 4 additions & 0 deletions build.bat
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ for %%T in (x86_64-pc-windows-msvc aarch64-pc-windows-msvc) do (
copy /Y "!BIN_DIR!\plm.exe" "sdk\node\bin\!SDK_ARCH!\" >nul
echo Copied !SDK_ARCH!\plm.exe
)
if exist "!BIN_DIR!\mxc_ffi.dll" (
copy /Y "!BIN_DIR!\mxc_ffi.dll" "sdk\node\bin\!SDK_ARCH!\" >nul
echo Copied !SDK_ARCH!\mxc_ffi.dll
)
if "%WITH_NANVIX%"=="1" (
for %%B in (nanvixd.exe nanvix_rootfs.img python3.initrd) do (
if exist "!BIN_DIR!\%%B" (
Expand Down
6 changes: 5 additions & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ echo "=== Building Rust binaries ($BUILD_TYPE) ==="
cd "$SRC_DIR"

# Packages to build and lint β€” kept in one place so build and clippy stay in sync.
LXC_PACKAGES=(-p lxc -p lxc_common -p wxc_common -p bwrap_common -p unix_test_proxy)
LXC_PACKAGES=(-p lxc -p lxc_common -p wxc_common -p bwrap_common -p unix_test_proxy -p mxc_ffi)

CARGO_FEATURES=()
FEATURES_LIST=()
Expand Down Expand Up @@ -137,6 +137,10 @@ if [ -n "$TARGET_TRIPLE" ]; then
cp "$SRC_DIR/target/$TARGET_TRIPLE/debug/unix-test-proxy" "$BIN_DIR/" 2>/dev/null || \
echo "Warning: Could not find unix-test-proxy binary to copy"
fi

cp "$SRC_DIR/target/$BUILD_TYPE/libmxc_ffi.so" "$BIN_DIR/" 2>/dev/null || \
cp "$SRC_DIR/target/$TARGET_TRIPLE/$BUILD_TYPE/libmxc_ffi.so" "$BIN_DIR/" 2>/dev/null || \
echo "Warning: Could not find libmxc_ffi.so to copy"
fi

# Build SDK
Expand Down
Loading