Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7a7e05b
feat(helm): nico machine-a-tron
akorobkov-nvda Jun 10, 2026
a9ec173
fix(helm): nico machine-a-tron command
akorobkov-nvda Jun 10, 2026
2ebc128
fix(helm): nico machine-a-tron config
akorobkov-nvda Jun 10, 2026
01dd4f2
fix(helm): nico machine-a-tron requirements
akorobkov-nvda Jun 10, 2026
6e0b957
fix(helm): nico machine-a-tron machines config
akorobkov-nvda Jun 10, 2026
a8799ee
feat(helm): nico machine-a-tron graceful shutdown support
akorobkov-nvda Jun 22, 2026
34caf43
feat(helm): nico machine-a-tron readme
akorobkov-nvda Jun 22, 2026
a5b6720
fix(helm): nico machine-a-tron umbrella chart metadata
akorobkov-nvda Jun 22, 2026
39a9ec6
fix(helm): nico machine-a-tron chart review
akorobkov-nvda Jun 22, 2026
0a3faab
feat(helm): nico machine-a-tron large scale
akorobkov-nvda Jun 23, 2026
ea33b21
chore(helm): nico machine-a-tron nginx proxy rename
akorobkov-nvda Jun 23, 2026
971dd27
chore(helm): nico machine-a-tron readme
akorobkov-nvda Jun 23, 2026
b9f3fb3
fix(helm): nico machine-a-tron values
akorobkov-nvda Jun 23, 2026
87c1951
feat(helm): nico machine-a-tron migrate to clusterip
akorobkov-nvda Jul 7, 2026
f31f50e
test(helm): nico machine-a-tron
akorobkov-nvda Jul 7, 2026
735f709
feat(dev): devspace use machine-a-tron chart
akorobkov-nvda Jul 8, 2026
1fb2d50
feat(machine-a-tron): end-to-end deployment + scale testing to 4500 h…
shayan1995 Jul 8, 2026
52edb4b
docs(machine-a-tron): 4500-node quick start, measured timings, final …
shayan1995 Jul 9, 2026
cebaee3
feat(devspace): k3s and machine-a-tron namespace support
akorobkov-nvda Jul 9, 2026
ec08d13
feat(ci): machine-a-tron container build
akorobkov-nvda Jul 9, 2026
17c6697
chore(format): rbac rules
akorobkov-nvda Jul 9, 2026
8f36c4a
docs(machine-a-tron): multi-pod bmcServices mode — validated example …
shayan1995 Jul 10, 2026
887726b
fix(devspace): machine-a-tron values
akorobkov-nvda Jul 14, 2026
409c318
fix(devspace): machine-a-tron values
akorobkov-nvda Jul 14, 2026
29f78e4
fix(ci): machine-a-tron grype image scan
akorobkov-nvda Jul 14, 2026
e55d13e
fix(devspace): machine-a-tron values
akorobkov-nvda Jul 14, 2026
0298ce6
fix(devspace): devspace k3s support
akorobkov-nvda Jul 14, 2026
c7362ee
fix(devspace): address code review feedback
akorobkov-nvda Jul 15, 2026
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
32 changes: 32 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,35 @@ jobs:
${{ needs.prepare.outputs.image_registry }}/nvmetal-carbide@${{ needs.build-release-container-x86_64.outputs.image_digest }} \
${{ needs.prepare.outputs.image_registry }}/nvmetal-carbide-aarch64@${{ needs.build-release-container-aarch64.outputs.image_digest }}

