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
62 changes: 50 additions & 12 deletions docs/guides/native-candidate.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ Compose backend. Native support for them is planned after v5.
| External network | A top-level network sets `external: true` or `external: {name: ...}`. A reviewed `x-hack-isolated: true` replacement is not external: it creates an owned internal bridge. A network that the `HACK_NATIVE_ADAPTATION` selection (see [Frontend integration status](#frontend-integration-status)) lists in `isolatedNetworks` gets the same replacement, so it is not external either. |
| External volume | A top-level volume sets `external: true` or `external: {name: ...}`. The native runtime only creates volumes it owns, and there is no native replacement for an external volume. |
| Reserved ownership label | A service, network or volume label key starts with `com.docker.compose.`, `io.hack-local.`, `io.hack.native-config.`, `io.hack.native-file.` or `io.hack.storage-witness.`. Compose, the native runtime and native-config Compose use these labels to prove which resources they own. |
| Build outside the basic form | A service `build` is not the basic form that [`hack config import --dry-run`](../reference/native-config-import.md#pure-basic-build-preview) accepts (a relative context and optional relative `dockerfile` and `target`), or the service also sets `image`. Build arguments, secrets, SSH, cache options, platforms and other build options are outside the basic form. |
| Build outside the basic form | A service `build` is not the basic form that [`hack config import --dry-run`](../reference/native-config-import.md#pure-basic-build-preview) accepts (a relative context and optional relative `dockerfile` and `target`), or the service also sets `image`. Build arguments, secrets, SSH, cache options, platforms and other build options are outside the basic form. With `HACK_NATIVE_BUILDS=1` (see below), only a build field other than `context`, `dockerfile`, `target` and `args`, or `image` together with `build`, counts; native build admission reviews the values of those four fields itself. |
| Non-native platform | A service sets a `platform` other than `linux/arm64` or `linux/arm64/v8`, for example `linux/amd64`. The native VM runs Linux arm64 only. A missing or `null` `platform` is unset and passes. |

Native `hack up` and `hack restart` check for these features after selecting the
Expand Down Expand Up @@ -228,9 +228,45 @@ selection; see [Test both backends](https://github.com/hack-dance/hack/blob/next

Other labels keep their native behavior. Routing (`caddy*`) and dependency cache
(`hack.dependencies.*`) labels are reviewed as before, and other ordinary labels
are refused with the general native configuration refusal. A basic build is also
refused by native image-project `up`, with the general refusal: it needs the
authored native format.
are refused with the general native configuration refusal.

Native image-project `up` builds Compose `build:` services only when you opt in
with `HACK_NATIVE_BUILDS=1` (and the usual `HACK_NATIVE_SHARED_SOURCE=1`). Without
it, a `build:` service refuses before any hook or VM effect and names the variable.
With it:

- Accepted forms are `build: <context>` and a mapping of `context`, `dockerfile`,
`target` and `args`. Paths follow Compose (the context is relative to the Compose
file, the Dockerfile to the context) and must stay inside the project. `args` may be
a mapping of literal strings or numbers, or a list of `KEY=VALUE` literals. Any `$`
interpolation, a list item without `=` (host variable inheritance), `null`, other
build keys (`secrets`, `ssh`, `cache_from`, `platforms`, `network` and the rest),
remote contexts and `image` together with `build` refuse. Values are never shown.
- Build args are not secrets: as with Docker, the image records them in its history.
A build arg whose value equals a `hack env` secret value of this project and
environment refuses before any hook or VM effect, naming the service and the
argument but never the value. The refusal does not suggest the Compose backend,
because a Compose build would record the value in the image history too. Pass
secrets with BuildKit build secrets instead; native builds do not support them yet.
- Every build refusal names the service. A refusal from the runtime's build source
policy (for example a base image that is not a public Docker Hub reference) says
that it is the build source policy and what to change. Other build failures name
the service and keep the runtime's message.
- After the runtime is up, each distinct build runs once with
`runtime build-image` (below), and its filtered output streams to your terminal.
Every service with that build is then pinned to the built content ID, so review,
readiness and restore treat it like an image service.
- An existing image for the same build inputs is reused without building. Set
`HACK_NATIVE_REBUILD=1` to build again; base-image tags then resolve again too.
Edits to other files in the context do not trigger a rebuild, as with Compose.
- Restoring an unchanged retained run uses the retained images and never builds; if
one is missing, `up` refuses and asks you to start fresh. `hack restart` also never
builds: it reuses the running or retained image, or refuses before stopping anything.
- As with Compose `up`, only build services in the selected profiles are built and
pinned. A build service in a profile you did not select is not built, and restore
and restart need no image for it; selecting its profile in a later fresh `up` builds
it then. Native builds are `linux/arm64` only; `platform: linux/amd64` is still
refused.

`hack doctor` reports the same features for the current project in its
`compose backend features` check. With `--json`, the check's `composeBackend.features`
Expand Down Expand Up @@ -443,9 +479,8 @@ Provider setup is separate and explicit. Obtain the exact archives identified in
./hack-native --candidate-root /absolute/private/candidate-home runtime probe --json
```

The pins also name a BuildKit client (`buildx`, `darwin-arm64`) for future native image
builds. Native `up` still refuses `build:` services and nothing runs this client yet.
Preparing it is optional:
The pins also name a BuildKit client (`buildx`, `darwin-arm64`) for native image
builds. Prepare it before using `HACK_NATIVE_BUILDS=1`; it is optional otherwise:

```sh
./hack-native --candidate-root /absolute/private/candidate-home runtime prepare-builder --archive /absolute/docker-buildx
Expand All @@ -458,9 +493,9 @@ it again and does not replace it. If the prepared tree changes, `runtime probe`
refuses; it reports `builder_prepared` when the client is present and unchanged.

`runtime build-image --request <file> --json` builds one image in the running
runtime's engine with that client. It is a building block: native `up` still refuses
`build:` services and does not call it. The request is a private JSON file (a singly
linked, mode-`0600` file owned by you):
runtime's engine with that client. Native `up` calls it for `build:` services when
`HACK_NATIVE_BUILDS=1` is set; you can also run it directly. The request is a private
JSON file (a singly linked, mode-`0600` file owned by you):

```json
{"version": 1, "project_root": "/absolute/project", "context": "app",
Expand Down Expand Up @@ -519,8 +554,11 @@ saved run state. The report lists removed images and why each other one was kept

Before startup, network-tool preparation additionally requires all four pinned
Alpine aarch64 APKs in a current-user-owned private directory (mode `0700`), with
regular, singly linked mode-`0600` files. Acquire the matching public package bytes;
the command never downloads packages or accepts substitute versions:
regular, singly linked mode-`0600` files. The pins are the Alpine v3.19 `main`
repository for `aarch64`. Other Alpine releases, such as v3.20, publish files with
the same names but different bytes, which the command refuses. Acquire the matching
public package bytes; the command never downloads packages or accepts substitute
versions:

| File | SHA-256 |
| --- | --- |
Expand Down
4 changes: 2 additions & 2 deletions packages/runtime-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,8 @@ that does not name an owned network or `none`. Cold builds need free guest stora
(at least 6 GiB, or twice the key's last image), successful builds prune BuildKit
cache to 8 GiB, and `runtime reclaim-build-images` removes only owned, superseded,
unreferenced images (`provider/image_build/reclaim.rs`; model
`tests/models/tla/native-build-retention`). Native `up` does not call the build
operation yet.
`tests/models/tla/native-build-retention`). Native `up` calls the build operation
for Compose `build:` services only when `HACK_NATIVE_BUILDS=1` is set.

Source binaries embed their build checkout. If a copied Cargo target directory
retains a different checkout identity, use a fresh `--target-dir` for checks and
Expand Down
Loading
Loading