mirror of
https://github.com/nestriness/nestri.git
synced 2026-09-20 01:35:19 +03:00
Get this thing going..
<!-- greptile_comment -->
<!-- greptile_summary -->
<h2><a
href="https://app.greptile.com/api/retrigger?id=63134761"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=1"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=1"><img
alt="Retrigger"
src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=1"
align="right"></picture></a>Confidence Score: 5/5</h2>
The PR appears safe to merge; all previous findings are resolved and the
latest readiness change introduces no established actionable regression.
<h3>Summary</h3>
- Establishes required guest filesystems, runtime directories, device
permissions, and service processes.
- Reports initialization and service deaths over the lifecycle channel.
- Supports launch, restart, and shutdown commands for a resident guest.
- Separates service and workload identities and configures per-launch
runtime environments.
- Removes the currently inactive nescope screenshot option and makes
capture-chain verification fail explicitly when compositor readback is
unavailable.
- Reworks the guest image around `nesinit` as PID 1 without a
distribution service manager.
<h3>Diagram</h3>
```mermaid
sequenceDiagram
participant Host
participant Init as nesinit
participant FS as Guest filesystems
participant Services as Service stack
participant Workload
Init->>Host: Ready(protocol version)
Host->>Init: Boot(mount descriptors)
Init->>FS: Establish and mount shares
Init->>Services: Spawn services in order
Services-->>Init: Required sockets ready
Init->>Host: Initialized(service names)
Host->>Init: Launch(id, exec, on_exit)
Init->>Workload: Spawn with isolated UID/runtime
Init->>Host: Started(id)
Workload-->>Init: Exit status
Init->>Host: WorkloadExited(id, status)
Host->>Init: Launch / Restart / Shutdown
```
<sub>Reviews (4) · Last reviewed commit: ["fix(nesinit): readiness is a
socket
that..."](731d34df9d)</sub>
<!-- /greptile_comment -->
---------
Co-authored-by: DatCaptainHorse <DatCaptainHorse@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
100 lines
4.8 KiB
Makefile
100 lines
4.8 KiB
Makefile
SHELL := /bin/bash
|
|
.PHONY: build build-debug image image-debug proton-image proton-push clean help
|
|
|
|
CONTAINER_RT := $(shell command -v podman 2>/dev/null || command -v docker 2>/dev/null)
|
|
ifeq ($(CONTAINER_RT),)
|
|
$(error "Neither docker nor podman found in PATH")
|
|
endif
|
|
|
|
# The Containerfile COPYs from apps/ and crates/, so the build context is the
|
|
# repo root, not this directory — same reason borealis's build/ *is* its own
|
|
# context: here the guest source lives one level up instead of inside build/.
|
|
CONTEXT := ..
|
|
# `ghcr.io/nestrilabs/nestri/base` (a package name with a `/` in it, matching
|
|
# how every other image this org has published is named) is a deliberate
|
|
# name, not just a tag: this is the image other builds start FROM —
|
|
# nesbox's jailer image extracts Mesa/virgl from it to keep the guest and
|
|
# host sides of the virtio-gpu native-context protocol on the same patched
|
|
# Mesa, and closed downstream builds layer Proton/Steam on top of it
|
|
# elsewhere. `runtime_prod`/`runtime_debug` already are exactly that: distro
|
|
# packages plus our own Mesa/nestri artifacts overlaid on top, nothing
|
|
# stripped that a downstream COPY --from= would miss — no separate
|
|
# unstripped tag is needed for this.
|
|
#
|
|
# The registry host is part of the name on purpose, including for local
|
|
# builds: a bare `nestrilabs/nestri` has no host, so anyone who pulls
|
|
# instead of building locally resolves it against Docker Hub by default,
|
|
# where it does not exist. One name, always pullable, beats a local-only
|
|
# short name and a different published one.
|
|
IMAGE_NAME := ghcr.io/nestrilabs/nestri/base
|
|
|
|
# Proton is the one artifact worth publishing on its own: it takes hours to
|
|
# build and changes only when its tag moves, so the guest build pulls it by
|
|
# name instead of rebuilding it.
|
|
#
|
|
# `PROTON_TAG` is the single place to change it. The published version is
|
|
# derived from the tag rather than written twice, because the two are the same
|
|
# number in two spellings and an image whose name does not say which Proton is
|
|
# inside it is worse than no image at all. Changing the tag by hand and
|
|
# forgetting the version is exactly the mistake this removes.
|
|
PROTON_TAG ?= cachyos-11.0-20260703-native
|
|
PROTON_VERSION := $(PROTON_TAG:cachyos-%-native=%)
|
|
PROTON_IMAGE ?= ghcr.io/nestrilabs/proton-cachyos-native-wow64
|
|
PROTON_REF := $(PROTON_IMAGE):$(PROTON_VERSION)
|
|
OUTPUT_DIR := output
|
|
ROOTFS_SIZE ?= 3G
|
|
FORCE_REBUILD ?=
|
|
|
|
build:
|
|
DOCKER_BUILDKIT=1 $(CONTAINER_RT) build $(if $(FORCE_REBUILD),--no-cache,) \
|
|
--build-arg PROTON_IMAGE=$(PROTON_REF) \
|
|
-f Containerfile -t $(IMAGE_NAME):latest --target runtime_prod $(CONTEXT)
|
|
|
|
build-debug:
|
|
DOCKER_BUILDKIT=1 $(CONTAINER_RT) build $(if $(FORCE_REBUILD),--no-cache,) \
|
|
--build-arg PROTON_IMAGE=$(PROTON_REF) \
|
|
-f Containerfile -t $(IMAGE_NAME):debug --target runtime_debug $(CONTEXT)
|
|
|
|
# Hours, and only when PROTON_TAG moves. Its context is this directory rather
|
|
# than the repository root: the two scripts beside the Containerfile are the
|
|
# whole input, and the root would hand it everything else for nothing.
|
|
proton-image:
|
|
DOCKER_BUILDKIT=1 $(CONTAINER_RT) build $(if $(FORCE_REBUILD),--no-cache,) \
|
|
--build-arg PROTON_TAG=$(PROTON_TAG) \
|
|
-f Containerfile.proton -t $(PROTON_REF) .
|
|
@echo "Built $(PROTON_REF)"
|
|
|
|
# Publishing is what makes `make build` cheap for everyone else, since that
|
|
# build pulls this by name. Push before expecting anyone to use a new tag.
|
|
proton-push: proton-image
|
|
$(CONTAINER_RT) push $(PROTON_REF)
|
|
|
|
# Not `sudo make image`/sudo'd in here: mkimage.sh runs as you and escalates
|
|
# only the specific commands that need root. Under rootless Podman, `make
|
|
# build` stores the image in *your* storage — sudo-ing the whole script would
|
|
# have root's podman look for that tag in its own, separate storage and fail
|
|
# to find it.
|
|
image: build
|
|
@mkdir -p $(OUTPUT_DIR)
|
|
bash scripts/mkimage.sh $(IMAGE_NAME):latest $(OUTPUT_DIR)/rootfs.ext4 $(ROOTFS_SIZE)
|
|
|
|
image-debug: build-debug
|
|
@mkdir -p $(OUTPUT_DIR)
|
|
bash scripts/mkimage.sh $(IMAGE_NAME):debug $(OUTPUT_DIR)/rootfs-debug.ext4 $(ROOTFS_SIZE)
|
|
|
|
clean:
|
|
rm -rf $(OUTPUT_DIR)
|
|
|
|
help:
|
|
@echo "Usage:"
|
|
@echo " make build Build the runtime_prod container image"
|
|
@echo " make build-debug Build the runtime_debug container image"
|
|
@echo " make image Build + pack runtime_prod into output/rootfs.ext4"
|
|
@echo " make image-debug Build + pack runtime_debug into output/rootfs-debug.ext4"
|
|
@echo " make clean Remove output/"
|
|
@echo " make proton-image Build Proton from source (hours)"
|
|
@echo " make proton-push Build it and publish it"
|
|
@echo " make FORCE_REBUILD=1 ... Rebuild from scratch, no layer cache"
|
|
@echo " make PROTON_TAG=... ... Use a different proton-cachyos tag"
|
|
@echo " make ROOTFS_SIZE=8G image Override the packed image size (default 5G)"
|