build-machine-a-tron:
if: >-
${{
always()
&& github.event_name != 'schedule'
&& needs.prepare.result == 'success'
&& needs.prepare.outputs.source_files_changed == 'true'
}}
needs:
- prepare
uses: ./.github/workflows/docker-build.yml
with:
dockerfile_path: crates/machine-a-tron/Dockerfile
context_path: .
build_args: >-
${{ format('{{"VERSION":"{0}","CI_COMMIT_SHORT_SHA":"{1}"}}',
needs.prepare.outputs.version,
needs.prepare.outputs.short_sha) }}
image_name: ${{ needs.prepare.outputs.image_registry }}/machine-a-tron
image_tag: ${{ needs.prepare.outputs.version }}
platforms: linux/amd64
runner: linux-amd64-cpu16
push: ${{ needs.prepare.outputs.publish_images == 'true' }}
load: true
scan: true
tag_latest: false
timeout_minutes: 60
secrets: inherit

test-release-container-services:
if: >-
${{
Expand Down Expand Up @@ -1738,6 +1767,7 @@ jobs:
- build-artifacts-container-aarch64
- build-release-container-x86_64
- build-release-container-aarch64
- build-machine-a-tron
- test-release-container-services
- build-boot-artifacts-x86
- build-boot-artifacts-bfb
Expand Down Expand Up @@ -1838,6 +1868,7 @@ jobs:
runs-on: linux-amd64-cpu4
needs:
- build-release-container-x86_64
- build-machine-a-tron
- build-forge-cli-x86_64
- build-release-artifacts-x86-host
- build-release-artifacts-arm-host
Expand Down Expand Up @@ -1868,6 +1899,7 @@ jobs:
- build-artifacts-container-aarch64
- build-release-container-x86_64
- build-release-container-aarch64
- build-machine-a-tron
- test-release-container-services
- build-boot-artifacts-x86
- build-boot-artifacts-bfb
Expand Down
5 changes: 4 additions & 1 deletion crates/api-core/src/auth/internal_rbac_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,10 @@ impl InternalRBACRules {
x.perm("UpdateInstancePhoneHomeLastContact", vec![Agent]);
x.perm("SetHostUefiPassword", vec![ForgeAdminCLI]);
x.perm("ClearHostUefiPassword", vec![ForgeAdminCLI]);
x.perm("AddExpectedMachine", vec![ForgeAdminCLI, SiteAgent, Flow]);
x.perm(
"AddExpectedMachine",
vec![ForgeAdminCLI, SiteAgent, Flow, Machineatron],
);
x.perm("DeleteExpectedMachine", vec![ForgeAdminCLI, SiteAgent]);
x.perm("UpdateExpectedMachine", vec![ForgeAdminCLI, SiteAgent]);
x.perm("CreateExpectedMachines", vec![ForgeAdminCLI, SiteAgent]);
Expand Down
89 changes: 89 additions & 0 deletions crates/machine-a-tron/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# syntax=docker/dockerfile:1.7
#
# Cross-compilation: the BUILDER always runs NATIVE on the build host
# ($BUILDPLATFORM) and cross-compiles to x86_64-unknown-linux-gnu. This is not
# a Mac convenience: building the amd64 stage the naive way on an Apple
# Silicon host runs rustc under QEMU emulation, and QEMU SEGFAULTs assembling
# aws-lc-sys's hand-written x86-64 assembly (s2n-bignum) — even though the
# resulting binary runs fine on real x86_64. On an x86_64 build host the
# builder is simply native and the "cross" compile is a no-op.
#
# Build from the repo root:
#
# docker buildx build \
# --platform linux/amd64 \
# -f crates/machine-a-tron/Dockerfile \
# --build-arg VERSION=0.1.0 \
# -t machine-a-tron:latest \
# .
#
ARG RUST_VERSION=1.96.0

FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION}-slim-bookworm AS builder

ARG VERSION
ARG CI_COMMIT_SHORT_SHA
ENV VERSION=${VERSION}
ENV CI_COMMIT_SHORT_SHA=${CI_COMMIT_SHORT_SHA}

RUN apt-get update && apt-get install -y --no-install-recommends \
git \
pkg-config \
protobuf-compiler \
libprotobuf-dev \
&& if [ "$(uname -m)" != "x86_64" ]; then \
apt-get install -y --no-install-recommends \
gcc-x86-64-linux-gnu libc6-dev-amd64-cross; \
else \
apt-get install -y --no-install-recommends gcc libc6-dev; \
fi \
&& rm -rf /var/lib/apt/lists/*

RUN rustup target add x86_64-unknown-linux-gnu

ENV CARGO_HOME=/cargo-home
ENV CARGO_NET_GIT_FETCH_WITH_CLI=true
ENV CARGO_TARGET_DIR=/cargo-target
ENV RUST_BACKTRACE=1

WORKDIR /workspace
COPY . .

# Build release binary with cross-compilation
RUN --mount=type=cache,id=nico-mat-cross-cargo-home,target=/cargo-home,sharing=locked \
--mount=type=cache,id=nico-mat-cross-cargo-target,target=/cargo-target,sharing=locked \
if [ "$(uname -m)" != "x86_64" ]; then \
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc \
CC_x86_64_unknown_linux_gnu=x86_64-linux-gnu-gcc; \
fi && \
cargo build -p carbide-machine-a-tron --bin machine-a-tron --locked --release \
--target x86_64-unknown-linux-gnu && \
mkdir -p /artifacts && \
cp /cargo-target/x86_64-unknown-linux-gnu/release/machine-a-tron /artifacts/machine-a-tron

# Runtime image
FROM --platform=linux/amd64 debian:bookworm-slim

ARG VERSION
ARG CI_COMMIT_SHORT_SHA
LABEL org.opencontainers.image.version="${VERSION}"
LABEL org.opencontainers.image.revision="${CI_COMMIT_SHORT_SHA}"
LABEL org.opencontainers.image.title="machine-a-tron"
LABEL org.opencontainers.image.description="NICo Hardware Simulation Tool"
LABEL org.opencontainers.image.vendor="NVIDIA"

RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
iproute2 \
iputils-ping \
libssl3 \
libudev1 \
&& rm -rf /var/lib/apt/lists/*

RUN mkdir -p /opt/machine-a-tron/bin /opt/machine-a-tron/templates /tmp/machine-a-tron-data

COPY --from=builder /artifacts/machine-a-tron /opt/machine-a-tron/bin/machine-a-tron
COPY crates/machine-a-tron/templates /opt/machine-a-tron/templates

WORKDIR /opt/machine-a-tron
ENTRYPOINT ["/opt/machine-a-tron/bin/machine-a-tron"]
18 changes: 11 additions & 7 deletions dev/deployment/devspace/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ DevSpace will:

- build the local runtime images from [`Dockerfile.api`](Dockerfile.api), [`Dockerfile.bmc-proxy`](Dockerfile.bmc-proxy), and [`Dockerfile.machine-a-tron`](Dockerfile.machine-a-tron)
- build the REST API, workflow, site-manager, site-agent, database migration, certificate-manager, and MCP images from [`rest-api/docker/local`](../../../rest-api/docker/local)
- deploy the Helm chart in [`helm/`](../../../helm)
- deploy the Helm chart in [`helm/`](../../../helm) (including `nico-machine-a-tron`)
- deploy the REST umbrella, site-agent, and MCP charts in [`helm/rest`](../../../helm/rest)
- apply the local-only `machine-a-tron` Kubernetes objects from [`machine-a-tron.yaml`](machine-a-tron.yaml) with `kubectl`
- inject the built image names and DevSpace-generated tags into both deployments at runtime
Expand All @@ -109,11 +109,9 @@ The image builds are configured in [`devspace.yaml`](../../../devspace.yaml). Th

The DevSpace images also use Dockerfile-specific ignore files: [`Dockerfile.api.dockerignore`](Dockerfile.api.dockerignore), [`Dockerfile.bmc-proxy.dockerignore`](Dockerfile.bmc-proxy.dockerignore), and [`Dockerfile.machine-a-tron.dockerignore`](Dockerfile.machine-a-tron.dockerignore). This keeps the top-level [`.dockerignore`](../../../.dockerignore) aligned with the main branch for CI and release builds, while still giving the local DevSpace builds a small Docker context.

DevSpace watches the Rust workspace, toolchain metadata, and the runtime Dockerfiles to decide when images need rebuilding.
DevSpace watches the Rust workspace, toolchain metadata, and the runtime Dockerfiles to decide when images need rebuilding. On kind clusters, the pre-deploy hooks load all Core and REST images into the cluster selected by the current kube context.

The REST images use the existing local Dockerfiles and one shared per-run tag because the REST Helm charts intentionally consume a common repository and tag. On kind clusters, the pre-deploy hooks load all Core and REST images into the cluster selected by the current kube context.

The production Helm chart is still only responsible for the product services. `machine-a-tron` is deployed separately as plain local-only Kubernetes objects in [`machine-a-tron.yaml`](machine-a-tron.yaml), with DevSpace wiring in the local image tag and certificate issuer from [`devspace.yaml`](../../../devspace.yaml). The local API and BMC proxy configs in [`values.base.yaml`](values.base.yaml) point BMC traffic at `machine-a-tron-bmc-mock.nico-system.svc.cluster.local:1266`.
The `nico-machine-a-tron` Helm subchart configuration is in [`values.base.yaml`](values.base.yaml). The local API and BMC proxy configs point BMC traffic at `nico-machine-a-tron-bmc-mock.nico-system.svc.cluster.local:1266`.

Common usage:

Expand Down Expand Up @@ -163,7 +161,13 @@ docker build -t "nico-bmc-proxy:<devspace-generated-tag>" -f dev/deployment/devs
docker build -t "machine-a-tron:<devspace-generated-tag>" -f dev/deployment/devspace/Dockerfile.machine-a-tron .
```

DevSpace then deploys the Helm chart with the built `nico-api` image wired into `global.image.repository` and `global.image.tag`, the built `nico-bmc-proxy` image wired into the `nico-bmc-proxy` chart values, and applies the local-only `machine-a-tron` manifest with its image wired into the `Deployment` spec. The REST images are built from the existing `rest-api/docker/local` Dockerfiles and are passed to the three existing REST Helm charts with the same generated tag.
DevSpace then deploys the Helm chart with:
- the built `nico-api` image wired into `global.image.repository` and `global.image.tag`
- the built `nico-bmc-proxy` image wired into the `nico-bmc-proxy` chart values
- the built `machine-a-tron` image wired into the `nico-machine-a-tron` chart values
- certificate issuer settings from the DevSpace environment variables

The REST images are built from the existing `rest-api/docker/local` Dockerfiles and are passed to the three existing REST Helm charts with the same generated tag.

## Resetting the local environment

Expand All @@ -175,7 +179,7 @@ Reset the complete local environment by running:
devspace purge -n nico-system
```

When the current context is `kind-<cluster>`, the purge pipeline deletes and recreates that kind cluster with the same node image, then bootstraps clean prerequisites. This removes all Kubernetes state, including the Core and REST databases, Temporal namespaces and history, Vault data, Keycloak data, certificates, site registration, Helm releases, CRDs, and persistent volumes.
When the current context is `kind-<cluster>`, the purge pipeline deletes and recreates that kind cluster with the same node image, then bootstraps clean prerequisites. This removes all Kubernetes state, including the Core and REST databases, Temporal namespaces and history, Vault data, Keycloak data, certificates, site registration, Helm releases (including machine-a-tron), CRDs, and persistent volumes.

On any other Kubernetes context, the pipeline delegates to DevSpace's default purge behavior. It removes the deployments managed by this project without replacing the cluster or reinstalling separately managed prerequisites.

Expand Down
140 changes: 0 additions & 140 deletions dev/deployment/devspace/machine-a-tron.yaml

This file was deleted.

Loading
Loading