mirror of
https://github.com/commaai/agnos-builder.git
synced 2026-08-21 16:23:53 +08:00
vibing alpine
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
# Alpine Migration Plan (Draft 1)
|
||||
|
||||
## What We Have Today
|
||||
- `build_system.sh` pulls `ubuntu-base-24.04.3-base-arm64.tar.gz`, loads it into `Dockerfile.agnos`, and bakes the final `system.img`.
|
||||
- `Dockerfile.agnos` and `userspace/*.sh` assume Ubuntu/Debian tooling: `apt-fast`, `dpkg`, `.deb` blobs in `userspace/debs`, and systemd units in `userspace/files`.
|
||||
- `Dockerfile.builder` is an Ubuntu 20.04 helper image that mounts the workspace and provides build-essential tools.
|
||||
- Services are managed exclusively with systemd (`userspace/services.sh`), and dozens of `*.service`/`*.timer` files are copied into `/lib/systemd/system`.
|
||||
|
||||
The goal: swap the Ubuntu base for Alpine while keeping device functionality (openpilot, hardware services, flashing) unchanged.
|
||||
|
||||
## Guiding Principles
|
||||
1. **Parallelize, don’t destabilize.** Leave the Ubuntu build path untouched; all Alpine work happens in new `build_alpine.sh`, `Dockerfile.alpine`, etc., until we prove parity.
|
||||
2. **Change one layer at a time.** Migrate builder tooling before touching the rootfs so failures are easy to bisect.
|
||||
3. **Stay reproducible.** Every replacement must be scripted (no manual `apk add` on a live device).
|
||||
4. **Prefer rebuilding from source.** Debian-only `.deb` artifacts (qtwayland5, modemmanager, etc.) should become source builds or Alpine `apk`s.
|
||||
5. **Keep service semantics.** Whether we keep systemd on Alpine or port to OpenRC must be decided up front and applied consistently.
|
||||
|
||||
## Phase A – Minimal Alpine Bring-up (Parallel Path)
|
||||
Goal: produce a new `build_alpine.sh` that builds a tiny Alpine-based rootfs, flashes separately, boots to userspace, and runs `usr/comma/magic.py` to show the logo. Existing Ubuntu images/scripts remain the default.
|
||||
|
||||
1. [x] Create `Dockerfile.alpine` that starts from the Alpine minirootfs and installs just enough to boot OpenRC and launch the logo service.
|
||||
2. [x] Clone `build_system.sh` into `build_alpine.sh`. Adjust it to:
|
||||
- Download `alpine-minirootfs-<ver>-aarch64.tar.gz`.
|
||||
- Use new Alpine docker build to produce a `system-alpine.img`.
|
||||
- Keep all outputs in `output/alpine/` so it doesn’t collide with Ubuntu artifacts.
|
||||
3. [ ] Inside the Alpine image:
|
||||
- [x] Configure networking basics, hostname, and ensure `/usr/comma` is copied from the existing repository.
|
||||
- [x] Install just enough packages (`python3`, `py3-pip`, DRM/mesa bits) plus pip-install `pyray` for `magic.py`.
|
||||
- [x] Create an OpenRC service (`/etc/init.d/magic`) that launches `/usr/comma/magic.py` on boot and streams logs to `/var/log/magic.log`.
|
||||
- [ ] Validate on real hardware (or QEMU once GPU path is mocked) that the logo shows and backlight powers on.
|
||||
4. [x] Add a simple smoke test stub (`test_alpine_magic.sh`) describing how to exercise the image until automation exists.
|
||||
5. [ ] Document how to invoke the new flow in `README.md` (later) but keep it optional until feature-complete.
|
||||
|
||||
## Phase 0 – Recon & Prep
|
||||
1. [ ] Pin an Alpine release (3.20 or edge) that ships `aarch64` and `armv7` repos; record mirror URLs.
|
||||
2. [ ] List every Ubuntu package we install (`userspace/base_setup.sh`, `openpilot_dependencies.sh`, `install_extras.sh`, etc.) and mark whether Alpine has an equivalent `apk`, needs a community repo, or must be built from source.
|
||||
3. [ ] Inventory `.deb` blobs in `userspace/debs`, `userspace/qtwayland`, compiler stages, and note which ones rely on glibc symbols.
|
||||
4. [ ] Decide init strategy:
|
||||
- Option A: keep systemd (build it from source on Alpine + run in PID1).
|
||||
- Option B: switch to OpenRC (rewrite service units + helper scripts).
|
||||
Document the choice because it impacts almost every script.
|
||||
5. [ ] Confirm musl vs glibc requirements. If any binary *must* stay glibc-linked (e.g., Qualcomm blobs), plan to add the `gcompat`/`alpine-pkg-glibc` shim or run those pieces inside a glibc sysroot.
|
||||
|
||||
## Phase 1 – Alpine Builder Container (new `Dockerfile.builder.alpine`)
|
||||
1. [ ] Copy `Dockerfile.builder` to `Dockerfile.builder.alpine`; base the new file on `alpine:<version>` while leaving the Ubuntu original intact.
|
||||
2. [ ] Swap `apt-get` for `apk add --no-cache` and install Alpine equivalents (`build-base`, `clang`, `openssl`, `ccache`, `android-tools`, `py3` packages, etc.).
|
||||
3. [ ] Ensure `python2` requirement is gone or solved (Alpine only ships `python3`; if python2 is still needed, vendor it from source).
|
||||
4. [ ] Re-implement the user-mapping logic using BusyBox `addgroup/adduser` syntax.
|
||||
5. [ ] Verify `ccache` symlink setup still works and that `docker buildx --load` succeeds when `build_alpine.sh` references the new Dockerfile.
|
||||
|
||||
## Phase 2 – Alpine Rootfs Source (`build_alpine.sh`)
|
||||
1. [ ] Copy `build_system.sh` to `build_alpine.sh` so the Ubuntu path remains unchanged.
|
||||
2. [ ] Replace Ubuntu download variables with Alpine ones (use `alpine-minirootfs-<ver>-aarch64.tar.gz`) and update the SHA.
|
||||
3. [ ] Wire `build_alpine.sh` to call the Alpine Dockerfile and emit outputs under `build/alpine/` + `output/alpine/`.
|
||||
4. [ ] Drop `debconf`, `dpkg`, and `apt` assumptions as soon as the Alpine tarball is extracted; Alpine already has `apk-tools`.
|
||||
5. [ ] Confirm `qemu-user-static` still handles musl binaries when running on x86_64 hosts.
|
||||
6. [ ] Validate that `img2simg` + ext4 creation stays the same (filesystem layer is independent of distro).
|
||||
|
||||
## Phase 3 – Userspace & Package Installation (Alpine variants live beside Ubuntu)
|
||||
1. **Agnos compiler stages**
|
||||
- [ ] Duplicate `Dockerfile.agnos` or split it into named targets so the Alpine build stages live alongside the Ubuntu ones without altering them.
|
||||
- [ ] Change all Alpine stages to `FROM alpine`. Install build deps via `apk` (`alpine-sdk`, `cmake`, `ninja`, etc.).
|
||||
- [ ] Audit `compile-*.sh` scripts for `apt-get`, `ldconfig`, `/usr/lib/aarch64-linux-gnu` assumptions; rewrite paths for Alpine (`/usr/lib`, `/lib`).
|
||||
- [ ] Replace `checkinstall`-generated `.deb` outputs with either plain tarballs or ad-hoc `.apk` packages (use `abuild` or `apkbuild` templates).
|
||||
2. **Base setup (`userspace/base_setup.sh`)**
|
||||
- [ ] Add `userspace/base_setup_alpine.sh` (leave the Ubuntu script alone). Use `/etc/apk/repositories` plus `apk update && apk add`.
|
||||
- [ ] Recreate required system users/groups using BusyBox tools.
|
||||
- [ ] Re-map package names (e.g., `build-essential` → `build-base`, `network-manager` → `NetworkManager` from the community repo, `iptables-persistent` → `iptables` + manual save).
|
||||
- [ ] Handle 32-bit deps: Alpine’s `aarch64` repo does **not** support mixing `armhf` packages. Decide between cross-compiling needed 32-bit libs from source or hosting a parallel `armv7` sysroot mounted under `/lib32`.
|
||||
- [ ] Replace `locale-gen`/`update-locale` with Alpine equivalents (`/etc/profile.d/locale.sh`, `glibc-i18n` if using glibc shim, or `musl-locales`).
|
||||
3. **Openpilot deps (`userspace/openpilot_dependencies.sh`, `openpilot_python_dependencies.sh`)**
|
||||
- [ ] Provide Alpine siblings of these scripts and translate each dependency to `apk` packages or source builds. For tools missing on Alpine, extend the compiler stages.
|
||||
- [ ] Ensure `uv` install script runs on musl (needs `build-base`, `curl`, `python3`).
|
||||
4. **Hardware setup & proprietary debs**
|
||||
- [ ] For each `.deb` in `userspace/debs`, extract it (`dpkg-deb -x`) and repackage the payload into the Alpine rootfs manually or via custom `apk`s.
|
||||
- [ ] Verify Qualcomm binaries only depend on glibc symbols that exist in your shim (or keep a glibc chroot mounted under `/usr/glibc`).
|
||||
- [ ] Replace `apt install libjson-c2` hack with either an Alpine package or a source build pinned to the required ABI.
|
||||
5. **Service management**
|
||||
- [ ] If staying with systemd: build systemd against musl (supported as of v253) and ensure `pam`, `udev`, and `resolved` pieces still work. Double-check `systemctl` invocations in `userspace/services.sh`.
|
||||
- [ ] If moving to OpenRC: convert every `.service`, `.timer`, `.path` file into OpenRC services; rewrite `userspace/services.sh` to call `rc-update`. Confirm replacements for `systemd-tmpfiles`, `journald`, and `networkd` (likely use `busybox-ntpd`, `rsyslog`, and `NetworkManager`).
|
||||
6. **Filesystem layout differences**
|
||||
- [ ] Alpine does not use `/lib/systemd/system` or `/usr/lib/aarch64-linux-gnu`; adjust copy paths only in the Alpine Dockerfile variant.
|
||||
- [ ] Revisit `readonly_setup.sh`: drop `apt` cache cleanup, ensure `/etc/localtime` logic matches Alpine’s `/etc/TZ`/`/etc/timezone` expectations.
|
||||
|
||||
## Phase 4 – Image Assembly & Flash Scripts
|
||||
1. [ ] Introduce `load_alpine*.sh` and `flash_alpine*.sh` companions instead of rewriting the Ubuntu scripts; point them at the new image names.
|
||||
2. [ ] Ensure the Alpine image writes its own `/VERSION` metadata (maybe `VERSION_ALPINE` or embed in `VERSION`).
|
||||
3. [ ] Re-run size optimization (Alpine is smaller; re-tune `ROOTFS_IMAGE_SIZE` specifically for the Alpine build).
|
||||
4. [ ] Verify `readonly_setup.sh` + `mv /var /usr/default` still behave; Alpine may ship busybox `mv` without `-T`, so test carefully.
|
||||
|
||||
## Phase 5 – Validation
|
||||
1. [ ] First milestone: boot the Alpine image and verify `/usr/comma/magic.py` auto-runs and shows the logo.
|
||||
2. [ ] Full milestone: boot the new image on comma 3/3X; confirm kernel + modem + UI stack.
|
||||
3. [ ] Run the existing `TESTING.md` checklist plus:
|
||||
- `apk` database integrity (`apk info -vv | head`).
|
||||
- Services status via the new init system.
|
||||
- Openpilot runtime smoke test.
|
||||
4. [ ] Exercise flashing (`flash_alpine*.sh`) end-to-end on at least one device.
|
||||
5. [ ] Document any remaining Ubuntu assumptions and either fix or log issues for follow-up.
|
||||
|
||||
## Open Questions & Risks
|
||||
- **glibc-only blobs:** If Qualcomm or Weston hacks require glibc, we need either a glibc compatibility layer or to keep those pieces in a Debian chroot.
|
||||
- **Systemd vs OpenRC:** Porting dozens of custom services may dwarf other work; validate effort before committing.
|
||||
- **Multi-arch libraries:** Alpine currently lacks an easy way to install `armhf` packages alongside `aarch64`. Plan for source builds or rethink the need for 32-bit libs.
|
||||
- **CI coverage:** GitHub Actions runners may not have `apk` tooling; ensure CI images are updated before merging.
|
||||
|
||||
> Next iteration: once we lock the init strategy and package availability, we can expand each checkbox into concrete scripts/commands.
|
||||
@@ -0,0 +1,82 @@
|
||||
# check=error=true
|
||||
|
||||
ARG ALPINE_VERSION=3.20.8
|
||||
|
||||
# ############### #
|
||||
# ### Minimal ### #
|
||||
# ### Alpine ### #
|
||||
# ############### #
|
||||
FROM scratch AS agnos-alpine
|
||||
|
||||
ARG ALPINE_BASE_IMAGE
|
||||
ARG USERNAME=comma
|
||||
|
||||
ADD ${ALPINE_BASE_IMAGE} /
|
||||
|
||||
SHELL ["/bin/sh", "-c"]
|
||||
ENV PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=1 \
|
||||
PYTHONUNBUFFERED=1
|
||||
|
||||
# Base packages just for the magic logo proof-of-concept
|
||||
RUN set -eux; \
|
||||
apk update; \
|
||||
apk add --no-cache \
|
||||
bash \
|
||||
ca-certificates \
|
||||
coreutils \
|
||||
curl \
|
||||
eudev \
|
||||
libdrm \
|
||||
libinput \
|
||||
mesa-dri-gallium \
|
||||
mesa-egl \
|
||||
mesa-gbm \
|
||||
mesa-gl \
|
||||
musl-locales \
|
||||
openrc \
|
||||
python3 \
|
||||
py3-pillow \
|
||||
py3-pip \
|
||||
py3-psutil \
|
||||
py3-setuptools \
|
||||
shadow \
|
||||
sudo \
|
||||
ttf-dejavu
|
||||
|
||||
# python deps that require a compiler (kept isolated so we can delete the toolchain afterwards)
|
||||
RUN set -eux; \
|
||||
apk add --no-cache --virtual .magic-build-deps \
|
||||
build-base \
|
||||
linux-headers \
|
||||
python3-dev; \
|
||||
pip3 install --no-cache-dir --break-system-packages pyray; \
|
||||
apk del .magic-build-deps
|
||||
|
||||
# Create comma user
|
||||
RUN set -eux; \
|
||||
addgroup -g 1000 "${USERNAME}" || true; \
|
||||
adduser -D -G "${USERNAME}" -u 1000 -s /bin/bash -h "/home/${USERNAME}" "${USERNAME}" || true; \
|
||||
echo "${USERNAME}:${USERNAME}" | chpasswd; \
|
||||
adduser "${USERNAME}" video; \
|
||||
adduser "${USERNAME}" input; \
|
||||
adduser "${USERNAME}" dialout; \
|
||||
mkdir -p /data /var/tmp/weston; \
|
||||
chown "${USERNAME}:${USERNAME}" /data /var/tmp/weston /home/${USERNAME}
|
||||
|
||||
# Copy minimal comma payload (logo assets + helper scripts)
|
||||
COPY userspace/usr/comma /usr/comma
|
||||
RUN chown -R "${USERNAME}:${USERNAME}" /usr/comma && \
|
||||
chmod +x /usr/comma/*.sh || true
|
||||
|
||||
# Install OpenRC service that drives magic.py
|
||||
COPY userspace/alpine/magic.init /etc/init.d/magic
|
||||
RUN chmod 0755 /etc/init.d/magic && \
|
||||
rc-update add magic default
|
||||
|
||||
# Basic runtime directories
|
||||
RUN mkdir -p /run/magic && \
|
||||
chown "${USERNAME}:${USERNAME}" /run/magic
|
||||
|
||||
# Default entrypoint: boot OpenRC like a normal system
|
||||
CMD ["/sbin/init"]
|
||||
Executable
+137
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ALPINE_VERSION="${ALPINE_VERSION:-3.20.8}"
|
||||
ALPINE_SERIES="$(echo "$ALPINE_VERSION" | awk -F. '{printf "%s.%s", $1, $2}')"
|
||||
ALPINE_BASE_URL="https://dl-cdn.alpinelinux.org/alpine/v${ALPINE_SERIES}/releases/aarch64"
|
||||
ALPINE_FILE="alpine-minirootfs-${ALPINE_VERSION}-aarch64.tar.gz"
|
||||
ALPINE_FILE_CHECKSUM="${ALPINE_FILE_CHECKSUM:-6d0e15d9f9f5c5003c4692337dffebe9475cab7d8a0390f109f6999fbb28745f}"
|
||||
|
||||
# Ensure we are inside the repo root
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd "$DIR"
|
||||
|
||||
BUILD_DIR="$DIR/build/alpine"
|
||||
OUTPUT_DIR="$DIR/output/alpine"
|
||||
|
||||
ROOTFS_DIR="$BUILD_DIR/rootfs"
|
||||
ROOTFS_IMAGE="$BUILD_DIR/system-alpine.img"
|
||||
OUT_IMAGE="$OUTPUT_DIR/system-alpine.img"
|
||||
|
||||
ROOTFS_IMAGE_SIZE="${ROOTFS_IMAGE_SIZE:-2048M}"
|
||||
|
||||
mkdir -p "$BUILD_DIR" "$OUTPUT_DIR"
|
||||
|
||||
# Download Alpine minirootfs if missing
|
||||
if [ ! -f "$ALPINE_FILE" ]; then
|
||||
echo "Downloading Alpine minirootfs: $ALPINE_FILE"
|
||||
if ! curl -C - -o "$ALPINE_FILE" "$ALPINE_BASE_URL/$ALPINE_FILE" --silent --remote-time --fail; then
|
||||
echo "Download failed, please check Alpine releases: $ALPINE_BASE_URL"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Verify checksum
|
||||
if [ "$(shasum -a 256 "$ALPINE_FILE" | awk '{print $1}')" != "$ALPINE_FILE_CHECKSUM" ]; then
|
||||
echo "Checksum mismatch, please check Alpine releases: $ALPINE_BASE_URL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Register qemu user emulation if needed
|
||||
if [ "$(uname -m)" = "x86_64" ]; then
|
||||
echo "Registering qemu-user-static"
|
||||
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes > /dev/null
|
||||
fi
|
||||
|
||||
export DOCKER_BUILDKIT=1
|
||||
|
||||
echo "Checking Dockerfile.alpine"
|
||||
docker buildx build -f Dockerfile.alpine --check "$DIR" \
|
||||
--build-arg ALPINE_VERSION="$ALPINE_VERSION" \
|
||||
--build-arg ALPINE_BASE_IMAGE="$ALPINE_FILE"
|
||||
|
||||
echo "Building Alpine system image"
|
||||
BUILD_CMD="docker buildx build --load"
|
||||
if [ -n "${NS:-}" ]; then
|
||||
BUILD_CMD="nsc build --load"
|
||||
fi
|
||||
$BUILD_CMD -f Dockerfile.alpine -t agnos-alpine "$DIR" \
|
||||
--build-arg ALPINE_VERSION="$ALPINE_VERSION" \
|
||||
--build-arg ALPINE_BASE_IMAGE="$ALPINE_FILE" \
|
||||
--platform=linux/arm64
|
||||
|
||||
echo "Creating agnos-alpine container"
|
||||
CONTAINER_ID=$(docker container create --entrypoint /bin/sh agnos-alpine:latest)
|
||||
|
||||
echo "Checking meta-builder Dockerfile"
|
||||
docker buildx build --load -f Dockerfile.builder --check "$DIR" \
|
||||
--build-arg UNAME="$(id -nu)" \
|
||||
--build-arg UID="$(id -u)" \
|
||||
--build-arg GID="$(id -g)"
|
||||
|
||||
echo "Building meta-builder"
|
||||
docker buildx build --load -f Dockerfile.builder -t agnos-meta-builder "$DIR" \
|
||||
--build-arg UNAME="$(id -nu)" \
|
||||
--build-arg UID="$(id -u)" \
|
||||
--build-arg GID="$(id -g)"
|
||||
|
||||
echo "Starting meta-builder container"
|
||||
MOUNT_CONTAINER_ID=$(docker run -d --privileged -v "$DIR:$DIR" agnos-meta-builder)
|
||||
|
||||
cleanup() {
|
||||
echo "Cleaning up containers:"
|
||||
docker container rm -f "$CONTAINER_ID" "$MOUNT_CONTAINER_ID" > /dev/null
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
exec_as_user() {
|
||||
docker exec -u "$(id -nu)" "$MOUNT_CONTAINER_ID" "$@"
|
||||
}
|
||||
|
||||
exec_as_root() {
|
||||
docker exec "$MOUNT_CONTAINER_ID" "$@"
|
||||
}
|
||||
|
||||
echo "Creating sparse filesystem"
|
||||
exec_as_user mkdir -p "$BUILD_DIR"
|
||||
exec_as_user fallocate -l "$ROOTFS_IMAGE_SIZE" "$ROOTFS_IMAGE"
|
||||
exec_as_user mkfs.ext4 "$ROOTFS_IMAGE" > /dev/null
|
||||
|
||||
echo "Mounting filesystem"
|
||||
exec_as_root mkdir -p "$ROOTFS_DIR"
|
||||
exec_as_root mount "$ROOTFS_IMAGE" "$ROOTFS_DIR"
|
||||
|
||||
cleanup_with_umount() {
|
||||
exec_as_root umount -l "$ROOTFS_DIR" > /dev/null 2>&1 || true
|
||||
cleanup
|
||||
}
|
||||
trap cleanup_with_umount EXIT
|
||||
|
||||
echo "Extracting container filesystem"
|
||||
docker container export -o "$BUILD_DIR/filesystem.tar" "$CONTAINER_ID"
|
||||
exec_as_root tar -xf "$BUILD_DIR/filesystem.tar" -C "$ROOTFS_DIR" > /dev/null
|
||||
|
||||
echo "Removing container markers"
|
||||
exec_as_root rm -f "$ROOTFS_DIR/.dockerenv"
|
||||
|
||||
echo "Configuring hostname and networking files"
|
||||
set_network_stuff() {
|
||||
cd "$ROOTFS_DIR"
|
||||
HOST=comma
|
||||
ln -sf /proc/sys/kernel/hostname etc/hostname
|
||||
echo "127.0.0.1 localhost.localdomain localhost" > etc/hosts
|
||||
echo "127.0.0.1 $HOST" >> etc/hosts
|
||||
ln -sf /run/network/resolv.conf etc/resolv.conf
|
||||
DATETIME=$(date '+%Y-%m-%dT%H:%M:%S')
|
||||
printf "%s\n%s\n" "$GIT_HASH" "$DATETIME" > BUILD
|
||||
}
|
||||
GIT_HASH=${GIT_HASH:-$(git --git-dir="$DIR/.git" rev-parse HEAD)}
|
||||
exec_as_root bash -c "set -e; export ROOTFS_DIR=\"$ROOTFS_DIR\" GIT_HASH=\"$GIT_HASH\"; $(declare -f set_network_stuff); set_network_stuff"
|
||||
|
||||
echo "Unmounting filesystem"
|
||||
exec_as_root umount -l "$ROOTFS_DIR"
|
||||
|
||||
echo "Sparsifying image"
|
||||
exec_as_user img2simg "$ROOTFS_IMAGE" "$OUT_IMAGE"
|
||||
|
||||
echo "Alpine image written to $OUT_IMAGE"
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
IMAGE_PATH="${1:-output/alpine/system-alpine.img}"
|
||||
|
||||
if [ ! -f "$IMAGE_PATH" ]; then
|
||||
echo "Missing $IMAGE_PATH"
|
||||
echo "Build it first with ./build_alpine.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
Alpine splash image ready at: $IMAGE_PATH
|
||||
|
||||
Manual smoke test until automation exists:
|
||||
1. Flash the image to a spare comma 3/3X or boot it in your preferred ARM64 VM.
|
||||
2. Let the device boot normally. OpenRC should launch /usr/comma/magic.py automatically.
|
||||
3. Verify the comma logo (bg.jpg) appears and the backlight turns on.
|
||||
4. If it does not, capture /var/log/magic.log from the device and file an issue.
|
||||
EOF
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/sbin/openrc-run
|
||||
|
||||
description="Render the comma boot logo with magic.py"
|
||||
command="/usr/bin/python3"
|
||||
command_args="/usr/comma/magic.py"
|
||||
command_user="comma"
|
||||
command_group="comma"
|
||||
command_background="true"
|
||||
pidfile="/run/magic/magic.pid"
|
||||
start_stop_daemon_args="--make-pidfile --stdout /var/log/magic.log --stderr /var/log/magic.log"
|
||||
supervisor="supervise-daemon"
|
||||
respawn_delay="2"
|
||||
respawn_max="0"
|
||||
|
||||
depend() {
|
||||
need localmount
|
||||
use net
|
||||
after modules
|
||||
}
|
||||
|
||||
start_pre() {
|
||||
checkpath --directory --mode 0755 --owner ${command_user}:${command_group} /var/log
|
||||
checkpath --file --mode 0644 --owner ${command_user}:${command_group} /var/log/magic.log
|
||||
checkpath --directory --mode 0755 --owner ${command_user}:${command_group} /var/tmp/weston
|
||||
}
|
||||
Reference in New Issue
Block a user