From 6a8be734f3a1b11839edcbcecf56b73cbf9b836f Mon Sep 17 00:00:00 2001 From: "Michal S." Date: Thu, 6 Aug 2026 10:26:36 +0100 Subject: [PATCH] Replace pkgsrc and mdevd with mouse ports desktop base --- .gitattributes | 1 + Containerfile | 193 +++- Makefile | 32 +- README.md | 55 +- TODO.md | 4 + base/cheesed/scripts/build-static.sh | 10 +- base/cheesed/src/linux/boot.rs | 50 +- base/kernel/aarch64.config | 146 +++ base/kernel/x86_64.config | 66 +- base/limine.conf | 3 +- base/patches/pkgsrc-bootstrap-mouse.patch | 13 - ...subr-cgroup.patch => rc.subr-cgroup.patch} | 0 base/patches/shadow-4.20.0-stdint.patch | 18 + .../wpa-supplicant-2.11-openssl-4.patch | 64 ++ base/rootfs/etc/doas.conf | 1 + base/rootfs/etc/group | 17 + base/rootfs/etc/hostname | 2 +- base/rootfs/etc/mdev.conf | 13 - base/rootfs/etc/motd | 2 +- base/rootfs/etc/mouse-release | 2 +- base/rootfs/etc/passwd | 2 + base/rootfs/etc/rc.conf | 4 + base/rootfs/etc/rc.d/console_login | 4 +- base/rootfs/etc/rc.d/gardendevd | 25 + base/rootfs/etc/rc.d/mdevd | 11 - base/rootfs/etc/rc.d/network | 14 - base/rootfs/etc/rc.d/wpa_supplicant | 12 + base/rootfs/etc/rc.subr | 1008 +++++++++++++++++ base/rootfs/etc/securetty | 2 +- base/rootfs/etc/shadow | 6 +- .../etc/wpa_supplicant/wpa_supplicant.conf | 2 + base/rootfs/usr/lib/mouse/required-services | 1 - base/rootfs/usr/libexec/mouse-wpa-supplicant | 21 + base/support/cross-compiler-driver | 11 +- base/support/mouse-auth.c | 118 ++ base/support/mouse-package | 84 ++ base/support/rust-eh-personality.c | 5 +- release/autotools.lock | 5 + release/device-firmware.lock | 2 + release/facilities.lock | 2 +- release/firmware.lock | 1 + release/kernel.lock | 2 +- release/pkgsrc.lock | 2 - release/software.lock | 32 +- release/storage.lock | 4 +- release/toolchain.lock | 2 +- release/wireless.lock | 3 + scripts/audit-static-base.sh | 42 +- scripts/build-boot-disk.sh | 46 +- scripts/build-btrfs-image-tool.sh | 22 + scripts/build-image-commands.sh | 15 +- scripts/build-image.sh | 133 ++- scripts/build-in-container.sh | 62 +- scripts/build-kernel-test-module.sh | 7 +- scripts/build-kernel.sh | 27 +- scripts/build-mouse-ports-seed.sh | 85 ++ scripts/build-pkgsrc-seed.sh | 89 -- scripts/build-world-autotools.sh | 136 +++ scripts/check-source-locks.sh | 63 +- scripts/configure-cross-toolchain.sh | 4 +- scripts/extract-build-firmware.sh | 23 + scripts/fetch-sources.sh | 82 +- scripts/mouse-arch.sh | 94 ++ scripts/run-qemu.sh | 60 +- scripts/static-base/bootstrap.sh | 123 +- scripts/static-base/common.sh | 15 +- scripts/static-base/dynamic-runtime.sh | 31 +- scripts/static-base/facilities.sh | 55 +- scripts/static-base/libraries-and-accounts.sh | 52 +- scripts/static-base/native-toolchain.sh | 36 +- scripts/static-base/storage.sh | 9 +- scripts/static-base/system-services.sh | 91 +- scripts/static-base/wireless.sh | 65 ++ tests/acceptance/admin.exp | 56 + tests/acceptance/admin.sh | 10 + tests/acceptance/boot.exp | 15 +- tests/acceptance/boot.sh | 2 +- tests/acceptance/btrfs.exp | 6 +- tests/acceptance/firmware.exp | 9 +- tests/acceptance/firmware.sh | 24 +- tests/acceptance/harness.sh | 3 +- tests/acceptance/multi-user.exp | 22 +- tests/acceptance/network.exp | 8 +- tests/acceptance/pkgsrc.exp | 66 -- tests/acceptance/pkgsrc.sh | 33 - tests/acceptance/service-integration.exp | 12 +- tests/acceptance/storage.exp | 4 +- tests/acceptance/toolchain.exp | 42 +- tests/acceptance/world.exp | 10 +- tests/acceptance/world.sh | 2 +- .../pkgsrc/distfiles/mouse-hello-1.0.c | 8 - tests/fixtures/pkgsrc/local/mouse-hello/DESCR | 2 - .../pkgsrc/local/mouse-hello/Makefile | 26 - tests/fixtures/pkgsrc/local/mouse-hello/PLIST | 3 - .../pkgsrc/local/mouse-hello/distinfo | 5 - .../mouse-hello/files/mouse-hello-service | 16 - .../local/mouse-hello/files/mouse_hello.sh | 11 - 97 files changed, 3129 insertions(+), 810 deletions(-) create mode 100644 .gitattributes create mode 100644 TODO.md create mode 100644 base/kernel/aarch64.config delete mode 100644 base/patches/pkgsrc-bootstrap-mouse.patch rename base/patches/{pkgsrc-rc.subr-cgroup.patch => rc.subr-cgroup.patch} (100%) create mode 100644 base/patches/shadow-4.20.0-stdint.patch create mode 100644 base/patches/wpa-supplicant-2.11-openssl-4.patch create mode 100644 base/rootfs/etc/doas.conf delete mode 100644 base/rootfs/etc/mdev.conf create mode 100644 base/rootfs/etc/rc.d/gardendevd delete mode 100644 base/rootfs/etc/rc.d/mdevd create mode 100644 base/rootfs/etc/rc.d/wpa_supplicant create mode 100644 base/rootfs/etc/rc.subr create mode 100644 base/rootfs/etc/wpa_supplicant/wpa_supplicant.conf create mode 100644 base/rootfs/usr/libexec/mouse-wpa-supplicant create mode 100644 base/support/mouse-auth.c create mode 100755 base/support/mouse-package create mode 100644 release/autotools.lock create mode 100644 release/device-firmware.lock delete mode 100644 release/pkgsrc.lock create mode 100644 release/wireless.lock create mode 100755 scripts/build-btrfs-image-tool.sh create mode 100755 scripts/build-mouse-ports-seed.sh delete mode 100755 scripts/build-pkgsrc-seed.sh create mode 100755 scripts/build-world-autotools.sh create mode 100755 scripts/extract-build-firmware.sh create mode 100644 scripts/mouse-arch.sh create mode 100644 scripts/static-base/wireless.sh create mode 100755 tests/acceptance/admin.exp create mode 100755 tests/acceptance/admin.sh delete mode 100755 tests/acceptance/pkgsrc.exp delete mode 100755 tests/acceptance/pkgsrc.sh delete mode 100644 tests/fixtures/pkgsrc/distfiles/mouse-hello-1.0.c delete mode 100644 tests/fixtures/pkgsrc/local/mouse-hello/DESCR delete mode 100644 tests/fixtures/pkgsrc/local/mouse-hello/Makefile delete mode 100644 tests/fixtures/pkgsrc/local/mouse-hello/PLIST delete mode 100644 tests/fixtures/pkgsrc/local/mouse-hello/distinfo delete mode 100644 tests/fixtures/pkgsrc/local/mouse-hello/files/mouse-hello-service delete mode 100644 tests/fixtures/pkgsrc/local/mouse-hello/files/mouse_hello.sh diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..24e115f --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.patch -whitespace diff --git a/Containerfile b/Containerfile index f7a4e46..9be5a31 100644 --- a/Containerfile +++ b/Containerfile @@ -1,7 +1,15 @@ ARG MOUSE_ROOTFS_STAGE=rootfs-builder +ARG TARGETARCH +ARG TARGETPLATFORM +ARG MOUSE_ARCH=${TARGETARCH} +ARG MOUSE_TARGET_CONTAINER_PLATFORM=${TARGETPLATFORM} FROM alpine@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b AS toolchain +ARG MOUSE_ARCH +ENV MOUSE_ARCH=${MOUSE_ARCH} +ENV MOUSE_BUILD_DIR=/work/mouse-src/build + RUN apk add --no-cache \ bc=1.08.2-r1 \ build-base=0.5-r4 \ @@ -30,10 +38,15 @@ ENV RUSTUP_HOME=/opt/rustup ENV CARGO_HOME=/opt/cargo ENV PATH=/opt/cargo/bin:/usr/lib/llvm22/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -RUN rustup-init -y \ +RUN case "$MOUSE_ARCH" in \ + x86_64|amd64) rust_target=x86_64-unknown-linux-musl ;; \ + aarch64|arm64) rust_target=aarch64-unknown-linux-musl ;; \ + *) printf '%s\n' "unsupported MOUSE architecture: $MOUSE_ARCH" >&2; exit 2 ;; \ + esac \ + && rustup-init -y \ --profile minimal \ --default-toolchain 1.94.0 \ - --target x86_64-unknown-linux-musl \ + --target "$rust_target" \ && chmod -R a+rX /opt/rustup /opt/cargo WORKDIR /work/mouse-src @@ -47,7 +60,16 @@ FROM scratch AS kernel-sources COPY mouse-sources/kernel/ /opt/mouse-sources/ FROM scratch AS firmware-sources -COPY mouse-sources/firmware/ /opt/mouse-sources/ +COPY mouse-sources/firmware/ /opt/mouse-firmware-sources/ + +FROM scratch AS device-firmware-sources +COPY mouse-sources/device-firmware/ /opt/mouse-sources/ + +FROM scratch AS wireless-sources +COPY mouse-sources/wireless/ /opt/mouse-sources/ + +FROM scratch AS autotools-sources +COPY mouse-sources/autotools/ /opt/mouse-sources/ FROM scratch AS facilities-sources COPY mouse-sources/facilities/ /opt/mouse-sources/ @@ -55,13 +77,31 @@ COPY mouse-sources/facilities/ /opt/mouse-sources/ FROM scratch AS storage-sources COPY mouse-sources/storage/ /opt/mouse-sources/ -FROM scratch AS pkgsrc-sources -COPY mouse-sources/pkgsrc/ /opt/mouse-sources/ - FROM scratch AS software-sources COPY mouse-sources/software/ /opt/mouse-sources/ -FROM --platform=linux/amd64 alpine@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b AS pkgsrc-seed-tools +FROM --platform=${MOUSE_TARGET_CONTAINER_PLATFORM} alpine@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b AS mouse-ports-seed-tools + +RUN apk add --no-cache \ + bmake \ + bison \ + build-base \ + bash \ + cargo \ + curl \ + git \ + gperf \ + gettext \ + libxslt \ + linux-headers \ + meson \ + ninja \ + patch \ + pkgconf \ + perl \ + python3 \ + rust \ + tzdata FROM toolchain AS kernel-builder @@ -69,6 +109,7 @@ RUN apk add --no-cache bison=3.8.2-r3 COPY --from=kernel-sources /opt/mouse-sources/ /opt/mouse-sources/ COPY mouse-src/base/kernel/ /work/mouse-src/base/kernel/ +COPY mouse-src/scripts/mouse-arch.sh /work/mouse-src/scripts/mouse-arch.sh COPY mouse-src/scripts/build-kernel.sh /work/mouse-src/scripts/build-kernel.sh RUN MOUSE_SOURCE_DIR=/opt/mouse-sources \ @@ -81,9 +122,6 @@ COPY mouse-src/scripts/build-kernel-test-module.sh /work/mouse-src/scripts/build RUN /work/mouse-src/scripts/build-kernel-test-module.sh -# Keep the resource-heavy kernel and LLVM builds from running concurrently. -# The constant marker adds an ordering edge without passing kernel artifacts -# into the static-base cache key. FROM kernel-builder AS kernel-ready RUN install -m 0444 /dev/null /kernel-ready @@ -99,6 +137,7 @@ COPY --from=kernel-sources /opt/mouse-sources/ /opt/mouse-sources/ COPY --from=software-sources /opt/mouse-sources/ /opt/mouse-sources/ COPY mouse-src/base/support/cross-compiler-driver /work/mouse-src/base/support/cross-compiler-driver COPY mouse-src/base/support/rust-eh-personality.c /work/mouse-src/base/support/rust-eh-personality.c +COPY mouse-src/scripts/mouse-arch.sh /work/mouse-src/scripts/mouse-arch.sh COPY mouse-src/scripts/configure-cross-toolchain.sh /work/mouse-src/scripts/configure-cross-toolchain.sh COPY mouse-src/scripts/static-base/common.sh /work/mouse-src/scripts/static-base/common.sh COPY mouse-src/scripts/static-base/bootstrap.sh /work/mouse-src/scripts/static-base/bootstrap.sh @@ -108,6 +147,7 @@ RUN MOUSE_SOURCE_DIR=/opt/mouse-sources \ FROM static-base-bootstrap AS static-base-libraries +COPY mouse-src/base/patches/shadow-4.20.0-stdint.patch /work/mouse-src/base/patches/shadow-4.20.0-stdint.patch COPY mouse-src/scripts/static-base/libraries-and-accounts.sh /work/mouse-src/scripts/static-base/libraries-and-accounts.sh RUN MOUSE_SOURCE_DIR=/opt/mouse-sources \ @@ -127,10 +167,27 @@ RUN MOUSE_NATIVE_TOOLCHAIN_PHASE=package-tools \ COPY mouse-src/scripts/static-base/dynamic-runtime.sh /work/mouse-src/scripts/static-base/dynamic-runtime.sh -RUN sh /work/mouse-src/scripts/static-base/dynamic-runtime.sh +RUN MOUSE_SOURCE_DIR=/opt/mouse-sources \ + sh /work/mouse-src/scripts/static-base/dynamic-runtime.sh + +FROM toolchain AS autotools-builder + +ARG MOUSE_BUILD_JOBS=8 + +COPY --from=static-base-toolchain /work/mouse-src/build/static/sysroot /work/mouse-src/build/static/sysroot +COPY --from=static-base-toolchain /work/mouse-src/build/static/cross-tools /work/mouse-src/build/static/cross-tools +COPY --from=static-base-toolchain /work/mouse-src/build/static/rust-eh-personality.o /work/mouse-src/build/static/rust-eh-personality.o +COPY --from=autotools-sources /opt/mouse-sources/ /opt/mouse-sources/ +COPY mouse-src/scripts/build-world-autotools.sh /usr/libexec/mouse-build-world-autotools + +RUN MOUSE_BUILD_JOBS="$MOUSE_BUILD_JOBS" \ + /usr/libexec/mouse-build-world-autotools FROM static-base-toolchain AS static-base-system +RUN apk add --no-cache bash=5.3.9-r1 + +COPY --from=autotools-builder /opt/mouse-autotools/ /work/mouse-src/build/static/rootfs/ COPY mouse-src/base/patches/chimerautils-native-cdefs.patch /work/mouse-src/base/patches/chimerautils-native-cdefs.patch COPY mouse-src/base/patches/chimerautils-scanflike.patch /work/mouse-src/base/patches/chimerautils-scanflike.patch COPY mouse-src/base/patches/tcsh-gethost-native.patch /work/mouse-src/base/patches/tcsh-gethost-native.patch @@ -139,7 +196,19 @@ COPY mouse-src/scripts/static-base/system-services.sh /work/mouse-src/scripts/st RUN MOUSE_SOURCE_DIR=/opt/mouse-sources \ sh /work/mouse-src/scripts/static-base/system-services.sh -FROM static-base-system AS static-base-facilities +FROM static-base-system AS static-base-wireless + +COPY --from=kernel-builder /usr/bin/bison /usr/bin/bison +COPY --from=kernel-builder /usr/share/bison /usr/share/bison + +COPY --from=wireless-sources /opt/mouse-sources/ /opt/mouse-sources/ +COPY mouse-src/base/patches/wpa-supplicant-2.11-openssl-4.patch /work/mouse-src/base/patches/wpa-supplicant-2.11-openssl-4.patch +COPY mouse-src/scripts/static-base/wireless.sh /work/mouse-src/scripts/static-base/wireless.sh + +RUN MOUSE_SOURCE_DIR=/opt/mouse-sources \ + sh /work/mouse-src/scripts/static-base/wireless.sh + +FROM static-base-wireless AS static-base-facilities COPY --from=facilities-sources /opt/mouse-sources/ /opt/mouse-sources/ COPY mouse-src/base/patches/nftables-posix-configure.patch /work/mouse-src/base/patches/nftables-posix-configure.patch @@ -163,25 +232,17 @@ COPY mouse-src/scripts/static-base/finish.sh /work/mouse-src/scripts/static-base RUN MOUSE_SOURCE_DIR=/opt/mouse-sources \ sh /work/mouse-src/scripts/static-base/finish.sh -FROM --platform=linux/amd64 scratch AS pkgsrc-seed-builder +FROM mouse-ports-seed-tools AS mouse-ports-seed-builder -ARG MOUSE_BUILD_JOBS=8 +COPY mouse-ports/ /usr/local/src/mouse-ports/ +COPY mouse-src/scripts/build-mouse-ports-seed.sh /usr/libexec/mouse-build-ports-seed -COPY --from=static-base-builder /work/mouse-src/build/static/rootfs / -COPY --from=pkgsrc-sources /opt/mouse-sources/pkgsrc-2026Q2.tar.gz /usr/share/mouse/pkgsrc-2026Q2.tar.gz -COPY mouse-src/base/rootfs/etc/group /etc/group -COPY mouse-src/base/rootfs/etc/mouse-release /etc/mouse-release -COPY mouse-src/base/rootfs/etc/passwd /etc/passwd -COPY mouse-src/base/patches/pkgsrc-bootstrap-mouse.patch /usr/share/mouse/pkgsrc-bootstrap-mouse.patch -COPY mouse-src/scripts/build-pkgsrc-seed.sh /usr/libexec/mouse-build-pkgsrc-seed -COPY --from=pkgsrc-seed-tools /bin/busybox /usr/libexec/mouse-build-busybox - -RUN MOUSE_BUILD_JOBS="$MOUSE_BUILD_JOBS" \ - sh /usr/libexec/mouse-build-pkgsrc-seed +RUN /usr/libexec/mouse-build-ports-seed FROM toolchain AS btrfs-image-builder RUN apk add --no-cache \ + coreutils=9.11-r0 \ mtools=4.0.49-r0 \ pkgconf=2.5.1-r0 \ sfdisk=2.42.1-r0 \ @@ -189,31 +250,29 @@ RUN apk add --no-cache \ zlib-dev=1.3.2-r0 \ zstd-dev=1.5.7-r2 -COPY --from=storage-sources /opt/mouse-sources/btrfs-progs-v7.0.tar.xz /opt/ -COPY --from=storage-sources /opt/mouse-sources/limine-binary-12.3.2.tar.xz /opt/mouse-sources/limine-binary-12.3.2.tar.xz +COPY --from=storage-sources /opt/mouse-sources/btrfs-progs-v7.1.tar.xz /opt/ +COPY --from=storage-sources /opt/mouse-sources/limine-binary-12.5.2.tar.xz /opt/mouse-sources/limine-binary-12.5.2.tar.xz +COPY mouse-src/scripts/build-btrfs-image-tool.sh /usr/libexec/mouse-build-btrfs-image-tool -RUN tar -C /work -xf /opt/btrfs-progs-v7.0.tar.xz \ - && cd /work/btrfs-progs-v7.0 \ - && ./configure \ - --prefix=/usr \ - --disable-backtrace \ - --disable-documentation \ - --disable-convert \ - --disable-lzo \ - --disable-libudev \ - --disable-python \ - --disable-zoned \ - --with-crypto=builtin \ - && make \ - -j"$MOUSE_BUILD_JOBS" \ - mkfs.btrfs \ - && install -m 0755 \ - /work/btrfs-progs-v7.0/mkfs.btrfs \ - /opt/mkfs.btrfs +RUN MOUSE_BUILD_JOBS="$MOUSE_BUILD_JOBS" \ + /usr/libexec/mouse-build-btrfs-image-tool + +FROM toolchain AS device-firmware-builder + +RUN apk add --no-cache coreutils=9.11-r0 + +COPY --from=device-firmware-sources /opt/mouse-sources/linux-firmware-20260622.tar.xz /opt/mouse-sources/ + +RUN tar -xf /opt/mouse-sources/linux-firmware-20260622.tar.xz -C /work \ + && make -s -C /work/linux-firmware-20260622 \ + DESTDIR=/opt/mouse-device-firmware \ + install-xz FROM static-base-builder AS image-commands-builder COPY mouse-src/base/support/mouse-bootenv /work/mouse-src/base/support/mouse-bootenv +COPY mouse-src/base/support/mouse-auth.c /work/mouse-src/base/support/mouse-auth.c +COPY mouse-src/base/support/mouse-package /work/mouse-src/base/support/mouse-package COPY mouse-src/scripts/audit-static-base.sh /work/mouse-src/scripts/audit-static-base.sh COPY mouse-src/scripts/build-image-commands.sh /work/mouse-src/scripts/build-image-commands.sh @@ -224,19 +283,22 @@ FROM image-commands-builder AS test-fixtures-builder COPY mouse-src/tests/fixtures/mouse-echo/mouse-echo.c /work/mouse-src/tests/fixtures/mouse-echo/mouse-echo.c -RUN /work/mouse-src/build/static/cross-tools/bin/x86_64-mouse-linux-musl-cc \ +RUN . /work/mouse-src/scripts/mouse-arch.sh \ + && /work/mouse-src/build/static/cross-tools/bin/$MOUSE_CROSS_TARGET-cc \ -O2 -Wall -Wextra -Werror \ /work/mouse-src/tests/fixtures/mouse-echo/mouse-echo.c \ -o /opt/mouse-echo FROM image-commands-builder AS cheesed-builder +COPY mouse-cargo/ /opt/cargo/ COPY mouse-src/base/cheesed/ /work/mouse-src/base/cheesed/ -RUN CHEESED_TARGET=x86_64-unknown-linux-musl \ - /work/mouse-src/base/cheesed/scripts/build-static.sh \ +RUN . /work/mouse-src/scripts/mouse-arch.sh \ + && CARGO_NET_OFFLINE=true CHEESED_TARGET="$MOUSE_RUST_TARGET" \ + /work/mouse-src/base/cheesed/scripts/build-static.sh \ && install -m 0755 \ - /work/mouse-src/base/cheesed/target/x86_64-unknown-linux-musl/release/cheesed \ + /work/mouse-src/base/cheesed/target/$MOUSE_RUST_TARGET/release/cheesed \ /opt/cheesed FROM btrfs-image-builder AS rootfs-common @@ -244,11 +306,12 @@ FROM btrfs-image-builder AS rootfs-common COPY --from=cheesed-builder /work/mouse-src/build/static/rootfs /work/mouse-src/build/static/rootfs COPY --from=cheesed-builder /opt/cheesed /opt/cheesed COPY --from=kernel-builder /work/mouse-src/build/vmlinuz-virt /work/mouse-src/build/vmlinuz-virt -COPY --from=pkgsrc-seed-builder /usr/local /opt/mouse-pkgsrc-seed/usr/local -COPY --from=pkgsrc-seed-builder /var/db/pkg /opt/mouse-pkgsrc-seed/var/db/pkg +COPY --from=mouse-ports-seed-builder /opt/mouse-ports-seed /opt/mouse-ports-seed COPY mouse-src/base/rootfs/ /work/mouse-src/base/rootfs/ -COPY mouse-src/base/patches/pkgsrc-rc.subr-cgroup.patch /work/mouse-src/base/patches/pkgsrc-rc.subr-cgroup.patch +COPY mouse-ports-revision /work/mouse-ports-revision +COPY mouse-src/base/patches/rc.subr-cgroup.patch /work/mouse-src/base/patches/rc.subr-cgroup.patch COPY mouse-src/scripts/audit-static-base.sh /work/mouse-src/scripts/audit-static-base.sh +COPY mouse-src/scripts/mouse-arch.sh /work/mouse-src/scripts/mouse-arch.sh COPY mouse-src/scripts/build-image.sh /work/mouse-src/scripts/build-image.sh COPY mouse-src/scripts/build-boot-disk.sh /work/mouse-src/scripts/build-boot-disk.sh COPY mouse-src/base/limine.conf /work/mouse-src/base/limine.conf @@ -256,44 +319,50 @@ COPY mouse-src/base/limine.conf /work/mouse-src/base/limine.conf FROM rootfs-common AS rootfs-builder COPY --from=kernel-builder /work/mouse-src/build/kernel/modules /opt/mouse-kernel-modules +COPY --from=device-firmware-builder /opt/mouse-device-firmware /opt/mouse-device-firmware RUN MOUSE_SOURCE_DIR=/opt/mouse-sources \ MOUSE_CHEESED_BINARY=/opt/cheesed \ MOUSE_BTRFS_IMAGE_TOOL=/opt/mkfs.btrfs \ - MOUSE_PKGSRC_SEED=/opt/mouse-pkgsrc-seed \ + MOUSE_PORTS_SEED=/opt/mouse-ports-seed \ MOUSE_KERNEL_MODULES=/opt/mouse-kernel-modules \ + MOUSE_DEVICE_FIRMWARE=/opt/mouse-device-firmware \ /work/mouse-src/scripts/build-image.sh FROM rootfs-common AS rootfs-test-builder COPY --from=kernel-test-builder /work/mouse-src/build/kernel/test-modules /opt/mouse-kernel-modules +COPY --from=device-firmware-builder /opt/mouse-device-firmware /opt/mouse-device-firmware COPY --from=test-fixtures-builder /opt/mouse-echo /opt/mouse-echo COPY mouse-src/tests/fixtures/ /work/mouse-src/tests/fixtures/ RUN MOUSE_SOURCE_DIR=/opt/mouse-sources \ MOUSE_CHEESED_BINARY=/opt/cheesed \ MOUSE_BTRFS_IMAGE_TOOL=/opt/mkfs.btrfs \ - MOUSE_PKGSRC_SEED=/opt/mouse-pkgsrc-seed \ + MOUSE_PORTS_SEED=/opt/mouse-ports-seed \ MOUSE_KERNEL_MODULES=/opt/mouse-kernel-modules \ + MOUSE_DEVICE_FIRMWARE=/opt/mouse-device-firmware \ MOUSE_MOUSE_ECHO_BINARY=/opt/mouse-echo \ MOUSE_INCLUDE_TEST_FIXTURES=1 \ /work/mouse-src/scripts/build-image.sh FROM ${MOUSE_ROOTFS_STAGE} AS selected-rootfs +FROM selected-rootfs AS compressed-rootfs + +RUN gzip -1 /work/mouse-src/build/mouse-disk.img \ + && gzip -t /work/mouse-src/build/mouse-disk.img.gz + FROM toolchain AS artifact-packer -COPY --from=selected-rootfs /work/mouse-src/build/mouse-disk.img / -COPY --from=firmware-sources /opt/mouse-sources/ovmf-0.0.202605-r0.apk /opt/ +COPY --from=compressed-rootfs /work/mouse-src/build/mouse-disk.img.gz / +COPY --from=firmware-sources /opt/mouse-firmware-sources/ /opt/mouse-sources/ +COPY mouse-src/scripts/extract-build-firmware.sh /usr/libexec/mouse-extract-build-firmware -RUN mkdir -p /opt/ovmf \ - && tar -xf /opt/ovmf-0.0.202605-r0.apk \ - -C /opt/ovmf \ - usr/share/OVMF/OVMF_CODE.fd \ - && gzip -1 /mouse-disk.img +RUN /usr/libexec/mouse-extract-build-firmware FROM scratch AS artifacts COPY --from=kernel-builder /work/mouse-src/build/vmlinuz-virt / COPY --from=artifact-packer /mouse-disk.img.gz / -COPY --from=artifact-packer /opt/ovmf/usr/share/OVMF/OVMF_CODE.fd /ovmf-code.fd +COPY --from=artifact-packer /uefi-code.fd / diff --git a/Makefile b/Makefile index 2978ffb..9898d64 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,35 @@ .PHONY: all check check-locks clean fetch image run +MOUSE_ARCH_INPUT := $(MOUSE_ARCH) +MOUSE_ARCH_RESOLVED := $(shell \ + MOUSE_ARCH='$(MOUSE_ARCH_INPUT)' \ + MOUSE_BUILDER_PLATFORM='$(MOUSE_BUILDER_PLATFORM)' \ + sh -c '. ./scripts/mouse-arch.sh; printf "%s" "$$MOUSE_ARCH"') +ifeq ($(MOUSE_ARCH_RESOLVED),) +$(error unable to resolve MOUSE_ARCH) +endif +override MOUSE_ARCH := $(MOUSE_ARCH_RESOLVED) + +MOUSE_BUILD_DIR ?= $(CURDIR)/build/$(MOUSE_ARCH) +MOUSE_SOURCE_DIR ?= $(CURDIR)/build/sources MOUSE_BUILDER_CPUS ?= 8 MOUSE_BUILDER_MEMORY ?= 8G MOUSE_BUILD_JOBS ?= 8 MOUSE_BOOT_MODE ?= firmware MOUSE_NETWORK ?= 1 +MOUSE_GRAPHICAL ?= 1 BUILD_ENV = \ + MOUSE_ARCH="$(MOUSE_ARCH)" \ + MOUSE_BUILD_DIR="$(MOUSE_BUILD_DIR)" \ + MOUSE_SOURCE_DIR="$(MOUSE_SOURCE_DIR)" \ + MOUSE_BUILDER_PLATFORM="$(MOUSE_BUILDER_PLATFORM)" \ MOUSE_BUILDER_CPUS="$(MOUSE_BUILDER_CPUS)" \ MOUSE_BUILDER_MEMORY="$(MOUSE_BUILDER_MEMORY)" \ MOUSE_BUILD_JOBS="$(MOUSE_BUILD_JOBS)" -CHECKS = boot firmware world service-integration storage btrfs network \ - multi-user toolchain pkgsrc +CHECKS = admin boot firmware world service-integration storage btrfs network \ + multi-user toolchain all: image @@ -20,20 +37,27 @@ check-locks: ./scripts/check-source-locks.sh fetch: check-locks - ./scripts/fetch-sources.sh + MOUSE_SOURCE_DIR="$(MOUSE_SOURCE_DIR)" ./scripts/fetch-sources.sh image: check-locks $(BUILD_ENV) ./scripts/build-in-container.sh run: + MOUSE_ARCH="$(MOUSE_ARCH)" \ + MOUSE_BUILD_DIR="$(MOUSE_BUILD_DIR)" \ MOUSE_BOOT_MODE="$(MOUSE_BOOT_MODE)" \ MOUSE_NETWORK="$(MOUSE_NETWORK)" \ + MOUSE_GRAPHICAL="$(MOUSE_GRAPHICAL)" \ ./scripts/run-qemu.sh check: check-locks $(BUILD_ENV) MOUSE_INCLUDE_TEST_FIXTURES=1 \ ./scripts/build-in-container.sh - @set -e; for check in $(CHECKS); do ./tests/acceptance/$$check.sh; done + @set -e; for check in $(CHECKS); do \ + MOUSE_ARCH="$(MOUSE_ARCH)" \ + MOUSE_BUILD_DIR="$(MOUSE_BUILD_DIR)" \ + ./tests/acceptance/$$check.sh; \ + done clean: rm -rf build/* diff --git a/README.md b/README.md index 3ff1b69..6b7e6d5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # MOUSE MOUSE is the **Monolithic Opinionated Unix-like System Environment**: a small -Linux system with a versioned base, pkgsrc for third-party software, and +Linux system with a versioned base, mouse-ports for third-party software, and `cheesed` as PID 1. ## Build @@ -15,22 +15,32 @@ make run make check ``` -Artifacts and downloaded sources are kept in `build/`. The default builder has +The guest defaults to the host architecture, so Apple Silicon builds AArch64. +Set `MOUSE_ARCH=x86_64` or `MOUSE_ARCH=aarch64` to override it. An explicit +`MOUSE_BUILDER_PLATFORM` supplies the default architecture only when +`MOUSE_ARCH` is unset, so `MOUSE_ARCH=x86_64 MOUSE_BUILDER_PLATFORM=linux/arm64` +cross-builds an x86_64 guest on the Arm builder. Architecture-specific artifacts +live under `build/x86_64/` and `build/aarch64/`; downloaded sources are shared +under `build/sources/`. + +The default builder has 8 CPUs, 8 GB of memory, and 8 build jobs; override those with `MOUSE_BUILDER_CPUS`, `MOUSE_BUILDER_MEMORY`, and `MOUSE_BUILD_JOBS`. -`MOUSE_NETWORK=0 make run` disables QEMU networking. +`MOUSE_NETWORK=0 make run` disables QEMU networking. `MOUSE_GRAPHICAL=1 make +run` opens QEMU's graphical display while retaining the serial console in the +terminal. -Development images contain `root` and `toor`, both with the password -`cheddar`. `root` uses `/bin/sh` for emergency administration; `toor` uses -`/bin/tcsh` for ordinary administration. Change both passwords before exposing -an image to a network. +VM images use the hostname `mousehole` and provide the administrator account +`mouse` with the password `cheddar`. The account is a member of `wheel` and can +elevate through `doas`; direct `root` and `toor` password authentication remains +locked. ## System -The base owns `/bin`, `/sbin`, `/usr/bin`, and `/usr/sbin`; pkgsrc owns +The base owns `/bin`, `/sbin`, `/usr/bin`, and `/usr/sbin`; mouse-ports owns `/usr/local`. `/var`, `/home`, `/srv`, and `/usr/local` are shared by both root environments, `/etc` follows the selected root, and `/run` is rebuilt at boot. -The fixed `/usr/local` package prefix keeps pkgsrc out of base-owned paths. +The fixed `/usr/local` package prefix keeps ports out of base-owned paths. Limine boots the default or alternate root from the same disk. `mouse-bootenv prepare` snapshots the running root into the inactive one; @@ -47,6 +57,10 @@ Persistent service policy lives only in `/etc/rc.conf`: ```sh enable_network=YES +enable_gardendevd=YES +enable_seatd=YES +enable_greetd=YES +enable_wpa_supplicant=NO enable_cron=YES enable_ntpd=YES ``` @@ -55,18 +69,25 @@ Assignments are exactly `enable_NAME=YES` or `enable_NAME=NO`; shell expansion, includes, and other keys are invalid. `/sbin/service` controls the running system without editing boot policy. +The x86_64 kernel includes common laptop and desktop storage, USB, input, +wired-network, Intel Wi-Fi, and Atheros Wi-Fi drivers. Images ship the complete +pinned linux-firmware collection. To configure Wi-Fi, write a mode-0600 +`/etc/wpa_supplicant/wpa_supplicant.conf` with `wpa_passphrase`, set +`enable_wpa_supplicant=YES` in `/etc/rc.conf`, and reboot; gardendevd loads drivers +for devices present at boot or plugged in later. + ## Packages -Images contain the pinned pkgsrc 2026Q2 tree in `/usr/local/src/pkgsrc`, with -`bmake` and the package tools under `/usr/local`. Packages use -`/usr/local/etc` for configuration, `/var/db/pkg` for records, and -`/var/cache/pkgsrc` for distfiles and binary packages. This state survives a -base rollback. +Images contain the MOUSE ports tree in `/usr/local/src/mouse-ports`, with +source-built `bmake` under `/usr/local`. Ports use `/usr/local/etc` for +configuration, `/var/db/mouse/packages` for installation records, and +`/var/cache/mouse/ports` for verified distfiles. This state survives a base +rollback. ## Checks `make check` builds the assembled disk with test fixtures, then boots it under -QEMU. It covers BIOS and UEFI boot, both Btrfs roots, services and cgroup -cleanup, users, networking, storage tools, native C and C++ compilation, pkgsrc -installation, and persistence across reboots. The build also rejects changed +QEMU. It covers UEFI boot on both architectures and BIOS on x86_64, both Btrfs roots, services and cgroup +cleanup, users, networking, storage tools, native C and C++ compilation, ports +layout, and persistence across reboots. The build also rejects changed source checksums and dynamic base executables. diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..42f51e9 --- /dev/null +++ b/TODO.md @@ -0,0 +1,4 @@ +- [x] let there be graphics! +- [ ] transactional world updates + - [ ] etcmerge-esque /etc updating +- [ ] make it boot on real hardware diff --git a/base/cheesed/scripts/build-static.sh b/base/cheesed/scripts/build-static.sh index c3f82d4..070cd91 100755 --- a/base/cheesed/scripts/build-static.sh +++ b/base/cheesed/scripts/build-static.sh @@ -3,7 +3,15 @@ set -eu script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) repo_dir=$(dirname "$script_dir") -target=${CHEESED_TARGET:-x86_64-unknown-linux-musl} +if [ -n "${CHEESED_TARGET:-}" ]; then + target=$CHEESED_TARGET +else + case "$(uname -m)" in + x86_64|amd64) target=x86_64-unknown-linux-musl ;; + aarch64|arm64) target=aarch64-unknown-linux-musl ;; + *) printf '%s\n' "unsupported cheesed build architecture: $(uname -m)" >&2; exit 2 ;; + esac +fi if ! rustup target list --installed | grep -qx "$target"; then printf '%s\n' "missing Rust target: $target" >&2 diff --git a/base/cheesed/src/linux/boot.rs b/base/cheesed/src/linux/boot.rs index 0e88e9e..11aef13 100644 --- a/base/cheesed/src/linux/boot.rs +++ b/base/cheesed/src/linux/boot.rs @@ -8,7 +8,8 @@ const MOUSE_ROOT_PARTUUID: &str = "4d4f5553-4500-4000-8000-000000000002"; const BTRFS_SUPER_MAGIC: u64 = 0x9123_683e; pub(super) fn mount_early_filesystems() -> io::Result<()> { - mount_filesystem(c"devtmpfs".as_ptr(), c"/dev".as_ptr(), c"devtmpfs".as_ptr())?; + // The MOUSE kernels mount devtmpfs before starting PID 1. Mounting another + // instance here would hide device nodes registered during kernel startup. mount_filesystem(c"proc".as_ptr(), c"/proc".as_ptr(), c"proc".as_ptr())?; mount_filesystem(c"sysfs".as_ptr(), c"/sys".as_ptr(), c"sysfs".as_ptr())?; std::fs::create_dir_all(CGROUP_ROOT)?; @@ -17,26 +18,49 @@ pub(super) fn mount_early_filesystems() -> io::Result<()> { c"/sys/fs/cgroup".as_ptr(), c"cgroup2".as_ptr(), )?; - mount_filesystem(c"tmpfs".as_ptr(), c"/run".as_ptr(), c"tmpfs".as_ptr()) + mount_filesystem(c"tmpfs".as_ptr(), c"/run".as_ptr(), c"tmpfs".as_ptr())?; + std::fs::create_dir_all("/dev/shm")?; + mount_filesystem_with_options( + c"tmpfs".as_ptr(), + c"/dev/shm".as_ptr(), + c"tmpfs".as_ptr(), + libc::MS_NOSUID | libc::MS_NODEV, + c"mode=1777".as_ptr().cast(), + )?; + std::fs::create_dir_all("/dev/pts")?; + mount_filesystem_with_options( + c"devpts".as_ptr(), + c"/dev/pts".as_ptr(), + c"devpts".as_ptr(), + libc::MS_NOSUID | libc::MS_NOEXEC, + c"mode=0620,ptmxmode=0666".as_ptr().cast(), + ) } fn mount_filesystem( source: *const libc::c_char, target: *const libc::c_char, filesystem_type: *const libc::c_char, +) -> io::Result<()> { + mount_filesystem_with_options( + source, + target, + filesystem_type, + 0, + std::ptr::null::(), + ) +} + +fn mount_filesystem_with_options( + source: *const libc::c_char, + target: *const libc::c_char, + filesystem_type: *const libc::c_char, + flags: libc::c_ulong, + data: *const libc::c_void, ) -> io::Result<()> { // SAFETY: all pointers are valid, static, NUL-terminated C strings; no data - // argument is required for these pseudo-filesystems. - if unsafe { - libc::mount( - source, - target, - filesystem_type, - 0, - std::ptr::null::(), - ) - } == -1 - { + // argument is required unless the filesystem receives static mount options. + if unsafe { libc::mount(source, target, filesystem_type, flags, data) } == -1 { let error = io::Error::last_os_error(); if error.raw_os_error() != Some(libc::EBUSY) { return Err(error); diff --git a/base/kernel/aarch64.config b/base/kernel/aarch64.config new file mode 100644 index 0000000..b7860d5 --- /dev/null +++ b/base/kernel/aarch64.config @@ -0,0 +1,146 @@ +CONFIG_LOCALVERSION="-mouse" +CONFIG_DEFAULT_HOSTNAME="mousehole" + +CONFIG_64BIT=y +CONFIG_ARM64=y +CONFIG_SMP=y +CONFIG_ARM_PSCI_FW=y +CONFIG_ACPI=y +CONFIG_EFI=y +CONFIG_EFI_STUB=y + +CONFIG_MULTIUSER=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_SCRIPT=y +CONFIG_FILE_LOCKING=y +CONFIG_SWAP=y +CONFIG_CGROUPS=y +CONFIG_KALLSYMS=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_BASIC_MODVERSIONS=y + +CONFIG_BLOCK=y +CONFIG_BLK_DEV=y +CONFIG_EFI_PARTITION=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_FW_LOADER=y +CONFIG_FW_LOADER_COMPRESS=y +CONFIG_FW_LOADER_COMPRESS_XZ=y +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y + +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_PACKET_DIAG=y +CONFIG_UNIX=y +CONFIG_UNIX_DIAG=y +CONFIG_INET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_UDP_DIAG=y +CONFIG_IPV6=y +CONFIG_NETLINK_DIAG=y +CONFIG_NAMESPACES=y +CONFIG_NET_NS=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_NAT=y +CONFIG_NF_TABLES=y +CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_CT=y +CONFIG_NFT_LOG=y +CONFIG_NFT_LIMIT=y +CONFIG_NFT_MASQ=y +CONFIG_NFT_REDIR=y +CONFIG_NFT_NAT=y +CONFIG_NFT_REJECT=y +CONFIG_NFT_REJECT_INET=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_HTB=y +CONFIG_NET_SCH_FQ_CODEL=y +CONFIG_NET_CLS_BASIC=y +CONFIG_NET_CLS_U32=y +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +CONFIG_ETHERNET=y +CONFIG_DUMMY=y +CONFIG_BONDING=y +CONFIG_TUN=y +CONFIG_VETH=y +CONFIG_VLAN_8021Q=y +CONFIG_BRIDGE=y +CONFIG_BRIDGE_VLAN_FILTERING=y + +CONFIG_PCI=y +CONFIG_PCI_MSI=y +CONFIG_PCI_HOST_GENERIC=y +CONFIG_VIRTIO_MENU=y +CONFIG_VIRTIO=y +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_MMIO=y +CONFIG_VIRTIO_BLK=y +CONFIG_VIRTIO_INPUT=y +CONFIG_VIRTIO_NET=y +CONFIG_NET_VENDOR_INTEL=y +CONFIG_E1000=y +CONFIG_E1000E=y + +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_ATA=y +CONFIG_SATA_AHCI=y +CONFIG_BLK_DEV_NVME=y + +CONFIG_USB_SUPPORT=y +CONFIG_USB=y +CONFIG_USB_PCI=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI=y +CONFIG_USB_STORAGE=y +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HID_GENERIC=y +CONFIG_USB_HID=y + +CONFIG_TTY=y +CONFIG_UNIX98_PTYS=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_INPUT=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_FB=y +CONFIG_FB_EFI=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_SYSFB=y +CONFIG_SYSFB_SIMPLEFB=y +CONFIG_DRM=y +CONFIG_DRM_SIMPLEDRM=y +CONFIG_DRM_FBDEV_EMULATION=y +CONFIG_DRM_VIRTIO_GPU=y +CONFIG_DRM_VIRTIO_GPU_KMS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_DRV_EFI=y +CONFIG_RTC_DRV_PL031=y + +CONFIG_BTRFS_FS=y +CONFIG_BTRFS_FS_POSIX_ACL=y diff --git a/base/kernel/x86_64.config b/base/kernel/x86_64.config index 0d666a0..53a01b0 100644 --- a/base/kernel/x86_64.config +++ b/base/kernel/x86_64.config @@ -1,5 +1,5 @@ CONFIG_LOCALVERSION="-mouse" -CONFIG_DEFAULT_HOSTNAME="mouse" +CONFIG_DEFAULT_HOSTNAME="mousehole" CONFIG_64BIT=y CONFIG_X86_64=y @@ -7,8 +7,17 @@ CONFIG_SMP=y CONFIG_HYPERVISOR_GUEST=y CONFIG_PARAVIRT=y CONFIG_ACPI=y +CONFIG_ACPI_AC=y +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_FAN=y +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_VIDEO=y +CONFIG_ACPI_WMI=y CONFIG_EFI=y CONFIG_EFI_STUB=y +CONFIG_MICROCODE=y +CONFIG_X86_MCE=y CONFIG_MULTIUSER=y CONFIG_PRINTK=y @@ -35,6 +44,8 @@ CONFIG_EFI_PARTITION=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_FW_LOADER=y +CONFIG_FW_LOADER_COMPRESS=y +CONFIG_FW_LOADER_COMPRESS_XZ=y CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y @@ -87,20 +98,59 @@ CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_PCI=y CONFIG_PCI_MSI=y +CONFIG_PCIEPORTBUS=y +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_ACPI=y CONFIG_VIRTIO_MENU=y CONFIG_VIRTIO=y CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_BLK=y +CONFIG_VIRTIO_INPUT=y CONFIG_VIRTIO_NET=y CONFIG_NET_VENDOR_INTEL=y CONFIG_E1000=y CONFIG_E1000E=y +CONFIG_IGB=m +CONFIG_IGC=m +CONFIG_NET_VENDOR_REALTEK=y +CONFIG_R8169=m +CONFIG_NET_VENDOR_BROADCOM=y +CONFIG_TIGON3=m + +CONFIG_WLAN=y +CONFIG_CFG80211=m +CONFIG_MAC80211=m +CONFIG_RFKILL=y +CONFIG_WLAN_VENDOR_INTEL=y +CONFIG_IWLWIFI=m +CONFIG_IWLMVM=m +CONFIG_WLAN_VENDOR_ATH=y +CONFIG_ATH9K=m +CONFIG_ATH9K_PCI=y +CONFIG_ATH10K=m +CONFIG_ATH10K_PCI=m CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_ATA=y CONFIG_SATA_AHCI=y +CONFIG_ATA_PIIX=y CONFIG_BLK_DEV_NVME=y +CONFIG_VMD=y + +CONFIG_USB_SUPPORT=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_PCI=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PCI=y +CONFIG_USB_UHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_HID=y +CONFIG_HID_GENERIC=y +CONFIG_USB_HID=y CONFIG_TTY=y CONFIG_UNIX98_PTYS=y @@ -110,13 +160,27 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_VGA_CONSOLE=y CONFIG_INPUT=y +CONFIG_INPUT_EVDEV=y CONFIG_INPUT_KEYBOARD=y CONFIG_KEYBOARD_ATKBD=y +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y CONFIG_SERIO=y CONFIG_SERIO_I8042=y CONFIG_FB=y CONFIG_FB_EFI=y CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_SYSFB=y +CONFIG_SYSFB_SIMPLEFB=y +CONFIG_DRM=y +CONFIG_DRM_SIMPLEDRM=y +CONFIG_DRM_FBDEV_EMULATION=y +CONFIG_DRM_VIRTIO_GPU=y +CONFIG_DRM_VIRTIO_GPU_KMS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_DRV_CMOS=y CONFIG_BTRFS_FS=y CONFIG_BTRFS_FS_POSIX_ACL=y diff --git a/base/limine.conf b/base/limine.conf index 3c2946d..e86f6ea 100644 --- a/base/limine.conf +++ b/base/limine.conf @@ -1,7 +1,6 @@ timeout: 3 default_entry: 1 -serial: yes -serial_baudrate: 115200 +serial: no graphics: yes interface_branding: MOUSE diff --git a/base/patches/pkgsrc-bootstrap-mouse.patch b/base/patches/pkgsrc-bootstrap-mouse.patch deleted file mode 100644 index ade29c3..0000000 --- a/base/patches/pkgsrc-bootstrap-mouse.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/bootstrap/bootstrap -+++ b/bootstrap/bootstrap -@@ -683,7 +683,9 @@ Linux) - fi - # Debian/Ubuntu's awk is mawk, and mawk does not understand - # some regexps used in pkgsrc/mk. -- if [ -f /etc/debian_version ]; then -+ if [ -f /etc/mouse-release ]; then -+ bootstrap_awk=/usr/bin/awk -+ elif [ -f /etc/debian_version ]; then - need_awk=yes - # Arch uses gawk 5 that breaks some regexps. It doesn't provide pax - # anymore. diff --git a/base/patches/pkgsrc-rc.subr-cgroup.patch b/base/patches/rc.subr-cgroup.patch similarity index 100% rename from base/patches/pkgsrc-rc.subr-cgroup.patch rename to base/patches/rc.subr-cgroup.patch diff --git a/base/patches/shadow-4.20.0-stdint.patch b/base/patches/shadow-4.20.0-stdint.patch new file mode 100644 index 0000000..a2d34e0 --- /dev/null +++ b/base/patches/shadow-4.20.0-stdint.patch @@ -0,0 +1,18 @@ +--- a/lib/find_new_sub_gids.c ++++ b/lib/find_new_sub_gids.c +@@ -7,6 +7,7 @@ + + #ifdef ENABLE_SUBIDS + ++#include + #include + #include +--- a/lib/find_new_sub_uids.c ++++ b/lib/find_new_sub_uids.c +@@ -7,6 +7,7 @@ + + #ifdef ENABLE_SUBIDS + ++#include + #include + #include diff --git a/base/patches/wpa-supplicant-2.11-openssl-4.patch b/base/patches/wpa-supplicant-2.11-openssl-4.patch new file mode 100644 index 0000000..d29b5d0 --- /dev/null +++ b/base/patches/wpa-supplicant-2.11-openssl-4.patch @@ -0,0 +1,64 @@ +--- a/src/crypto/tls_openssl.c ++++ b/src/crypto/tls_openssl.c +@@ -1854,8 +1854,9 @@ static int tls_match_altsubject_component(X509 *cert, int type, + gen = sk_GENERAL_NAME_value(ext, i); + if (gen->type != type) + continue; +- if (os_strlen((char *) gen->d.ia5->data) == len && +- os_memcmp(value, gen->d.ia5->data, len) == 0) ++ if ((size_t) ASN1_STRING_length(gen->d.ia5) == len && ++ os_memcmp(value, ASN1_STRING_get0_data(gen->d.ia5), ++ len) == 0) + found++; + } + +@@ -2176,10 +2177,11 @@ static int tls_match_suffix_helper(X509 *cert, const char *match, + continue; + dns_name++; + wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate dNSName", +- gen->d.dNSName->data, +- gen->d.dNSName->length); +- if (domain_suffix_match(gen->d.dNSName->data, +- gen->d.dNSName->length, ++ ASN1_STRING_get0_data(gen->d.dNSName), ++ ASN1_STRING_length(gen->d.dNSName)); ++ if (domain_suffix_match( ++ ASN1_STRING_get0_data(gen->d.dNSName), ++ ASN1_STRING_length(gen->d.dNSName), + match, match_len, full) == 1) { + wpa_printf(MSG_DEBUG, "TLS: %s in dNSName found", + full ? "Match" : "Suffix match"); +@@ -2210,8 +2212,10 @@ static int tls_match_suffix_helper(X509 *cert, const char *match, + if (cn == NULL) + continue; + wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate commonName", +- cn->data, cn->length); +- if (domain_suffix_match(cn->data, cn->length, ++ ASN1_STRING_get0_data(cn), ++ ASN1_STRING_length(cn)); ++ if (domain_suffix_match(ASN1_STRING_get0_data(cn), ++ ASN1_STRING_length(cn), + match, match_len, full) == 1) { + wpa_printf(MSG_DEBUG, "TLS: %s in commonName found", + full ? "Match" : "Suffix match"); +@@ -2420,7 +2424,7 @@ static void openssl_tls_cert_event(struct tls_connection *conn, + gen->type != GEN_URI) + continue; + +- pos = os_malloc(10 + gen->d.ia5->length + 1); ++ pos = os_malloc(10 + ASN1_STRING_length(gen->d.ia5) + 1); + if (pos == NULL) + break; + altsubject[num_altsubject++] = pos; +@@ -2440,8 +2444,9 @@ static void openssl_tls_cert_event(struct tls_connection *conn, + break; + } + +- os_memcpy(pos, gen->d.ia5->data, gen->d.ia5->length); +- pos += gen->d.ia5->length; ++ os_memcpy(pos, ASN1_STRING_get0_data(gen->d.ia5), ++ ASN1_STRING_length(gen->d.ia5)); ++ pos += ASN1_STRING_length(gen->d.ia5); + *pos = '\0'; + } + sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free); diff --git a/base/rootfs/etc/doas.conf b/base/rootfs/etc/doas.conf new file mode 100644 index 0000000..11e9586 --- /dev/null +++ b/base/rootfs/etc/doas.conf @@ -0,0 +1 @@ +permit :wheel diff --git a/base/rootfs/etc/group b/base/rootfs/etc/group index f851fcc..6c0638b 100644 --- a/base/rootfs/etc/group +++ b/base/rootfs/etc/group @@ -1,6 +1,23 @@ root:x:0:root,toor tty:x:5: +disk:x:6: +lp:x:7: +kmem:x:9: +wheel:x:10:mouse +cdrom:x:11: uucp:x:14: +dialout:x:20: +tape:x:26: +audio:x:29: +video:x:44: +kvm:x:78: users:x:100: dhcpcd:x:101: _ntp:x:102: +input:x:103: +render:x:104: +clock:x:105: +sgx:x:106: +seat:x:107:mouse +greeter:x:108: +mouse:x:1000: diff --git a/base/rootfs/etc/hostname b/base/rootfs/etc/hostname index 3e41be9..3831d9c 100644 --- a/base/rootfs/etc/hostname +++ b/base/rootfs/etc/hostname @@ -1 +1 @@ -mouse +mousehole diff --git a/base/rootfs/etc/mdev.conf b/base/rootfs/etc/mdev.conf deleted file mode 100644 index 3bfdca8..0000000 --- a/base/rootfs/etc/mdev.conf +++ /dev/null @@ -1,13 +0,0 @@ -# Load the exact module matching a kernel device alias. Device nodes themselves -# are supplied by devtmpfs and mdevd applies conservative default ownership. -$MODALIAS=.* root:root 0600 @modprobe -qb "$MODALIAS" -null root:root 0666 -zero root:root 0666 -full root:root 0666 -random root:root 0444 -urandom root:root 0444 -console root:tty 0600 -tty root:tty 0666 -tty[0-9]* root:tty 0660 -ttyS[0-9]* root:uucp 0660 -.* root:root 0600 diff --git a/base/rootfs/etc/motd b/base/rootfs/etc/motd index 9af2982..d62b2ae 100644 --- a/base/rootfs/etc/motd +++ b/base/rootfs/etc/motd @@ -1,2 +1,2 @@ -MOUSE 0.1.0 (x86_64) +MOUSE 0.1.0 (@MOUSE_ARCH@) Monolithic Opinionated Unix-like System Environment diff --git a/base/rootfs/etc/mouse-release b/base/rootfs/etc/mouse-release index 4121765..31f5adb 100644 --- a/base/rootfs/etc/mouse-release +++ b/base/rootfs/etc/mouse-release @@ -3,4 +3,4 @@ ID=mouse PRETTY_NAME="MOUSE 0.1.0" VERSION="0.1.0" VERSION_ID=0.1.0 -ARCHITECTURE=x86_64 +ARCHITECTURE=@MOUSE_ARCH@ diff --git a/base/rootfs/etc/passwd b/base/rootfs/etc/passwd index f7ecbf7..961b512 100644 --- a/base/rootfs/etc/passwd +++ b/base/rootfs/etc/passwd @@ -1,4 +1,6 @@ root:x:0:0:root:/root:/bin/sh toor:x:0:0:BSD-style root account:/root:/bin/tcsh +mouse:x:1000:1000::/home/mouse:/bin/tcsh dhcpcd:x:101:101:dhcpcd privilege separation:/var/empty:/sbin/nologin _ntp:x:102:102:OpenNTPD privilege separation:/var/empty:/sbin/nologin +greeter:x:108:108:greetd greeter:/var/empty:/sbin/nologin diff --git a/base/rootfs/etc/rc.conf b/base/rootfs/etc/rc.conf index 146271c..8a3cefc 100644 --- a/base/rootfs/etc/rc.conf +++ b/base/rootfs/etc/rc.conf @@ -1,4 +1,8 @@ # Persistent MOUSE service policy belongs in this file. +enable_gardendevd=YES +enable_seatd=YES +enable_greetd=YES enable_network=YES +enable_wpa_supplicant=NO enable_cron=YES enable_ntpd=YES diff --git a/base/rootfs/etc/rc.d/console_login b/base/rootfs/etc/rc.d/console_login index ec790c9..d5a248b 100644 --- a/base/rootfs/etc/rc.d/console_login +++ b/base/rootfs/etc/rc.d/console_login @@ -25,9 +25,7 @@ console_login_start() { /usr/bin/setsid -f /sbin/agetty $autologin \ --login-program /bin/login --noclear --keep-baud \ - 115200,38400,9600 ttyS0 vt100 & - /usr/bin/setsid -f /sbin/agetty $autologin \ - --login-program /bin/login --noclear tty1 linux & + 115200,38400,9600 @MOUSE_CONSOLE@ vt100 & } run_rc_command "$1" diff --git a/base/rootfs/etc/rc.d/gardendevd b/base/rootfs/etc/rc.d/gardendevd new file mode 100644 index 0000000..9d9bbd3 --- /dev/null +++ b/base/rootfs/etc/rc.d/gardendevd @@ -0,0 +1,25 @@ +#!/bin/sh +# PROVIDE: gardendevd DEVFS +# BEFORE: machine_identity + +. /etc/rc.subr + +name=gardendevd +command=/usr/sbin/gardendevd +command_args="-K &" +pidfile=/run/gardendevd.pid +start_postcmd=gardendevd_trigger + +gardendevd_trigger() +{ + for attempt in 1 2 3 4 5; do + /usr/bin/gardendevctl control --ping >/dev/null 2>&1 && break + /bin/sleep 1 + done + /usr/bin/gardendevctl control --ping >/dev/null 2>&1 || return 1 + /usr/bin/gardendevctl trigger --type=subsystems --action=add || return $? + /usr/bin/gardendevctl trigger --type=devices --action=add || return $? + /usr/bin/gardendevctl settle -t 30 +} + +run_rc_command "$1" diff --git a/base/rootfs/etc/rc.d/mdevd b/base/rootfs/etc/rc.d/mdevd deleted file mode 100644 index c368e0d..0000000 --- a/base/rootfs/etc/rc.d/mdevd +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -# PROVIDE: mdevd DEVFS -# BEFORE: machine_identity - -. /etc/rc.subr - -name=mdevd -command=/sbin/mdevd -command_args="-C &" - -run_rc_command "$1" diff --git a/base/rootfs/etc/rc.d/network b/base/rootfs/etc/rc.d/network index a5fc987..ef464a0 100644 --- a/base/rootfs/etc/rc.d/network +++ b/base/rootfs/etc/rc.d/network @@ -9,7 +9,6 @@ name=network command=/sbin/dhcpcd command_args="-4 -b -q -c /usr/libexec/mouse-dhcpcd-hook" start_precmd=network_prestart -start_postcmd=network_poststart stop_postcmd=network_poststop network_prestart() @@ -17,19 +16,6 @@ network_prestart() rm -f /run/mouse-network.ready } -network_poststart() -{ - waited=0 - while [ ! -f /run/mouse-network.ready ]; do - if [ "$waited" -ge 20 ]; then - echo "timed out waiting for an IPv4 DHCP lease" >&2 - return 1 - fi - sleep 1 - waited=$((waited + 1)) - done -} - network_poststop() { rm -f /run/mouse-network.ready diff --git a/base/rootfs/etc/rc.d/wpa_supplicant b/base/rootfs/etc/rc.d/wpa_supplicant new file mode 100644 index 0000000..07bafb2 --- /dev/null +++ b/base/rootfs/etc/rc.d/wpa_supplicant @@ -0,0 +1,12 @@ +#!/bin/sh +# PROVIDE: wpa_supplicant WIRELESS +# REQUIRE: DAEMON +# BEFORE: NETWORKING LOGIN + +. /etc/rc.subr + +name=wpa_supplicant +command=/usr/libexec/mouse-wpa-supplicant +command_args="&" + +run_rc_command "$1" diff --git a/base/rootfs/etc/rc.subr b/base/rootfs/etc/rc.subr new file mode 100644 index 0000000..73412c8 --- /dev/null +++ b/base/rootfs/etc/rc.subr @@ -0,0 +1,1008 @@ +# $NetBSD: rc.subr,v 1.19 2025/04/21 21:12:57 wiz Exp $ +# +# Copyright (c) 1997-2002 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Luke Mewburn. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# rc.subr +# functions used by various rc scripts +# + +# global variables +# ---------------- + +sysconfbase=@SYSCONFBASE@ +_RCCMD_chown="/usr/sbin/chown" +_RCCMD_chroot="/usr/sbin/chroot" +_RCCMD_ci="/usr/bin/ci" +_RCCMD_co="/usr/bin/co" +_RCCMD_cp="/bin/cp" +_RCCMD_echo="echo" # use sh builtin +_RCCMD_kill="/bin/kill" +_RCCMD_logger="/usr/bin/logger" +_RCCMD_mount="/sbin/mount" +_RCCMD_mv="/bin/mv" +_RCCMD_nice="/usr/bin/nice" +_RCCMD_ps="/bin/ps" +_RCCMD_rcs="/usr/bin/rcs" +_RCCMD_rm="/bin/rm" +_RCCMD_sh="/bin/sh" +_RCCMD_su="/usr/bin/su" +_RCCMD_systrace="/bin/systrace" +_RCCMD_whoami="/usr/bin/whoami" + +_RCARG_psformat="-o pid,command" +_RCARG_ps="-ax" +_RCARG_su="-m" + +_osname=$(uname -s) +_osrelease=$(uname -r) +case $_osname in + Darwin) + _RCCMD_echo="/bin/echo" + ;; + SunOS) + _RCCMD_chown="/bin/chown" +# _RCCMD_ci="/usr/bin/ci" # not in Solaris 9 +# _RCCMD_co="/usr/bin/co" # not in Solaris 9 +# _RCCMD_systrace="/bin/systrace" # not in Solaris 9 + _RCARG_psformat="-o pid,comm" + _RCARG_ps="-ef" + _RCARG_su="" + if [ "$_osrelease" = "5.11" ]; then + bsd_echo () { + if [ "$1" = "-n" ]; then + shift; echo "$@\c" + else + echo "$@" + fi + } + _RCCMD_echo="bsd_echo" + else + _RCCMD_echo="/usr/ucb/echo" # not in Solaris 11 + _RCCMD_whoami="/usr/ucb/whoami" # not in Solaris 11 + fi + ;; + IRIX*) + _RCCMD_chown="/sbin/chown" + _RCCMD_ci="/usr/sbin/ci" + _RCCMD_co="/usr/sbin/co" + _RCCMD_cp="/sbin/cp" + _RCCMD_kill="kill" # use sh builtin +# _RCCMD_logger="/usr/bin/logger" # not in IRIX + _RCCMD_mv="/sbin/mv" + _RCCMD_nice="/sbin/nice" + _RCCMD_ps="/sbin/ps" + _RCCMD_rcs="/usr/sbin/rcs" + _RCCMD_rm="/sbin/rm" + _RCCMD_sh="/sbin/sh" + _RCCMD_su="/sbin/su" +# _RCCMD_systrace="/bin/systrace" # not in IRIX + _RCCMD_whoami="/bin/whoami" + _RCARG_psformat="-o pid,comm=12345678901234567890" + # widen column to try to get full command-name + _RCARG_ps="-ef" + _RCARG_su="" + ;; + Linux) + _RCCMD_chown="/bin/chown" +# _RCCMD_ci="/usr/bin/ci" # not in Slackware 8.1 +# _RCCMD_co="/usr/bin/co" # not in Slackware 8.1 + if [ ! -f /etc/arch-release ] ; then # which not in Arch + _RCCMD_nice=$(which nice) + fi +# _RCCMD_rcs="/usr/bin/rcs" # not in Slackware 8.1 +# _RCCMD_systrace="/bin/systrace" # not in Slackware 8.1 + _RCARG_ps="ax" + if [ -e /etc/redhat-release ]; then + _RCCMD_su="/bin/su" # for CentOS/RHEL + fi + ;; + QNX) + _RCCMD_chown="/bin/chown" +# _RCCMD_ci="/usr/bin/ci" # not in QNX +# _RCCMD_co="/usr/bin/co" # not in QNX +# _RCCMD_systrace="/bin/systrace" # not in QNX + _RCCMD_whoami="/usr/bin/id -un" + _RCARG_psformat="-o pid,comm" + _RCARG_ps="-ef" + _RCARG_su="" + ;; +esac + +# +# functions +# --------- + +# +# checkyesno var +# Test $1 variable, and warn if not set to YES or NO. +# Return 0 if it's "yes" (et al), nonzero otherwise. +# +checkyesno() +{ + eval _value=\$${1} + case $_value in + + # "yes", "true", "on", or "1" + [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) + return 0 + ;; + + # "no", "false", "off", or "0" + [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) + return 1 + ;; + *) + warn "\$${1} is not set properly - see rc.conf(5)." + return 1 + ;; + esac +} + +# reverse_list list +# print the list in reverse order +# +reverse_list() +{ + _revlist= + for _revfile; do + _revlist="$_revfile $_revlist" + done + ${_RCCMD_echo} $_revlist +} + +# +# mount_critical_filesystems type +# Go through the list of critical filesystems as provided in +# the rc.conf(5) variable $critical_filesystems_${type}, checking +# each one to see if it is mounted, and if it is not, mounting it. +# +mount_critical_filesystems() +{ + eval _fslist=\$critical_filesystems_${1} + for _fs in $_fslist; do + ${_RCCMD_mount} | ( + _ismounted=false + while read what _on on _type type; do + if [ $on = $_fs ]; then + _ismounted=true + fi + done + if $_ismounted; then + : + else + ${_RCCMD_mount} $_fs >/dev/null 2>&1 + fi + ) + done +} + +# +# check_pidfile pidfile procname [interpreter] +# Parses the first line of pidfile for a PID, and ensures +# that the process is running and matches procname. +# Prints the matching PID upon success, nothing otherwise. +# interpreter is optional; see _find_processes() for details. +# +check_pidfile() +{ + _pidfile=$1 + _procname=$2 + _interpreter=$3 + if [ -z "$_pidfile" -o -z "$_procname" ]; then + err 3 'USAGE: check_pidfile pidfile procname [interpreter]' + fi + if [ ! -f $_pidfile ]; then + return + fi + read _pid _junk < $_pidfile + if [ -z "$_pid" ]; then + return + fi + _find_processes $_procname ${_interpreter:-.} '-p '"$_pid" +} + +# +# check_process procname [interpreter] +# Ensures that a process (or processes) named procname is running. +# Prints a list of matching PIDs. +# interpreter is optional; see _find_processes() for details. +# +check_process() +{ + _procname=$1 + _interpreter=$2 + if [ -z "$_procname" ]; then + err 3 'USAGE: check_process procname [interpreter]' + fi + _find_processes $_procname ${_interpreter:-.} ${_RCARG_ps} +} + +# +# _find_processes procname interpreter psargs +# Search for procname in the output of ps generated by psargs. +# Prints the PIDs of any matching processes, space separated. +# +# If interpreter == ".", check the following variations of procname +# against the first word of each command: +# procname +# `basename procname` +# `basename procname` + ":" +# "(" + `basename procname` + ")" +# +# If interpreter != ".", read the first line of procname, remove the +# leading #!, normalise whitespace, append procname, and attempt to +# match that against each command, either as is, or with extra words +# at the end. +# +_find_processes() +{ + if [ $# -ne 3 ]; then + err 3 'USAGE: _find_processes procname interpreter psargs' + fi + _procname=$1 + _interpreter=$2 + _psargs=$3 + + _pref= + if [ $_interpreter != "." ]; then # an interpreted script + read _interp < $_procname # read interpreter name + _interp=${_interp#\#!} # strip #! + set -- $_interp + if [ $_interpreter != $1 ]; then + warn "\$command_interpreter $_interpreter != $1" + fi + _interp="$* $_procname" # cleanup spaces, add _procname + _fp_args='_argv' + _fp_match='case "$_argv" in + ${_interp}|"${_interp} "*)' + else # a normal daemon + _procnamebn=${_procname##*/} + _fp_args='_arg0 _argv' + _fp_match='case "$_arg0" in + $_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})"|"[${_procnamebn}]")' + fi + + _proccheck=' + ${_RCCMD_ps} ${_RCARG_psformat} '"$_psargs"' | + while read _npid '"$_fp_args"'; do + case "$_npid" in + PID) + continue ;; + esac ; '"$_fp_match"' + ${_RCCMD_echo} -n "$_pref$_npid" ; + _pref=" " + ;; + esac + done' + + eval $_proccheck +} + +# +# wait_for_pids pid [pid ...] +# spins until none of the pids exist +# +wait_for_pids() +{ + _list="$@" + if [ -z "$_list" ]; then + return + fi + _prefix= + while true; do + _nlist=""; + for _j in $_list; do + if ${_RCCMD_kill} -0 $_j 2>/dev/null; then + _nlist="${_nlist}${_nlist:+ }$_j" + fi + done + if [ -z "$_nlist" ]; then + break + fi + _list=$_nlist + ${_RCCMD_echo} -n ${_prefix:-"Waiting for PIDS: "}$_list + _prefix=", " + sleep 2 + done + if [ -n "$_prefix" ]; then + ${_RCCMD_echo} "." + fi +} + +# +# run_rc_command argument +# Search for argument in the list of supported commands, which is: +# "start stop restart rcvar status poll ${extra_commands}" +# If there's a match, run ${argument}_cmd or the default method +# (see below). +# +# If argument has a given prefix, then change the operation as follows: +# Prefix Operation +# ------ --------- +# fast Skip the pid check, and set rc_fast=yes +# force Set ${rcvar} to YES, and set rc_force=yes +# +# The following globals are used: +# +# Name Needed Purpose +# ---- ------ ------- +# name y Name of script. +# +# command n Full path to command. +# Not needed if ${rc_arg}_cmd is set for +# each keyword. +# +# command_args n Optional args/shell directives for command. +# +# command_interpreter n If not empty, command is interpreted, so +# call check_{pidfile,process}() appropriately. +# +# extra_commands n List of extra commands supported. +# +# pidfile n If set, use check_pidfile $pidfile $command, +# otherwise use check_process $command. +# In either case, only check if $command is set. +# +# procname n Process name to check for instead of $command. +# +# rcvar n This is checked with checkyesno to determine +# if the action should be run. +# +# ${name}_chroot n Directory to chroot to before running ${command} +# Requires /usr to be mounted. +# +# ${name}_chdir n Directory to cd to before running ${command} +# (if not using ${name}_chroot). +# +# ${name}_flags n Arguments to call ${command} with. +# NOTE: $flags from the parent environment +# can be used to override this. +# +# ${name}_nice n Nice level to run ${command} at. +# +# ${name}_user n User to run ${command} as, using su(1) if not +# using ${name}_chroot. +# Requires /usr to be mounted. +# +# ${name}_group n Group to run chrooted ${command} as. +# Requires /usr to be mounted. +# +# ${name}_groups n Comma separated list of supplementary groups +# to run the chrooted ${command} with. +# Requires /usr to be mounted. +# +# ${name}_systrace n Flags passed to systrace(1) if it is used. +# Setting this variable enables systracing +# of the given program. The use of "-a" is +# recommended so that the boot process is not +# stalled. In order to pass no flags to +# systrace, set this variable to "--". +# +# ${rc_arg}_cmd n If set, use this as the method when invoked; +# Otherwise, use default command (see below) +# +# ${rc_arg}_precmd n If set, run just before performing the +# ${rc_arg}_cmd method in the default +# operation (i.e, after checking for required +# bits and process (non)existence). +# If this completes with a non-zero exit code, +# don't run ${rc_arg}_cmd. +# +# ${rc_arg}_postcmd n If set, run just after performing the +# ${rc_arg}_cmd method, if that method +# returned a zero exit code. +# +# required_dirs n If set, check for the existence of the given +# directories before running the default +# (re)start command. +# +# required_files n If set, check for the readability of the given +# files before running the default (re)start +# command. +# +# required_vars n If set, perform checkyesno on each of the +# listed variables before running the default +# (re)start command. +# +# Default behaviour for a given argument, if no override method is +# provided: +# +# Argument Default behaviour +# -------- ----------------- +# start if !running && checkyesno ${rcvar} +# ${command} +# +# stop if ${pidfile} +# rc_pid=$(check_pidfile $pidfile $command) +# else +# rc_pid=$(check_process $command) +# kill $sig_stop $rc_pid +# wait_for_pids $rc_pid +# ($sig_stop defaults to TERM.) +# +# reload Similar to stop, except use $sig_reload instead, +# and doesn't wait_for_pids. +# $sig_reload defaults to HUP. +# +# restart Run `stop' then `start'. +# +# status Show if ${command} is running, etc. +# +# poll Wait for ${command} to exit. +# +# rcvar Display what rc.conf variable is used (if any). +# +# Variables available to methods, and after run_rc_command() has +# completed: +# +# Variable Purpose +# -------- ------- +# rc_arg Argument to command, after fast/force processing +# performed +# +# rc_flags Flags to start the default command with. +# Defaults to ${name}_flags, unless overridden +# by $flags from the environment. +# This variable may be changed by the precmd method. +# +# rc_pid PID of command (if appropriate) +# +# rc_fast Not empty if "fast" was provided (q.v.) +# +# rc_force Not empty if "force" was provided (q.v.) +# +# +run_rc_command() +{ + rc_arg=$1 + if [ -z "$name" ]; then + err 3 'run_rc_command: $name is not set.' + fi + + case "$rc_arg" in + fast*) # "fast" prefix; don't check pid + rc_arg=${rc_arg#fast} + rc_fast=yes + ;; + force*) # "force prefix; always start + rc_arg=${rc_arg#force} + rc_force=yes + if [ -n "${rcvar}" ]; then + eval ${rcvar}=YES + fi + ;; + esac + + _keywords="start stop restart rcvar $extra_commands" + rc_pid= + _pidcmd= + _procname=${procname:-${command}} + + # setup pid check command if not fast + if [ -z "$rc_fast" -a -n "$_procname" ]; then + if [ -n "$pidfile" ]; then + _pidcmd='rc_pid=$(check_pidfile '"$pidfile $_procname $command_interpreter"')' + else + _pidcmd='rc_pid=$(check_process '"$_procname $command_interpreter"')' + fi + if [ -n "$_pidcmd" ]; then + _keywords="${_keywords} status poll" + fi + fi + + if [ -z "$rc_arg" ]; then + rc_usage "$_keywords" + fi + + if [ -n "$flags" ]; then # allow override from environment + rc_flags=$flags + else + eval rc_flags=\$${name}_flags + fi + eval _chdir=\$${name}_chdir _chroot=\$${name}_chroot \ + _nice=\$${name}_nice _user=\$${name}_user \ + _group=\$${name}_group _groups=\$${name}_groups \ + _systrace=\$${name}_systrace + + if [ -n "$_user" ]; then # unset $_user if running as that user + if [ "$_user" = "$($_RCCMD_whoami)" ]; then + unset _user + fi + fi + + # if ${rcvar} is set, and $1 is not + # "rcvar", then run + # checkyesno ${rcvar} + # and return if that failed + # + if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" ]; then + if ! checkyesno ${rcvar}; then + return 0 + fi + fi + + eval $_pidcmd # determine the pid if necessary + + for _elem in $_keywords; do + if [ "$_elem" != "$rc_arg" ]; then + continue + fi + + # if there's a custom ${XXX_cmd}, + # run that instead of the default + # + eval _cmd=\$${rc_arg}_cmd _precmd=\$${rc_arg}_precmd \ + _postcmd=\$${rc_arg}_postcmd + if [ -n "$_cmd" ]; then + # if the precmd failed and force + # isn't set, exit + # + if ! eval $_precmd && [ -z "$rc_force" ]; then + return 1 + fi + + if ! eval $_cmd && [ -z "$rc_force" ]; then + return 1 + fi + eval $_postcmd + return 0 + fi + + case "$rc_arg" in # default operations... + + status) + if [ -n "$rc_pid" ]; then + ${_RCCMD_echo} \ + "${name} is running as pid $rc_pid." + else + ${_RCCMD_echo} "${name} is not running." + return 1 + fi + ;; + + start) + if [ -n "$rc_pid" ]; then + ${_RCCMD_echo} \ + "${name} already running? (pid=$rc_pid)." + exit 1 + fi + + if [ ! -x ${_chroot}${command} ]; then + return 0 + fi + + # check for required variables, + # directories, and files + # + for _f in $required_vars; do + if ! checkyesno $_f; then + warn "\$${_f} is not set." + if [ -z "$rc_force" ]; then + return 1 + fi + fi + done + for _f in $required_dirs; do + if [ ! -d "${_f}/." ]; then + warn "${_f} is not a directory." + if [ -z "$rc_force" ]; then + return 1 + fi + fi + done + for _f in $required_files; do + if [ ! -r "${_f}" ]; then + warn "${_f} is not readable." + if [ -z "$rc_force" ]; then + return 1 + fi + fi + done + + # if the precmd failed and force + # isn't set, exit + # + if ! eval $_precmd && [ -z "$rc_force" ]; then + return 1 + fi + + # setup the command to run, and run it + # + ${_RCCMD_echo} "Starting ${name}." + if [ -n "$_chroot" ]; then + if [ "$_osname" = "SunOS" ]; then + _doit="\ +${_nice:+${_RCCMD_nice} -n $_nice }\ +${_RCCMD_chroot} $_chroot" + if [ -n "$_user" ]; then + _doit="\ +$_doit ${_RCCMD_su} ${_RCARG_su} $_user \ +-c '${_RCCMD_sh} -c'" + fi + _doit="\ +$_doit $command $rc_flags $command_args" + else + _doit="\ +${_nice:+${_RCCMD_nice} -n $_nice }\ +${_systrace:+${_RCCMD_systrace} $_systrace }\ +${_RCCMD_chroot} ${_user:+-u $_user }${_group:+-g $_group }\ +${_groups:+-G $_groups } $_chroot $command $rc_flags $command_args" + fi + else + _doit="\ +${_chdir:+cd $_chdir; }\ +${_nice:+${_RCCMD_nice} -n $_nice }\ +${_systrace:+${_RCCMD_systrace} $_systrace }\ +$command $rc_flags $command_args" + if [ -n "$_user" ]; then + _doit="${_RCCMD_su} ${_RCARG_su} $_user \ + -c '${_RCCMD_sh} -c \"$_doit\"'" + fi + fi + + # if the cmd failed and force + # isn't set, exit + # + if ! eval $_doit && [ -z "$rc_force" ]; then + return 1 + fi + + # finally, run postcmd + # + eval $_postcmd + ;; + + stop) + if [ -z "$rc_pid" ]; then + if [ -n "$pidfile" ]; then + ${_RCCMD_echo} \ + "${name} not running? (check $pidfile)." + else + ${_RCCMD_echo} "${name} not running?" + fi + exit 1 + fi + + # if the precmd failed and force + # isn't set, exit + # + if ! eval $_precmd && [ -z "$rc_force" ]; then + return 1 + fi + + # send the signal to stop + # + ${_RCCMD_echo} "Stopping ${name}." + _doit="${_RCCMD_kill} -${sig_stop:-TERM} $rc_pid" + if [ -n "$_user" ]; then + _doit="${_RCCMD_su} ${_RCARG_su} $_user \ + -c '${_RCCMD_sh} -c \"$_doit\"'" + fi + + # if the stop cmd failed and force + # isn't set, exit + # + if ! eval $_doit && [ -z "$rc_force" ]; then + return 1 + fi + + # wait for the command to exit, + # and run postcmd. + wait_for_pids $rc_pid + eval $_postcmd + ;; + + reload) + if [ -z "$rc_pid" ]; then + if [ -n "$pidfile" ]; then + ${_RCCMD_echo} \ + "${name} not running? (check $pidfile)." + else + ${_RCCMD_echo} "${name} not running?" + fi + exit 1 + fi + ${_RCCMD_echo} "Reloading ${name} config files." + if ! eval $_precmd && [ -z "$rc_force" ]; then + return 1 + fi + _doit="${_RCCMD_kill} -${sig_reload:-HUP} $rc_pid" + if [ -n "$_user" ]; then + _doit="${_RCCMD_su} ${_RCARG_su} $_user -c '${_RCCMD_sh} -c \"$_doit\"'" + fi + if ! eval $_doit && [ -z "$rc_force" ]; then + return 1 + fi + eval $_postcmd + ;; + + restart) + if ! eval $_precmd && [ -z "$rc_force" ]; then + return 1 + fi + # prevent restart being called more + # than once by any given script + # + if ${_rc_restart_done:-false}; then + return 0 + fi + _rc_restart_done=true + + ( $0 ${rc_force:+force}stop ) + $0 ${rc_force:+force}start + + eval $_postcmd + ;; + + poll) + if [ -n "$rc_pid" ]; then + wait_for_pids $rc_pid + fi + ;; + + rcvar) + ${_RCCMD_echo} "# $name" + if [ -n "$rcvar" ]; then + if checkyesno ${rcvar}; then + ${_RCCMD_echo} "\$${rcvar}=YES" + else + ${_RCCMD_echo} "\$${rcvar}=NO" + fi + fi + ;; + + *) + rc_usage "$_keywords" + ;; + + esac + return 0 + done + + ${_RCCMD_echo} 1>&2 "$0: unknown directive '$rc_arg'." + rc_usage "$_keywords" + exit 1 +} + +# +# run_rc_script file arg +# Start the script `file' with `arg', and correctly handle the +# return value from the script. If `file' ends with `.sh', it's +# sourced into the current environment. If `file' appears to be +# a backup or scratch file, ignore it. Otherwise if it's +# executable run as a child process. +# +run_rc_script() +{ + _file=$1 + _arg=$2 + if [ -z "$_file" -o -z "$_arg" ]; then + err 3 'USAGE: run_rc_script file arg' + fi + + unset name command command_args command_interpreter \ + extra_commands pidfile procname \ + rcvar required_dirs required_files required_vars + eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd + + case "$_file" in + *.sh) # run in current shell + set $_arg ; . $_file + ;; + *[~#]|*.OLD|*.orig) # scratch file; skip + warn "Ignoring scratch file $_file" + ;; + *) # run in subshell + if [ -x $_file ]; then + if [ -n "$rc_fast_and_loose" ]; then + set $_arg ; . $_file + else + ( set $_arg ; . $_file ) + fi + fi + ;; + esac +} + +# +# load_rc_config +# Source in the configuration file for a given command. +# +load_rc_config() +{ + _command=$1 + if [ -z "$_command" ]; then + err 3 'USAGE: load_rc_config command' + fi + + if ${_rc_conf_loaded:-false}; then + : + else + . ${sysconfbase}/rc.conf + _rc_conf_loaded=true + fi + if [ "$_osname" = "OpenBSD" ] && [ -f ${sysconfbase}/rc.conf.local ]; then + . ${sysconfbase}/rc.conf.local + fi + if [ -f ${sysconfbase}/rc.conf.d/"$_command" ]; then + . ${sysconfbase}/rc.conf.d/"$_command" + fi +} + +# +# load_rc_config_var cmd var +# Read the rc.conf(5) var for cmd and set in the +# current shell, using load_rc_config in a subshell to prevent +# unwanted side effects from other variable assignments. +# +load_rc_config_var() +{ + if [ $# -ne 2 ]; then + err 3 'USAGE: load_rc_config_var cmd var' + fi + eval $(eval '( + load_rc_config '$1' >/dev/null; + if [ -n "${'$2'}" ] || [ "${'$2'-UNSET}" != "UNSET" ]; then + echo '$2'=\'\''${'$2'}\'\''; + fi + )' ) +} + + +# +# rc_usage commands +# Print a usage string for $0, with `commands' being a list of +# valid commands. +# +rc_usage() +{ + ${_RCCMD_echo} -n 1>&2 "Usage: $0 [fast|force](" + + _sep= + for _elem; do + ${_RCCMD_echo} -n 1>&2 "$_sep$_elem" + _sep="|" + done + ${_RCCMD_echo} 1>&2 ")" + exit 1 +} + +# +# err exitval message +# Display message to stderr and log to the syslog, and exit with exitval. +# +err() +{ + exitval=$1 + shift + + if [ -x ${_RCCMD_logger} ]; then + ${_RCCMD_logger} "$0: ERROR: $*" + fi + ${_RCCMD_echo} 1>&2 "$0: ERROR: $*" + exit $exitval +} + +# +# warn message +# Display message to stderr and log to the syslog. +# +warn() +{ + if [ -x ${_RCCMD_logger} ]; then + ${_RCCMD_logger} "$0: WARNING: $*" + fi + ${_RCCMD_echo} 1>&2 "$0: WARNING: $*" +} + +# +# backup_file action file cur backup +# Make a backup copy of `file' into `cur', and save the previous +# version of `cur' as `backup' or use rcs for archiving. +# +# This routine checks the value of the backup_uses_rcs variable, +# which can be either YES or NO. +# +# The `action' keyword can be one of the following: +# +# add `file' is now being backed up (and is possibly +# being reentered into the backups system). `cur' +# is created and RCS files, if necessary, are +# created as well. +# +# update `file' has changed and needs to be backed up. +# If `cur' exists, it is copied to to `back' or +# checked into RCS (if the repository file is old), +# and then `file' is copied to `cur'. Another RCS +# check in done here if RCS is being used. +# +# remove `file' is no longer being tracked by the backups +# system. If RCS is not being used, `cur' is moved +# to `back', otherwise an empty file is checked in, +# and then `cur' is removed. +# +# +backup_file() +{ + _action=$1 + _file=$2 + _cur=$3 + _back=$4 + + if checkyesno backup_uses_rcs; then + _msg0="backup archive" + _msg1="update" + + # ensure that history file is not locked + if [ -f $_cur,v ]; then + ${_RCCMD_rcs} -q -u -U -M $_cur + fi + + # ensure after switching to rcs that the + # current backup is not lost + if [ -f $_cur ]; then + # no archive, or current newer than archive + if [ ! -f $_cur,v -o $_cur -nt $_cur,v ]; then + ${_RCCMD_ci} -q -f -u -t-"$_msg0" \ + -m"$_msg1" $_cur + ${_RCCMD_rcs} -q -kb -U $_cur + ${_RCCMD_co} -q -f -u $_cur + fi + fi + + case $_action in + add|update) + ${_RCCMD_cp} -p $_file $_cur + ${_RCCMD_ci} -q -f -u -t-"$_msg0" -m"$_msg1" $_cur + ${_RCCMD_rcs} -q -kb -U $_cur + ${_RCCMD_co} -q -f -u $_cur + ${_RCCMD_chown} root:wheel $_cur $_cur,v + ;; + remove) + ${_RCCMD_cp} /dev/null $_cur + ${_RCCMD_ci} -q -f -u -t-"$_msg0" -m"$_msg1" $_cur + ${_RCCMD_rcs} -q -kb -U $_cur + ${_RCCMD_chown} root:wheel $_cur $_cur,v + ${_RCCMD_rm} $_cur + ;; + esac + else + case $_action in + add|update) + if [ -f $_cur ]; then + ${_RCCMD_cp} -p $_cur $_back + fi + ${_RCCMD_cp} -p $_file $_cur + ${_RCCMD_chown} root:wheel $_cur + ;; + remove) + ${_RCCMD_mv} -f $_cur $_back + ;; + esac + fi +} diff --git a/base/rootfs/etc/securetty b/base/rootfs/etc/securetty index 360e925..3e1b877 100644 --- a/base/rootfs/etc/securetty +++ b/base/rootfs/etc/securetty @@ -1 +1 @@ -ttyS0 +@MOUSE_CONSOLE@ diff --git a/base/rootfs/etc/shadow b/base/rootfs/etc/shadow index 29c8380..55e048f 100644 --- a/base/rootfs/etc/shadow +++ b/base/rootfs/etc/shadow @@ -1,4 +1,6 @@ -root:$6$mouse$LofYSsSObtmx/zmS97A.TFONKSQSATXE4bD6dY1H7JSBSayuyAuc4Qwpm7JdfW9lUnri9DrQfUKGiLTNKA3v81:1:0:99999:7::: -toor:$6$mouse$LofYSsSObtmx/zmS97A.TFONKSQSATXE4bD6dY1H7JSBSayuyAuc4Qwpm7JdfW9lUnri9DrQfUKGiLTNKA3v81:1:0:99999:7::: +root:!:1:0:99999:7::: +toor:!:1:0:99999:7::: +mouse:$6$mouse$LofYSsSObtmx/zmS97A.TFONKSQSATXE4bD6dY1H7JSBSayuyAuc4Qwpm7JdfW9lUnri9DrQfUKGiLTNKA3v81:1:0:99999:7::: dhcpcd:!:1:0:99999:7::: _ntp:!:1:0:99999:7::: +greeter:!:1:0:99999:7::: diff --git a/base/rootfs/etc/wpa_supplicant/wpa_supplicant.conf b/base/rootfs/etc/wpa_supplicant/wpa_supplicant.conf new file mode 100644 index 0000000..1f5df17 --- /dev/null +++ b/base/rootfs/etc/wpa_supplicant/wpa_supplicant.conf @@ -0,0 +1,2 @@ +ctrl_interface=/run/wpa_supplicant +update_config=0 diff --git a/base/rootfs/usr/lib/mouse/required-services b/base/rootfs/usr/lib/mouse/required-services index 4985ce6..8fb0edb 100644 --- a/base/rootfs/usr/lib/mouse/required-services +++ b/base/rootfs/usr/lib/mouse/required-services @@ -1,6 +1,5 @@ machine_identity loopback -mdevd syslogd daemon login diff --git a/base/rootfs/usr/libexec/mouse-wpa-supplicant b/base/rootfs/usr/libexec/mouse-wpa-supplicant new file mode 100644 index 0000000..b84c849 --- /dev/null +++ b/base/rootfs/usr/libexec/mouse-wpa-supplicant @@ -0,0 +1,21 @@ +#!/bin/sh +set -eu + +config=/etc/wpa_supplicant/wpa_supplicant.conf +if [ ! -s "$config" ]; then + printf '%s\n' "missing wpa_supplicant configuration: $config" >&2 + exit 1 +fi + +while :; do + for interface_path in /sys/class/net/*; do + if [ -d "$interface_path/wireless" ]; then + interface=${interface_path##*/} + exec /sbin/wpa_supplicant \ + -Dnl80211 \ + -i "$interface" \ + -c "$config" + fi + done + sleep 1 +done diff --git a/base/support/cross-compiler-driver b/base/support/cross-compiler-driver index 99269d7..bc1f0d2 100755 --- a/base/support/cross-compiler-driver +++ b/base/support/cross-compiler-driver @@ -16,6 +16,7 @@ fi IFS= read -r linker IFS= read -r builtins IFS= read -r rust_eh_personality + IFS= read -r target } <"$config" cxx_runtime=no @@ -61,7 +62,7 @@ done if [ "$link" = compile ]; then exec "$compiler" \ - --target=x86_64-unknown-linux-musl \ + --target="$target" \ --sysroot="$sysroot" \ "$@" fi @@ -71,7 +72,7 @@ fi # executables and must not inherit the static base link recipe below. if [ "$link" = shared ] || [ "$link" = relocatable ]; then exec "$compiler" \ - --target=x86_64-unknown-linux-musl \ + --target="$target" \ --sysroot="$sysroot" \ --ld-path="$linker" \ "$@" @@ -81,7 +82,7 @@ fi # -nostartfiles, so the caller supplies everything needed for startup. if [ "$caller_startup" = yes ]; then exec "$compiler" \ - --target=x86_64-unknown-linux-musl \ + --target="$target" \ --sysroot="$sysroot" \ --ld-path="$linker" \ -nostdlib \ @@ -97,7 +98,7 @@ fi if [ "$cxx_runtime" = yes ]; then exec "$compiler" \ - --target=x86_64-unknown-linux-musl \ + --target="$target" \ --sysroot="$sysroot" \ --ld-path="$linker" \ -nostdlib \ @@ -119,7 +120,7 @@ if [ "$cxx_runtime" = yes ]; then fi exec "$compiler" \ - --target=x86_64-unknown-linux-musl \ + --target="$target" \ --sysroot="$sysroot" \ --ld-path="$linker" \ -nostdlib \ diff --git a/base/support/mouse-auth.c b/base/support/mouse-auth.c new file mode 100644 index 0000000..fae1f86 --- /dev/null +++ b/base/support/mouse-auth.c @@ -0,0 +1,118 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USERNAME_CAP 256 +#define PASSWORD_CAP 4096 + +static const char dummy_hash[] = + "$6$mouse$LofYSsSObtmx/zmS97A.TFONKSQSATXE4bD6dY1H7JSBSayuyAuc4Qwpm7JdfW9lUnri9DrQfUKGiLTNKA3v81"; + +static void wipe(void *buffer, size_t length) +{ + volatile unsigned char *bytes = buffer; + + while (length-- > 0) + *bytes++ = 0; +} + +static bool read_field(char *buffer, size_t capacity) +{ + size_t length = 0; + + for (;;) { + unsigned char byte; + ssize_t count = read(STDIN_FILENO, &byte, 1); + + if (count == 0 || (count < 0 && errno != EINTR)) + return false; + if (count < 0) + continue; + if (byte == '\n') { + buffer[length] = '\0'; + return length > 0; + } + if (byte == '\0' || length + 1 >= capacity) + return false; + buffer[length++] = (char)byte; + } +} + +static bool input_finished(void) +{ + unsigned char byte; + ssize_t count; + + do { + count = read(STDIN_FILENO, &byte, 1); + } while (count < 0 && errno == EINTR); + return count == 0; +} + +static bool hashes_equal(const char *left, const char *right) +{ + size_t left_length = strlen(left); + size_t right_length = strlen(right); + size_t length = left_length > right_length ? left_length : right_length; + size_t difference = left_length ^ right_length; + + for (size_t index = 0; index < length; index++) { + unsigned char left_byte = index < left_length ? (unsigned char)left[index] : 0; + unsigned char right_byte = index < right_length ? (unsigned char)right[index] : 0; + difference |= (size_t)(left_byte ^ right_byte); + } + return difference == 0; +} + +int main(void) +{ + char username[USERNAME_CAP] = {0}; + char password[PASSWORD_CAP] = {0}; + char passwd_buffer[16384]; + char shadow_buffer[16384]; + struct passwd passwd_entry; + struct passwd *passwd_result = NULL; + struct spwd shadow_entry; + struct spwd *shadow_result = NULL; + struct crypt_data crypt_data = {0}; + const char *stored_hash = dummy_hash; + bool account_allowed = false; + bool authenticated = false; + + if (geteuid() != 0) + goto out; + if (!read_field(username, sizeof(username)) || + !read_field(password, sizeof(password)) || !input_finished()) + goto out; + + if (getpwnam_r(username, &passwd_entry, passwd_buffer, + sizeof(passwd_buffer), &passwd_result) == 0 && passwd_result != NULL && + getspnam_r(username, &shadow_entry, shadow_buffer, + sizeof(shadow_buffer), &shadow_result) == 0 && shadow_result != NULL && + passwd_entry.pw_uid != 0 && shadow_entry.sp_pwdp != NULL && + shadow_entry.sp_pwdp[0] != '\0' && shadow_entry.sp_pwdp[0] != '!' && + shadow_entry.sp_pwdp[0] != '*') { + stored_hash = shadow_entry.sp_pwdp; + account_allowed = true; + } + + char *candidate_hash = crypt_r(password, stored_hash, &crypt_data); + if (candidate_hash != NULL) + authenticated = account_allowed && hashes_equal(candidate_hash, stored_hash); + +out: + wipe(password, sizeof(password)); + wipe(&crypt_data, sizeof(crypt_data)); + wipe(shadow_buffer, sizeof(shadow_buffer)); + wipe(passwd_buffer, sizeof(passwd_buffer)); + wipe(username, sizeof(username)); + return authenticated ? 0 : 1; +} diff --git a/base/support/mouse-package b/base/support/mouse-package new file mode 100755 index 0000000..58a451c --- /dev/null +++ b/base/support/mouse-package @@ -0,0 +1,84 @@ +#!/bin/sh +set -eu + +database=/var/db/mouse/packages + +fail() +{ + printf '%s\n' "mouse-package: $*" >&2 + exit 1 +} + +safe_path() +{ + case "$1" in + ""|/*|.|..|../*|*/../*|*/..|./*|*/./*) return 1 ;; + *) return 0 ;; + esac +} + +manifest_value() +{ + sed -n "s/^$1=//p" "$2/+MANIFEST" +} + +add_package() +{ + package=$1 + [ -f "$package/+MANIFEST" ] || fail "missing package manifest" + [ -f "$package/+PLIST" ] || fail "missing packing list" + [ -d "$package/root/usr/local" ] || fail "payload escapes /usr/local" + name=$(manifest_value name "$package") + version=$(manifest_value version "$package") + case "$name:$version" in + *[!A-Za-z0-9._+:-]*) fail "invalid package identity" ;; + esac + mkdir -p "$database" + [ ! -e "$database/$name" ] || fail "$name is already installed" + while IFS= read -r path; do + safe_path "$path" || fail "unsafe packing-list path: $path" + for record in "$database"/*/+PLIST; do + [ -f "$record" ] || continue + grep -Fqx "$path" "$record" && fail "$path is already owned" + done + done <"$package/+PLIST" + cp -R "$package/root/usr/local/." /usr/local/ + temporary=$database/.$name.new + rm -rf "$temporary" + mkdir -p "$temporary" + cp "$package/+MANIFEST" "$temporary/+MANIFEST" + cp "$package/+PLIST" "$temporary/+PLIST" + printf '%s\n' "$version" >"$temporary/version" + mv "$temporary" "$database/$name" +} + +delete_package() +{ + name=$1 + record=$database/$name + [ -f "$record/+PLIST" ] || fail "$name is not installed" + sort -r "$record/+PLIST" | + while IFS= read -r path; do + safe_path "$path" || fail "unsafe installed path: $path" + if [ -d "/usr/local/$path" ] && [ ! -L "/usr/local/$path" ]; then + rmdir "/usr/local/$path" 2>/dev/null || true + else + rm -f "/usr/local/$path" + fi + done + rm -rf "$record" +} + +case "${1:-}" in + add) [ "$#" -eq 2 ] || fail "usage: mouse-package add PACKAGE"; add_package "$2" ;; + delete) [ "$#" -eq 2 ] || fail "usage: mouse-package delete NAME"; delete_package "$2" ;; + status) [ "$#" -eq 2 ] || fail "usage: mouse-package status NAME"; test -f "$database/$2/+MANIFEST" ;; + list) + [ "$#" -eq 1 ] || fail "usage: mouse-package list" + for record in "$database"/*; do + [ -f "$record/+MANIFEST" ] || continue + printf '%s-%s\n' "${record##*/}" "$(cat "$record/version")" + done + ;; + *) fail "usage: mouse-package {add|delete|status|list}" ;; +esac diff --git a/base/support/rust-eh-personality.c b/base/support/rust-eh-personality.c index 96315c4..fc355bf 100644 --- a/base/support/rust-eh-personality.c +++ b/base/support/rust-eh-personality.c @@ -1,7 +1,8 @@ /* * Rust's compiler-builtins archive carries an unused unwind reference on - * x86_64. Base C programs do not unwind through Rust, but lld still requires - * the personality symbol when it extracts the relevant builtins object. + * the selected target. Base C programs do not unwind through Rust, but lld + * still requires the personality symbol when it extracts the relevant + * builtins object. */ void rust_eh_personality(void) diff --git a/release/autotools.lock b/release/autotools.lock new file mode 100644 index 0000000..caf6668 --- /dev/null +++ b/release/autotools.lock @@ -0,0 +1,5 @@ +# SHA-256 URL filename +f25c6ab51548a73a75558742fb031e0625d6485fe5f9155949d6486a2408ab66 https://ftp.gnu.org/gnu/m4/m4-1.4.21.tar.xz m4-1.4.21.tar.xz +505cf43912e9480495c344c70260452e32aa2a73c546a026b3f100053b23ce91 https://www.cpan.org/src/5.0/perl-5.44.0.tar.xz perl-5.44.0.tar.xz +ba885c1319578d6c94d46e9b0dceb4014caafe2490e437a0dbca3f270a223f5a https://ftp.gnu.org/gnu/autoconf/autoconf-2.72.tar.xz autoconf-2.72.tar.xz +ff2bf7656c4d1c6fdda3b8bebb21f09153a736bcba169aaf65eab25fa113bf3a https://ftp.gnu.org/gnu/automake/automake-1.16.3.tar.xz automake-1.16.3.tar.xz diff --git a/release/device-firmware.lock b/release/device-firmware.lock new file mode 100644 index 0000000..9a10f13 --- /dev/null +++ b/release/device-firmware.lock @@ -0,0 +1,2 @@ +# SHA-256 URL filename +2b9d8a358e76eb766588609135e53fa548b902c551daae33ee32f26f25e60dbb https://www.kernel.org/pub/linux/kernel/firmware/linux-firmware-20260622.tar.xz linux-firmware-20260622.tar.xz diff --git a/release/facilities.lock b/release/facilities.lock index 696cfa8..622fce9 100644 --- a/release/facilities.lock +++ b/release/facilities.lock @@ -1,7 +1,7 @@ # SHA-256 URL filename 20a0b0a2bb2525fa53c7eee9beb854b4c9cf172eabb209af7020743547bfe9fb https://www.greenwoodsoftware.com/less/less-704.tar.gz less-704.tar.gz 8bf0d570f01e70a6e124884088870cbed7537f36328d512909eb10cd53179d9c https://mandoc.bsd.lv/snapshots/mandoc-1.14.6.tar.gz mandoc-1.14.6.tar.gz -45672fec165cb4cc1358a2d76b5d57d22876dcb97ab169427ac385cbe1d5597a https://astron.com/pub/file/file-5.47.tar.gz file-5.47.tar.gz +ed14656883b23a364b4057c05595d93252da9bc473d30106519519d0da141283 https://astron.com/pub/file/file-5.48.tar.gz file-5.48.tar.gz 01a7b881bd220bfdf615f97b8718f80bdfd3f6add385b993dcf6efd14e8c0ac6 https://ftp.gnu.org/gnu/gzip/gzip-1.14.tar.xz gzip-1.14.tar.xz ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269 https://sourceware.org/pub/bzip2/bzip2-1.0.8.tar.gz bzip2-1.0.8.tar.gz 33bf69c0d6c698e83a68f77e6c1f465778e418ca0b3d59860d3ab446f4ac99a6 https://github.com/tukaani-project/xz/releases/download/v5.8.3/xz-5.8.3.tar.bz2 xz-5.8.3.tar.bz2 diff --git a/release/firmware.lock b/release/firmware.lock index 55796eb..bc6d2b3 100644 --- a/release/firmware.lock +++ b/release/firmware.lock @@ -1,2 +1,3 @@ # SHA-256 URL filename abbfe6ee4a2b2d19a3a7c140c253015deed098d9731a0326db6465740d747846 https://dl-cdn.alpinelinux.org/alpine/edge/community/x86_64/ovmf-0.0.202605-r0.apk ovmf-0.0.202605-r0.apk +6a4d2d45a10d3700c238adbe371d8e473629ddb4c2bfe52b61237a26a8caf42e https://dl-cdn.alpinelinux.org/alpine/edge/community/aarch64/aavmf-0.0.202605-r0.apk aavmf-0.0.202605-r0.apk diff --git a/release/kernel.lock b/release/kernel.lock index 9ef2bbc..597aaa2 100644 --- a/release/kernel.lock +++ b/release/kernel.lock @@ -1,2 +1,2 @@ # SHA-256 URL filename -f78602932219125e211c5f5bfd84edcfd4ec5ce88fc944f8248413f665bef236 https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.18.35.tar.xz linux-6.18.35.tar.xz +995dd7188d924662b94b48fd6fb783587267590e5b8bb33dade2c771e7d855c1 https://cdn.kernel.org/pub/linux/kernel/v7.x/linux-7.1.6.tar.xz linux-7.1.6.tar.xz diff --git a/release/pkgsrc.lock b/release/pkgsrc.lock deleted file mode 100644 index a226bfb..0000000 --- a/release/pkgsrc.lock +++ /dev/null @@ -1,2 +0,0 @@ -# sha256 url filename -d8c008b6c786aeb9c7d5260d3fc8d14b15fed32f339be620fe7226f08061fc72 https://cdn.netbsd.org/pub/pkgsrc/pkgsrc-2026Q2/pkgsrc-2026Q2.tar.gz pkgsrc-2026Q2.tar.gz diff --git a/release/software.lock b/release/software.lock index d09f385..691dd94 100644 --- a/release/software.lock +++ b/release/software.lock @@ -1,32 +1,32 @@ # SHA-256 URL filename d585fd3b613c66151fc3249e8ed44f77020cb5e6c1e635a616d3f9f82460512a https://musl.libc.org/releases/musl-1.2.6.tar.gz musl-1.2.6.tar.gz bb329a0a2cd0274d05519d61c667c062e06990d72e125ee2dfa8de64f0119d16 https://zlib.net/zlib-1.3.2.tar.gz zlib-1.3.2.tar.gz -d3a8ba457ae25c27c84fd2830a2efdcc5b1d40bf585d4eb0d35f47e99e5d4774 https://github.com/libarchive/libarchive/releases/download/v3.8.7/libarchive-3.8.7.tar.xz libarchive-3.8.7.tar.xz +888c934f9d95648ecb9163dc8e23ab80a476ecb81a8f1154704a227b5b676dde https://github.com/libarchive/libarchive/releases/download/v3.8.9/libarchive-3.8.9.tar.xz libarchive-3.8.9.tar.xz 9d3ebd651e5f70b87b1327b01cbd7e0c01a0f036b4c1371f653b7704b11daf23 https://github.com/sabotage-linux/netbsd-curses/archive/refs/tags/v0.3.2.tar.gz netbsd-curses-0.3.2.tar.gz -39bf67452fa41d0948c2197601053f48b3d78a029389734332a6309a680c6c87 https://download-mirror.savannah.gnu.org/releases/attr/attr-2.5.2.tar.gz attr-2.5.2.tar.gz -5f2bdbad629707aa7d85c623f994aa8a1d2dec55a73de5205bac0bf6058a2f7c https://download-mirror.savannah.gnu.org/releases/acl/acl-2.3.2.tar.gz acl-2.3.2.tar.gz +d42fa374513180bb48cb11a46696f488240e5124ff1e6ad88b0abff706985612 https://download-mirror.savannah.gnu.org/releases/attr/attr-2.6.0.tar.gz attr-2.6.0.tar.gz +73c853c3d44e1f693e5a96a986f1bd19d3d0dac2c7d453e796177774bc4e5f6a https://download-mirror.savannah.gnu.org/releases/acl/acl-2.4.0.tar.gz acl-2.4.0.tar.gz d12249ffad3ef04b160e6419adf1bbe7e593a60bb23f0a0a077fa780b214934a https://github.com/Juniper/libxo/releases/download/1.7.5/libxo-1.7.5.tar.gz libxo-1.7.5.tar.gz aa8b6eeca8b93db659a7ebf421a7089b3f7f8457deba34170cd146b92fe60546 https://github.com/tcsh-org/tcsh/archive/refs/tags/TCSH6_24_16.tar.gz tcsh-6.24.16.tar.gz 183ad94242316cad014b54668e0b117ba4d8f6978b1229cde3fc5cd913020751 https://github.com/chimera-linux/chimerautils/archive/refs/tags/v15.0.3.tar.gz chimerautils-15.0.3.tar.gz -a8c0d28a529ca480f9f36cf5792e2cd21984552a3c8e4aa11a24aa31aeac98e8 https://github.com/openssl/openssl/releases/download/openssl-3.5.7/openssl-3.5.7.tar.gz openssl-3.5.7.tar.gz +2db3f3a0d6ea4b59e1f094ace2c8cd536dffb87cdc39084c5afa1e6f7f37dd09 https://github.com/openssl/openssl/releases/download/openssl-4.0.1/openssl-4.0.1.tar.gz openssl-4.0.1.tar.gz 3ff344e30b9b1ed2971044eabb438a08f2e2245ddb5f8ab1a3ad8b63ab4eaf91 https://curl.se/ca/cacert-2026-07-16.pem cacert-2026-07-16.pem -b035c1aeaf82d6988e0feb9be8ac80e1825227ff01d0c7a92e4356f423db0b62 https://raw.githubusercontent.com/chimera-linux/cports/1e8911eb1bb9dc94a6734686b8327206d5ac89e0/main/musl-bsd-headers/files/cdefs.h cdefs.h -3659cd137c320991a78413dd370a92fd18e0a8bc36d017d554f08677a37d7d5a https://raw.githubusercontent.com/chimera-linux/cports/1e8911eb1bb9dc94a6734686b8327206d5ac89e0/main/musl-bsd-headers/files/queue.h queue.h -e1e498a79bf160a5766fa560f2b07b206fe89fe21a62600c77d72e00a6992f92 https://raw.githubusercontent.com/chimera-linux/cports/1e8911eb1bb9dc94a6734686b8327206d5ac89e0/main/musl-bsd-headers/files/tree.h tree.h -a3c6ac4e3a3f7407760f87810e6937a213934bd8d2d7b9ea477489206d80742c https://raw.githubusercontent.com/chimera-linux/cports/1e8911eb1bb9dc94a6734686b8327206d5ac89e0/main/musl-bsd-headers/files/error.h error.h -febaa8f7c1916521c53eb5fd11c0641b5eb4741c2c6e9b42c288ed62d9e4fd2c https://github.com/mesonbuild/meson/archive/refs/tags/1.9.1.tar.gz meson-1.9.1.tar.gz -f0055ad0369bf2e372955ba55128d000cfcc21777057806015b45e4accbebf23 https://github.com/ninja-build/ninja/archive/refs/tags/v1.13.1.tar.gz ninja-1.13.1.tar.gz -79721badcad1987dead9c3609eb4877ab9b58821c06bdacb824f2c8897c11f2a https://github.com/pkgconf/pkgconf/archive/refs/tags/pkgconf-2.5.1.tar.gz pkgconf-2.5.1.tar.gz +b035c1aeaf82d6988e0feb9be8ac80e1825227ff01d0c7a92e4356f423db0b62 https://raw.githubusercontent.com/chimera-linux/cports/7db7f75c86ebed9977831622cb50651d96080bea/main/musl-bsd-headers/files/cdefs.h cdefs.h +3659cd137c320991a78413dd370a92fd18e0a8bc36d017d554f08677a37d7d5a https://raw.githubusercontent.com/chimera-linux/cports/7db7f75c86ebed9977831622cb50651d96080bea/main/musl-bsd-headers/files/queue.h queue.h +e1e498a79bf160a5766fa560f2b07b206fe89fe21a62600c77d72e00a6992f92 https://raw.githubusercontent.com/chimera-linux/cports/7db7f75c86ebed9977831622cb50651d96080bea/main/musl-bsd-headers/files/tree.h tree.h +a3c6ac4e3a3f7407760f87810e6937a213934bd8d2d7b9ea477489206d80742c https://raw.githubusercontent.com/chimera-linux/cports/7db7f75c86ebed9977831622cb50651d96080bea/main/musl-bsd-headers/files/error.h error.h +09cc2faedc61262fc62abf57aa6c47c57a8c0730b950609a0711bbaf587bd133 https://github.com/mesonbuild/meson/archive/refs/tags/1.11.2.tar.gz meson-1.11.2.tar.gz +974d6b2f4eeefa25625d34da3cb36bdcebe7fbce40f4c16ac0835fd1c0cbae17 https://github.com/ninja-build/ninja/archive/refs/tags/v1.13.2.tar.gz ninja-1.13.2.tar.gz +245d441b9d8f7b74390e060cb9db1a326c26f1b96b1a6c3216b54a5d5439367a https://github.com/pkgconf/pkgconf/archive/refs/tags/pkgconf-3.0.5.tar.gz pkgconf-3.0.5.tar.gz 03a05d3adf9602ef128f2da05b84b3205ce60c351e5737c0370f74000679ce8a https://www.kernel.org/pub/linux/utils/util-linux/v2.42/util-linux-2.42.2.tar.xz util-linux-2.42.2.tar.xz 71513a31c01a428bccd5367a32fd95f115d6dac50fb5b60c779d5c7942aec071 https://github.com/besser82/libxcrypt/releases/download/v4.5.2/libxcrypt-4.5.2.tar.xz libxcrypt-4.5.2.tar.xz -ce57a313e315a0a7cb04a8f50cc20753e994e487bbe9b78a2a824ca75cb486c0 https://github.com/shadow-maint/shadow/releases/download/4.19.4/shadow-4.19.4.tar.xz shadow-4.19.4.tar.xz -48a89ecf49927ed60b42b73edc07a63f6198d2c47a848f723a495c5cd66e220f https://github.com/NetworkConfiguration/dhcpcd/archive/8b312918d8f1885d7fe8fcc03a7e06ae8a0314b4.tar.gz dhcpcd-8b312918d8f1885d7fe8fcc03a7e06ae8a0314b4.tar.gz +239781632846db3b01901028147fb4b57e6f2d5330ca63ce104b21d9b3e6031f https://github.com/shadow-maint/shadow/releases/download/4.20.0/shadow-4.20.0.tar.xz shadow-4.20.0.tar.xz +4e98828056d6266bd8f2c93e6ecf12a63a71dbfd70a5ea99ccd4ab6d0745adf0 https://github.com/Duncaen/OpenDoas/releases/download/v6.8.2/opendoas-6.8.2.tar.xz opendoas-6.8.2.tar.xz +fed5c165551ffed47a812a161e36d057d95781c25cef84d4564cea8ab0a350f1 https://github.com/NetworkConfiguration/dhcpcd/archive/e3363cf477aa53d4ed74d00ce5d3d4c7e5b7f2c3.tar.gz dhcpcd-e3363cf477aa53d4ed74d00ce5d3d4c7e5b7f2c3.tar.gz dd16fb1d67bfab79a72f5e8390735c49e3e8e70b4945a15ab1f81ddb78658fb3 https://ftp.gnu.org/gnu/make/make-4.4.1.tar.gz make-4.4.1.tar.gz f1da374a15ba7605cf378347f96bc8b678d3d7c0765269c8242cfe5b0789c571 https://github.com/cronie-crond/cronie/releases/download/cronie-1.7.2/cronie-1.7.2.tar.gz cronie-1.7.2.tar.gz 091eeb3f4e358e28c3ab2ea58f93d7a0b5758a20d7c8a0418e162e9b2c27addc https://cdn.openbsd.org/pub/OpenBSD/OpenNTPD/openntpd-7.9p1.tar.gz openntpd-7.9p1.tar.gz -c2e6d193cc78f84cd6ddb72aaf6d5c6a9162f0470e5992092057f5ff518562fa https://sourceforge.net/projects/procps-ng/files/Production/procps-ng-4.0.5.tar.xz/download procps-ng-4.0.5.tar.xz +67bea6fbc3a42a535a0230c9e891e5ddfb4d9d39422d46565a2990d1ace15216 https://sourceforge.net/projects/procps-ng/files/Production/procps-ng-4.0.6.tar.xz/download procps-ng-4.0.6.tar.xz 19e680c9eef8c079da4da37040b5f5453763205b4edfb1e2c114de77908927e4 https://github.com/iputils/iputils/archive/refs/tags/20250605.tar.gz iputils-20250605.tar.gz 5a5d5073070cc7e0c7a7a3c6ec2a0e1780850c8b47b3e3892226b93ffcb9cb54 https://mirrors.edge.kernel.org/pub/linux/utils/kernel/kmod/kmod-34.2.tar.xz kmod-34.2.tar.xz -f9c905e74935c6fe911c7e344e3e89d5fbd2014c1a04650b524b15ce9b5635d1 https://skarnet.org/software/skalibs/skalibs-2.15.1.0.tar.gz skalibs-2.15.1.0.tar.gz -ce1ae0149b6a57a34f608218fd6181aa6aa68135cac2f4d931b5b417b072e244 https://skarnet.org/software/mdevd/mdevd-0.1.8.2.tar.gz mdevd-0.1.8.2.tar.gz +ad4acc80c4c511258bac631c21f5fef0570cc9507242a9f6a5afeee7a9207237 https://git.pinkro.se/Rose/gardenhouse/gardendevd.git gardendevd-611350ed44a116cffe6a53bbe8cfb13c721718f1.tar bc410ca64551a11fac6518b418fb6b8afbd888a70af2c5eb353334a706727bca https://github.com/troglobit/sysklogd/releases/download/v2.7.2/sysklogd-2.7.2.tar.gz sysklogd-2.7.2.tar.gz diff --git a/release/storage.lock b/release/storage.lock index b863cae..38126b5 100644 --- a/release/storage.lock +++ b/release/storage.lock @@ -1,4 +1,4 @@ # SHA-256 URL filename -c286d6876cbcd72327a0b417e4cfd280353ec23e37b549fdbcd7800a832d9a99 https://www.kernel.org/pub/linux/kernel/people/kdave/btrfs-progs/btrfs-progs-v7.0.tar.xz btrfs-progs-v7.0.tar.xz +d1f55cc2971398c9142eaa79d203e63d586a3b4b867f956664a1d68322cd4e34 https://www.kernel.org/pub/linux/kernel/people/kdave/btrfs-progs/btrfs-progs-v7.1.tar.xz btrfs-progs-v7.1.tar.xz 37d7284556b20954e56e1ca85b80226768902e2edabd3b649e9e72c0c9012ee3 https://github.com/facebook/zstd/archive/refs/tags/v1.5.7.tar.gz zstd-1.5.7.tar.gz -26e53e04d562e91403018997afdb5d8c4448a580a3db433d0bccc9b0f02ac134 https://github.com/Limine-Bootloader/Limine/releases/download/v12.3.2/limine-binary.tar.xz limine-binary-12.3.2.tar.xz +5e2d6eb86623fcdcd2a873c9eca7dcafccb34182c17779535fe824fd57b688c5 https://github.com/Limine-Bootloader/Limine/releases/download/v12.5.2/limine-binary.tar.xz limine-binary-12.5.2.tar.xz diff --git a/release/toolchain.lock b/release/toolchain.lock index 19ddd06..b553c31 100644 --- a/release/toolchain.lock +++ b/release/toolchain.lock @@ -1,2 +1,2 @@ # SHA-256 URL filename -2488c33a959eafba1c44f253e5bbe7ac958eb53fa626298a3a5f4b87373767cd https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.3/llvm-project-22.1.3.src.tar.xz llvm-project-22.1.3.src.tar.xz +922f1817a0df7b1489272d18134ee0087a8b068828f87ac63b9861b1a9965888 https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.8/llvm-project-22.1.8.src.tar.xz llvm-project-22.1.8.src.tar.xz diff --git a/release/wireless.lock b/release/wireless.lock new file mode 100644 index 0000000..460a2ed --- /dev/null +++ b/release/wireless.lock @@ -0,0 +1,3 @@ +# SHA-256 URL filename +fc51ca7196f1a3f5fdf6ffd3864b50f4f9c02333be28be4eeca057e103c0dd18 https://github.com/thom311/libnl/releases/download/libnl3_12_0/libnl-3.12.0.tar.gz libnl-3.12.0.tar.gz +912ea06f74e30a8e36fbb68064d6cdff218d8d591db0fc5d75dee6c81ac7fc0a https://w1.fi/releases/wpa_supplicant-2.11.tar.gz wpa_supplicant-2.11.tar.gz diff --git a/scripts/audit-static-base.sh b/scripts/audit-static-base.sh index 9063321..db7a082 100755 --- a/scripts/audit-static-base.sh +++ b/scripts/audit-static-base.sh @@ -1,6 +1,9 @@ #!/bin/sh set -eu +script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +. "$script_dir/mouse-arch.sh" + if [ "$#" -ne 1 ]; then printf '%s\n' "usage: audit-static-base.sh ROOTFS" >&2 exit 2 @@ -20,15 +23,19 @@ done for executable in \ /bin/chgrp /bin/login /bin/sh /bin/su /bin/tcsh \ /sbin/agetty /sbin/blkid /sbin/bridge /sbin/btrfs /sbin/dhcpcd /sbin/dmesg \ - /sbin/depmod /sbin/insmod /sbin/kmod /sbin/lsmod /sbin/mdevd \ - /sbin/mdevd-coldplug /sbin/mkfs.btrfs /sbin/modinfo /sbin/modprobe \ + /sbin/depmod /sbin/insmod /sbin/kmod /sbin/lsmod \ + /sbin/mkfs.btrfs /sbin/modinfo /sbin/modprobe \ /sbin/mount /sbin/fdisk /sbin/ip /sbin/losetup /sbin/nft /sbin/rmmod \ /sbin/sfdisk /sbin/ss /sbin/swapoff /sbin/swapon /sbin/sysctl /sbin/tc \ /sbin/umount /sbin/wipefs \ - /usr/bin/setsid /usr/sbin/mouse-bootenv \ + /sbin/wpa_supplicant \ + /usr/bin/gardendevctl /usr/bin/setsid /usr/libexec/mouse-auth \ + /usr/libexec/mouse-package /usr/sbin/gardendevd \ + /usr/sbin/mouse-bootenv \ /usr/bin/awk /usr/bin/basename /usr/bin/cmp /usr/bin/cut \ - /usr/bin/diff /usr/bin/dirname /usr/bin/fetch /usr/bin/groups /usr/bin/ldd \ - /usr/bin/install /usr/bin/m4 /usr/bin/nc /usr/bin/patch \ + /usr/bin/diff /usr/bin/dirname /usr/bin/doas /usr/bin/fetch /usr/bin/groups /usr/bin/ldd \ + /usr/bin/autoconf /usr/bin/autom4te /usr/bin/autoreconf \ + /usr/bin/install /usr/bin/m4 /usr/bin/nc /usr/bin/patch /usr/bin/perl \ /usr/bin/sort /usr/bin/test /usr/bin/tr /usr/bin/whoami \ /usr/bin/xargs \ /usr/bin/apropos /usr/bin/bzip2 /usr/bin/crontab \ @@ -36,7 +43,8 @@ for executable in \ /usr/bin/gzip /usr/bin/less /usr/bin/lsblk /usr/bin/man /usr/bin/mandoc \ /usr/bin/nvi /usr/bin/openssl /usr/bin/passwd /usr/bin/pgrep \ /usr/bin/pkill /usr/bin/readlink /usr/bin/sha256 /usr/bin/tar \ - /usr/bin/top /usr/bin/tput /usr/bin/unzip \ + /usr/bin/top /usr/bin/tput /usr/bin/unzip /usr/bin/wpa_cli \ + /usr/bin/wpa_passphrase \ /usr/bin/uptime /usr/bin/vmstat /usr/bin/watch /usr/bin/xz /usr/bin/zstd \ /bin/ping /bin/ps /usr/bin/vi /usr/sbin/makewhatis \ /usr/sbin/cron /usr/sbin/groupadd /usr/sbin/ntpd /usr/sbin/syslogd \ @@ -48,6 +56,17 @@ do fi done +for executable in \ + /bin/ping /bin/su /usr/bin/crontab /usr/bin/doas /usr/bin/passwd +do + metadata=$(stat -c '%a %u %g' "$rootfs$executable") + if [ "$metadata" != "4755 0 0" ]; then + printf '%s\n' \ + "setuid executable must have mode 4755 and root ownership: $executable" >&2 + exit 1 + fi +done + if [ ! -f "$rootfs/etc/ssl/cert.pem" ]; then printf '%s\n' "missing TLS trust bundle: /etc/ssl/cert.pem" >&2 exit 1 @@ -67,13 +86,6 @@ if [ -e "$rootfs/etc/mouse-release" ]; then done fi -if [ -e "$rootfs/usr/share/mouse/pkgsrc.version" ]; then - if [ "$(cat "$rootfs/usr/share/mouse/pkgsrc.version")" != 2026Q2 ]; then - printf '%s\n' "unexpected pkgsrc version" >&2 - exit 1 - fi -fi - if [ -e "$rootfs/usr/bin/cc" ]; then for tool in \ /usr/bin/ar /usr/bin/c++ /usr/bin/clang /usr/bin/clang++ \ @@ -88,7 +100,7 @@ if [ -e "$rootfs/usr/bin/cc" ]; then for development_file in \ /usr/include/stdio.h /usr/include/c++/v1/filesystem \ /usr/include/openssl/ssl.h /usr/include/zlib.h \ - /lib/ld-musl-x86_64.so.1 /usr/lib/libc.so \ + "/lib/$MOUSE_MUSL_LOADER" /usr/lib/libc.so \ /usr/lib/crt1.o /usr/lib/Scrt1.o /usr/lib/crtbegin.o \ /usr/lib/crtbeginS.o /usr/lib/crtendS.o \ /usr/lib/libc.a /usr/lib/libc++.a /usr/lib/libc++.so \ @@ -104,7 +116,7 @@ if [ -e "$rootfs/usr/bin/cc" ]; then fi if [ -e "$rootfs/usr/share/mk" ] || [ -e "$rootfs/usr/bin/bmake" ]; then - printf '%s\n' "base image must leave BSD make to pkgsrc under /usr/local" >&2 + printf '%s\n' "base image must leave BSD make to mouse-ports under /usr/local" >&2 exit 1 fi if [ -e "$rootfs/usr/bin/make" ]; then diff --git a/scripts/build-boot-disk.sh b/scripts/build-boot-disk.sh index 5519d2e..6d61bef 100644 --- a/scripts/build-boot-disk.sh +++ b/scripts/build-boot-disk.sh @@ -3,12 +3,13 @@ set -eu script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) repo_dir=$(dirname "$script_dir") -build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build"} -source_dir=${MOUSE_SOURCE_DIR:-"$build_dir/sources"} +. "$script_dir/mouse-arch.sh" +build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build/$MOUSE_ARCH"} +source_dir=${MOUSE_SOURCE_DIR:-"$repo_dir/build/sources"} rootfs_image=${MOUSE_ROOTFS_IMAGE:-"$build_dir/mouse-rootfs.btrfs"} kernel_image=${MOUSE_KERNEL_IMAGE:-"$build_dir/vmlinuz-virt"} disk_image=${MOUSE_DISK_IMAGE_OUTPUT:-"$build_dir/mouse-disk.img"} -limine_archive=${MOUSE_LIMINE_ARCHIVE:-"$source_dir/limine-binary-12.3.2.tar.xz"} +limine_archive=${MOUSE_LIMINE_ARCHIVE:-"$source_dir/limine-binary-12.5.2.tar.xz"} limine_config=${MOUSE_LIMINE_CONFIG:-"$repo_dir/base/limine.conf"} for command in cc make mcopy mformat mmd sfdisk; do @@ -49,20 +50,29 @@ truncate -s $((boot_sectors * sector_size)) "$boot_image" mformat -i "$boot_image" -F -v MOUSE_BOOT :: mmd -i "$boot_image" ::/EFI ::/EFI/BOOT mcopy -i "$boot_image" \ - "$limine_source/BOOTX64.EFI" ::/EFI/BOOT/BOOTX64.EFI -mcopy -i "$boot_image" \ - "$limine_source/limine-bios.sys" ::/limine-bios.sys -mcopy -i "$boot_image" "$limine_config" ::/limine.conf + "$limine_source/$MOUSE_EFI_LOADER" "::/EFI/BOOT/$MOUSE_EFI_LOADER" +if [ "$MOUSE_ARCH" = x86_64 ]; then + mcopy -i "$boot_image" \ + "$limine_source/limine-bios.sys" ::/limine-bios.sys +fi +sed "s/console=ttyS0/console=$MOUSE_CONSOLE/g" \ + "$limine_config" >"$working/limine.conf" +mcopy -i "$boot_image" "$working/limine.conf" ::/limine.conf mcopy -i "$boot_image" "$kernel_image" ::/vmlinuz-mouse rm -f "$disk_image" truncate -s $((disk_sectors * sector_size)) "$disk_image" +if [ "$MOUSE_ARCH" = x86_64 ]; then + bios_partition="start=34, size=$((boot_start - 34)), type=21686148-6449-6e6f-744e-656564454649, uuid=4d4f5553-4500-4000-8000-000000000003, name=\"MOUSE_BIOS\"" +else + bios_partition= +fi sfdisk --quiet "$disk_image" <&2 + exit 1 +fi + +if [ "$MOUSE_ARCH" = x86_64 ]; then + "$limine_source/limine" bios-install "$disk_image" + boot_support="BIOS and UEFI" +else + boot_support=UEFI +fi + +printf '%s\n' "built $disk_image with Limine $boot_support boot support" diff --git a/scripts/build-btrfs-image-tool.sh b/scripts/build-btrfs-image-tool.sh new file mode 100755 index 0000000..492f22e --- /dev/null +++ b/scripts/build-btrfs-image-tool.sh @@ -0,0 +1,22 @@ +#!/bin/sh +set -eu + +jobs=${MOUSE_BUILD_JOBS:-8} +source=/work/btrfs-progs-v7.1 + +tar -C /work -xf /opt/btrfs-progs-v7.1.tar.xz +( + cd "$source" + ./configure \ + --prefix=/usr \ + --disable-backtrace \ + --disable-documentation \ + --disable-convert \ + --disable-lzo \ + --disable-libudev \ + --disable-python \ + --disable-zoned \ + --with-crypto=builtin + make -j"$jobs" mkfs.btrfs +) +install -m 0755 "$source/mkfs.btrfs" /opt/mkfs.btrfs diff --git a/scripts/build-image-commands.sh b/scripts/build-image-commands.sh index b4f12e7..bc1f8b4 100755 --- a/scripts/build-image-commands.sh +++ b/scripts/build-image-commands.sh @@ -3,10 +3,11 @@ set -eu script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) repo_dir=$(dirname "$script_dir") -build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build"} +. "$script_dir/mouse-arch.sh" +build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build/$MOUSE_ARCH"} static_dir="$build_dir/static" base_root="$static_dir/rootfs" -cc="$static_dir/cross-tools/bin/x86_64-mouse-linux-musl-cc" +cc="$static_dir/cross-tools/bin/$MOUSE_CROSS_TARGET-cc" for requirement in \ "$cc" \ @@ -18,7 +19,15 @@ do fi done +install -d -m 0755 "$base_root/usr/libexec" install -m 0755 \ "$repo_dir/base/support/mouse-bootenv" \ "$base_root/usr/sbin/mouse-bootenv" -ln -sfn ../usr/lib/libc.so "$base_root/lib/ld-musl-x86_64.so.1" +install -m 0755 \ + "$repo_dir/base/support/mouse-package" \ + "$base_root/usr/libexec/mouse-package" +"$cc" -O2 -Wall -Wextra -Werror \ + "$repo_dir/base/support/mouse-auth.c" \ + -lcrypt \ + -o "$base_root/usr/libexec/mouse-auth" +ln -sfn ../usr/lib/libc.so "$base_root/lib/$MOUSE_MUSL_LOADER" diff --git a/scripts/build-image.sh b/scripts/build-image.sh index 67f2e7c..312a673 100755 --- a/scripts/build-image.sh +++ b/scripts/build-image.sh @@ -3,11 +3,13 @@ set -eu script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) repo_dir=$(dirname "$script_dir") +. "$script_dir/mouse-arch.sh" cheesed_dir="$repo_dir/base/cheesed" -build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build"} -target=${CHEESED_TARGET:-x86_64-unknown-linux-musl} +build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build/$MOUSE_ARCH"} +target=${CHEESED_TARGET:-$MOUSE_RUST_TARGET} test_fixtures=${MOUSE_INCLUDE_TEST_FIXTURES:-0} kernel_modules=${MOUSE_KERNEL_MODULES:-"$build_dir/kernel/modules"} +device_firmware=${MOUSE_DEVICE_FIRMWARE:-"$build_dir/device-firmware"} staging= image_staging= @@ -28,19 +30,18 @@ case "$test_fixtures" in ;; esac base_root="$build_dir/static/rootfs" -pkgsrc_seed=${MOUSE_PKGSRC_SEED:-"$build_dir/pkgsrc-seed"} -for input in "$base_root" "$build_dir/vmlinuz-virt"; do +ports_seed=${MOUSE_PORTS_SEED:-"$build_dir/mouse-ports-seed"} +for input in "$base_root" "$build_dir/vmlinuz-virt" \ + "$device_firmware/lib/firmware"; do if [ ! -e "$input" ]; then printf '%s\n' "missing prepared image input: $input" >&2 exit 1 fi done -for seed_directory in "$pkgsrc_seed/usr/local" "$pkgsrc_seed/var/db/pkg"; do - if [ ! -d "$seed_directory" ]; then - printf '%s\n' "missing pkgsrc seed directory: $seed_directory" >&2 - exit 1 - fi -done +if [ ! -d "$ports_seed/usr/local" ]; then + printf '%s\n' "missing mouse-ports seed directory: $ports_seed/usr/local" >&2 + exit 1 +fi btrfs_image_tool=${MOUSE_BTRFS_IMAGE_TOOL:-"$base_root/sbin/mkfs.btrfs"} if [ ! -x "$btrfs_image_tool" ]; then printf '%s\n' "missing btrfs image tool: $btrfs_image_tool" >&2 @@ -74,8 +75,8 @@ install -d -m 0755 \ "$staging/usr/local/etc/rc.d" \ "$staging/usr/lib/mouse" \ "$staging/usr/sbin" \ - "$staging/var/cache/pkgsrc/distfiles" \ - "$staging/var/cache/pkgsrc/packages" \ + "$staging/var/cache/mouse/ports/distfiles" \ + "$staging/var/cache/mouse/packages" \ "$staging/var/db" \ "$staging/var/lib/dhcpcd" \ "$staging/var/empty" \ @@ -94,13 +95,13 @@ install -d -m 1777 \ ln -s /run "$staging/var/run" cp -R "$base_root/." "$staging/" -cp -R "$pkgsrc_seed/usr/local/." "$staging/usr/local/" -cp -R "$pkgsrc_seed/var/db/pkg" "$staging/var/db/" +cp -R "$ports_seed/usr/local/." "$staging/usr/local/" if [ ! -d "$kernel_modules/lib/modules" ]; then printf '%s\n' "missing kernel module tree: $kernel_modules/lib/modules" >&2 exit 1 fi cp -R "$kernel_modules/lib/." "$staging/lib/" +cp -R "$device_firmware/lib/firmware" "$staging/lib/" if [ "$test_fixtures" -eq 1 ] && [ -d "$kernel_modules/usr/local" ]; then cp -R "$kernel_modules/usr/local/." "$staging/usr/local/" fi @@ -110,29 +111,40 @@ for command in service shutdown poweroff reboot; do done cp -R "$repo_dir/base/rootfs/." "$staging/" +install -d -m 0700 -o 1000 -g 1000 "$staging/home/mouse" +sed "s/@MOUSE_ARCH@/$MOUSE_ARCH/g" \ + "$staging/etc/mouse-release" >"$staging/etc/mouse-release.new" +mv "$staging/etc/mouse-release.new" "$staging/etc/mouse-release" +sed "s/@MOUSE_ARCH@/$MOUSE_ARCH/g" \ + "$staging/etc/motd" >"$staging/etc/motd.new" +mv "$staging/etc/motd.new" "$staging/etc/motd" +for console_file in \ + "$staging/etc/rc.d/console_login" \ + "$staging/etc/securetty" +do + sed "s/@MOUSE_CONSOLE@/$MOUSE_CONSOLE/g" \ + "$console_file" >"$console_file.new" + mv "$console_file.new" "$console_file" +done if [ "$test_fixtures" -eq 1 ]; then cp -R "$repo_dir/tests/fixtures/mouse-echo/rootfs/." "$staging/" install -m 0755 \ "${MOUSE_MOUSE_ECHO_BINARY:?missing test mouse-echo binary}" \ "$staging/usr/libexec/mouse-echo" printf '%s\n' "enable_mouse_echo=YES" >>"$staging/etc/rc.conf" + test_password_hash='$6$mouse$LofYSsSObtmx/zmS97A.TFONKSQSATXE4bD6dY1H7JSBSayuyAuc4Qwpm7JdfW9lUnri9DrQfUKGiLTNKA3v81' + awk -F: -v OFS=: -v password_hash="$test_password_hash" ' + $1 == "root" || $1 == "toor" { $2 = password_hash } + { print } + ' "$staging/etc/shadow" >"$staging/etc/shadow.test" + mv "$staging/etc/shadow.test" "$staging/etc/shadow" fi install -d -m 0755 "$staging/usr/share/mouse" -if [ "$test_fixtures" -eq 1 ]; then - install -d -m 0755 "$staging/usr/share/mouse/pkgsrc-fixture" - cp -R "$repo_dir/tests/fixtures/pkgsrc/local" \ - "$staging/usr/share/mouse/pkgsrc-fixture/" -fi -printf '%s\n' 2026Q2 >"$staging/usr/share/mouse/pkgsrc.version" -rc_subr_source="$staging/usr/local/src/pkgsrc/pkgtools/rc.subr/files/rc.subr" -[ -f "$rc_subr_source" ] || { - printf '%s\n' "pkgsrc seed lacks rc.subr source" >&2 - exit 1 -} -sed 's|@SYSCONFBASE@|/usr/local/etc|g' "$rc_subr_source" \ - >"$staging/etc/rc.subr" +install -m 0444 \ + "${MOUSE_PORTS_REVISION_FILE:-/work/mouse-ports-revision}" \ + "$staging/usr/share/mouse/ports.revision" patch "$staging/etc/rc.subr" \ - <"$repo_dir/base/patches/pkgsrc-rc.subr-cgroup.patch" + <"$repo_dir/base/patches/rc.subr-cgroup.patch" chmod 0444 "$staging/etc/rc.subr" ln -s mouse-release "$staging/etc/os-release" chmod 0755 \ @@ -142,24 +154,56 @@ chmod 0755 \ "$staging/etc/rc.d/login" \ "$staging/etc/rc.d/loopback" \ "$staging/etc/rc.d/machine_identity" \ - "$staging/etc/rc.d/mdevd" \ + "$staging/etc/rc.d/gardendevd" \ "$staging/etc/rc.d/network" \ "$staging/etc/rc.d/ntpd" \ "$staging/etc/rc.d/servers" \ "$staging/etc/rc.d/syslogd" \ - "$staging/usr/libexec/mouse-dhcpcd-hook" + "$staging/etc/rc.d/wpa_supplicant" \ + "$staging/usr/libexec/mouse-dhcpcd-hook" \ + "$staging/usr/libexec/mouse-wpa-supplicant" if [ "$test_fixtures" -eq 1 ]; then chmod 0755 "$staging/etc/rc.d/mouse_echo" fi +chown 0:0 \ + "$staging/bin/ping" \ + "$staging/bin/su" \ + "$staging/usr/bin/crontab" \ + "$staging/usr/bin/doas" \ + "$staging/usr/bin/passwd" +chmod 4755 \ + "$staging/bin/ping" \ + "$staging/bin/su" \ + "$staging/usr/bin/crontab" \ + "$staging/usr/bin/doas" \ + "$staging/usr/bin/passwd" chmod 0600 "$staging/etc/shadow" - -chmod 0444 "$staging/usr/share/mouse/pkgsrc.version" +chmod 0600 "$staging/etc/wpa_supplicant/wpa_supplicant.conf" "$script_dir/audit-static-base.sh" "$staging" +for desktop_input in \ + /usr/local/bin/bmake \ + /usr/local/bin/dwl \ + /usr/local/bin/havoc \ + /usr/local/bin/mouse-dwl-session \ + /usr/local/bin/seatd \ + /usr/local/bin/tuigreet \ + /usr/local/lib/libudev.so \ + /usr/local/lib/libwlroots-0.19.so \ + /usr/local/sbin/greetd \ + /usr/local/etc/rc.d/greetd \ + /usr/local/etc/rc.d/seatd +do + [ -e "$staging$desktop_input" ] || { + printf '%s\n' "missing mouse-ports seed input: $desktop_input" >&2 + exit 1 + } +done + mkdir -p "$build_dir" btrfs_image="$build_dir/mouse-rootfs.btrfs" -rootfs_size=${MOUSE_ROOTFS_SIZE:-4G} +rootfs_size=${MOUSE_ROOTFS_SIZE:-8G} install -d -m 0755 \ "$image_staging/ROOT/default" \ "$image_staging/ROOT/alternate" \ @@ -168,8 +212,8 @@ install -d -m 0755 \ "$image_staging/home" \ "$image_staging/srv" -cp -R "$staging/." "$image_staging/ROOT/default/" -cp -R "$staging/." "$image_staging/ROOT/alternate/" +cp -a "$staging/." "$image_staging/ROOT/default/" +cp -a "$staging/." "$image_staging/ROOT/alternate/" printf '%s\n' default \ >"$image_staging/ROOT/default/etc/mouse-boot-environment" printf '%s\n' alternate \ @@ -183,7 +227,7 @@ for persistent in \ do root_path=${persistent%%:*} subvolume=${persistent#*:} - cp -R "$staging/$root_path/." "$image_staging/$subvolume/" + cp -a "$staging/$root_path/." "$image_staging/$subvolume/" for environment in default alternate; do rm -rf "$image_staging/ROOT/$environment/$root_path" install -d -m 0755 \ @@ -191,6 +235,21 @@ do done done +for environment in default alternate; do + metadata=$(stat -c '%a %u %g' \ + "$image_staging/ROOT/$environment/usr/bin/doas") + if [ "$metadata" != "4755 0 0" ]; then + printf '%s\n' \ + "image staging lost doas setuid metadata in $environment" >&2 + exit 1 + fi +done +metadata=$(stat -c '%a %u %g' "$image_staging/home/mouse") +if [ "$metadata" != "700 1000 1000" ]; then + printf '%s\n' "image staging lost mouse home ownership" >&2 + exit 1 +fi + rm -f "$btrfs_image" truncate -s "$rootfs_size" "$btrfs_image" "$btrfs_image_tool" \ @@ -207,5 +266,5 @@ truncate -s "$rootfs_size" "$btrfs_image" "$btrfs_image" printf '%s\n' "built $build_dir/vmlinuz-virt" -printf '%s\n' "built $btrfs_image" sh "$script_dir/build-boot-disk.sh" +rm -f "$btrfs_image" diff --git a/scripts/build-in-container.sh b/scripts/build-in-container.sh index e7047db..428323f 100755 --- a/scripts/build-in-container.sh +++ b/scripts/build-in-container.sh @@ -3,7 +3,9 @@ set -eu script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) repo_dir=$(dirname "$script_dir") -output_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build"} +. "$script_dir/mouse-arch.sh" +output_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build/$MOUSE_ARCH"} +source_dir=${MOUSE_SOURCE_DIR:-"$repo_dir/build/sources"} test_fixtures=${MOUSE_INCLUDE_TEST_FIXTURES:-0} builder_cpus=${MOUSE_BUILDER_CPUS:-8} builder_memory=${MOUSE_BUILDER_MEMORY:-8G} @@ -76,9 +78,13 @@ fi container_frontend=$(basename "$container_cli") case "$container_frontend" in container) + dockerfile_bytes=$(wc -c <"$repo_dir/Containerfile" | tr -d ' ') + if [ "$dockerfile_bytes" -gt 14700 ]; then + die "Containerfile is $dockerfile_bytes bytes; Apple Container 1.0 closes Dockerfile streams above roughly 14960 bytes. Move inline build logic into a helper script." + fi "$container_cli" system start >/dev/null builder_resources=$("$container_cli" builder status 2>/dev/null | - awk 'NR == 2 { print $5, $6 }') + awk 'NR == 2 { print $(NF - 2), $(NF - 1) }') if [ -n "$builder_resources" ]; then set -- $builder_resources actual_cpus=$1 @@ -95,7 +101,7 @@ case "$container_frontend" in esac "$repo_dir/scripts/check-source-locks.sh" -"$repo_dir/scripts/fetch-sources.sh" +MOUSE_SOURCE_DIR="$source_dir" "$repo_dir/scripts/fetch-sources.sh" mkdir -p "$output_dir" build_context=$(mktemp -d "$output_dir/.container-context.XXXXXX") @@ -119,14 +125,28 @@ trap cleanup EXIT HUP INT TERM --exclude='mouse-src/.containerignore' \ --exclude='mouse-src/scripts/build-in-container.sh' \ --exclude='mouse-src/base/cheesed/target/*' \ - mouse-src + --exclude='mouse-ports/.git/*' \ + mouse-src mouse-ports ) | tar -xf - -C "$build_context" cp "$repo_dir/Containerfile" "$build_context/Dockerfile" cp "$repo_dir/.containerignore" "$build_context/.dockerignore" -source_dir=${MOUSE_SOURCE_DIR:-"$output_dir/sources"} -for domain in toolchain kernel firmware facilities storage pkgsrc software; do +ports_revision=$(git -C "$repo_dir/../mouse-ports" rev-parse --short=12 HEAD) +if [ -n "$(git -C "$repo_dir/../mouse-ports" status --porcelain)" ]; then + ports_revision=$ports_revision-dirty +fi +printf '%s\n' "$ports_revision" >"$build_context/mouse-ports-revision" + +mkdir -p "$build_context/mouse-cargo" +( + cd "$source_dir/cargo" + tar -cf - . +) | tar -xf - -C "$build_context/mouse-cargo" + +for domain in \ + toolchain kernel firmware device-firmware wireless autotools facilities storage software +do domain_dir="$build_context/mouse-sources/$domain" mkdir -p "$domain_dir" while read -r checksum url filename extra; do @@ -154,6 +174,8 @@ done set -- "$@" \ --platform "$builder_platform" \ --target artifacts \ + --build-arg "MOUSE_ARCH=$MOUSE_ARCH" \ + --build-arg "MOUSE_TARGET_CONTAINER_PLATFORM=$MOUSE_TARGET_CONTAINER_PLATFORM" \ --build-arg "MOUSE_BUILD_JOBS=$build_jobs" \ --build-arg "MOUSE_ROOTFS_STAGE=$rootfs_stage" \ --output "type=local,dest=$export_dir" \ @@ -167,7 +189,7 @@ if [ ! -f "$artifacts_dir/vmlinuz-virt" ]; then artifacts_dir="$export_dir/out.tar/$platform_dir" fi -for artifact in vmlinuz-virt ovmf-code.fd; do +for artifact in vmlinuz-virt uefi-code.fd; do [ -f "$artifacts_dir/$artifact" ] || \ die "container build did not export $artifact" install -m 0644 "$artifacts_dir/$artifact" "$output_dir/$artifact" @@ -176,15 +198,37 @@ done artifact=mouse-disk.img [ -f "$artifacts_dir/$artifact.gz" ] || \ die "container build did not export $artifact.gz" + +# Apple Container keeps discarded BuildKit blocks allocated in its sparse +# volume until the guest filesystem is trimmed. Return those blocks before +# expanding the raw disk on the host, when both copies briefly coexist. +if [ "$container_frontend" = container ]; then + "$container_cli" exec buildkit fstrim / >/dev/null +fi + artifact_temp="$output_dir/.$artifact.tmp" -gzip -dc "$artifacts_dir/$artifact.gz" >"$artifact_temp" +compressed_artifact="$artifacts_dir/$artifact.gz" +gzip_magic=$(LC_ALL=C od -An -tx1 -N2 "$compressed_artifact" | tr -d ' \n') +[ "$gzip_magic" = 1f8b ] || die "container build exported invalid $artifact.gz" +gzip -dc "$compressed_artifact" >"$artifact_temp" + +gpt_signature=$(dd if="$artifact_temp" bs=1 skip=512 count=8 2>/dev/null) +[ "$gpt_signature" = "EFI PART" ] || \ + die "exported disk does not contain a GPT header" +root_start=$((2048 + 262144)) +btrfs_magic_offset=$((root_start * 512 + 65536 + 64)) +btrfs_magic=$(dd if="$artifact_temp" bs=1 \ + skip="$btrfs_magic_offset" count=8 2>/dev/null) +[ "$btrfs_magic" = "_BHRfS_M" ] || \ + die "exported disk does not contain a Btrfs root filesystem" + chmod 0644 "$artifact_temp" mv -f "$artifact_temp" "$output_dir/$artifact" artifact_temp= for artifact in \ vmlinuz-virt \ - ovmf-code.fd \ + uefi-code.fd \ mouse-disk.img do printf '%s\n' "exported $output_dir/$artifact" diff --git a/scripts/build-kernel-test-module.sh b/scripts/build-kernel-test-module.sh index 0f50c26..cc7a9cc 100755 --- a/scripts/build-kernel-test-module.sh +++ b/scripts/build-kernel-test-module.sh @@ -3,9 +3,10 @@ set -eu script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) repo_dir=$(dirname "$script_dir") -build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build"} +. "$script_dir/mouse-arch.sh" +build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build/$MOUSE_ARCH"} kernel_version=$(cat "$build_dir/kernel/release") -kernel_source="$build_dir/kernel/linux-6.18.35" +kernel_source="$build_dir/kernel/linux-7.1.6" kernel_output="$build_dir/kernel/output" module_output="$build_dir/kernel/module-test" module_root="$build_dir/kernel/test-modules" @@ -17,7 +18,7 @@ cp "$repo_dir/tests/fixtures/kernel-module/mouse_test.c" \ "$module_output/" make -s -C "$kernel_source" \ O="$kernel_output" \ - ARCH=x86_64 \ + ARCH="$MOUSE_KERNEL_ARCH" \ LLVM=1 \ M="$module_output" \ modules diff --git a/scripts/build-kernel.sh b/scripts/build-kernel.sh index 9613205..cfd4bcb 100755 --- a/scripts/build-kernel.sh +++ b/scripts/build-kernel.sh @@ -3,13 +3,14 @@ set -eu script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) repo_dir=$(dirname "$script_dir") -build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build"} -source_dir=${MOUSE_SOURCE_DIR:-"$build_dir/sources"} -kernel_version=6.18.35 +. "$script_dir/mouse-arch.sh" +build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build/$MOUSE_ARCH"} +source_dir=${MOUSE_SOURCE_DIR:-"$repo_dir/build/sources"} +kernel_version=7.1.6 kernel_archive="$source_dir/linux-$kernel_version.tar.xz" kernel_source="$build_dir/kernel/linux-$kernel_version" kernel_output="$build_dir/kernel/output" -kernel_config="$repo_dir/base/kernel/x86_64.config" +kernel_config="$repo_dir/base/kernel/$MOUSE_ARCH.config" jobs=${MOUSE_BUILD_JOBS:-$(getconf _NPROCESSORS_ONLN 2>/dev/null || printf '1\n')} if [ ! -f "$kernel_archive" ]; then @@ -28,7 +29,7 @@ mkdir -p "$kernel_output" make -C "$kernel_source" \ O="$kernel_output" \ - ARCH=x86_64 \ + ARCH="$MOUSE_KERNEL_ARCH" \ LLVM=1 \ KCONFIG_ALLCONFIG="$kernel_config" \ allnoconfig @@ -45,25 +46,31 @@ while IFS= read -r requested || [ -n "$requested" ]; do fi done <"$kernel_config" +if grep -Fqx 'CONFIG_LEGACY_TIOCSTI=y' "$kernel_output/.config"; then + printf '%s\n' \ + "kernel enables legacy TIOCSTI, which is unsafe across privilege boundaries" >&2 + exit 1 +fi + make -C "$kernel_source" \ O="$kernel_output" \ - ARCH=x86_64 \ + ARCH="$MOUSE_KERNEL_ARCH" \ LLVM=1 \ KBUILD_BUILD_USER=mouse \ KBUILD_BUILD_HOST=mouse \ -j"$jobs" \ - bzImage modules + "$MOUSE_KERNEL_TARGET" modules kernel_release=$(make -s -C "$kernel_source" \ O="$kernel_output" \ - ARCH=x86_64 \ + ARCH="$MOUSE_KERNEL_ARCH" \ LLVM=1 \ kernelrelease) module_root="$build_dir/kernel/modules" rm -rf "$module_root" make -s -C "$kernel_source" \ O="$kernel_output" \ - ARCH=x86_64 \ + ARCH="$MOUSE_KERNEL_ARCH" \ LLVM=1 \ INSTALL_MOD_PATH="$module_root" \ modules_install @@ -74,7 +81,7 @@ install -m 0644 "$kernel_output/.config" \ install -m 0644 "$kernel_output/Module.symvers" \ "$module_root/lib/modules/$kernel_release/Module.symvers" install -m 0644 \ - "$kernel_output/arch/x86/boot/bzImage" \ + "$kernel_output/$MOUSE_KERNEL_BUILD_PATH" \ "$build_dir/vmlinuz-virt" printf '%s\n' \ "built Linux $kernel_release with built-in btrfs and loadable-module support" diff --git a/scripts/build-mouse-ports-seed.sh b/scripts/build-mouse-ports-seed.sh new file mode 100755 index 0000000..ee6e668 --- /dev/null +++ b/scripts/build-mouse-ports-seed.sh @@ -0,0 +1,85 @@ +#!/bin/sh +set -eu + +ports_dir=${MOUSE_PORTS_DIR:-/usr/local/src/mouse-ports} +seed=${MOUSE_PORTS_SEED:-/opt/mouse-ports-seed} +distdir=${MOUSE_PORTS_DISTDIR:-/var/cache/mouse/ports/distfiles} +workbase=${MOUSE_PORTS_WORKDIR:-/var/tmp/mouse-ports} +bmake=${BMAKE:-/usr/bin/bmake} + +fail() +{ + printf '%s\n' "build-mouse-ports-seed: $*" >&2 + exit 1 +} + +[ -x "$bmake" ] || fail "missing BSD make: $bmake" +[ -f "$ports_dir/ports/Mk/mouse.port.mk" ] || fail "missing ports tree" +rm -rf "$seed" "$workbase" +mkdir -p "$seed/usr/local" "$distdir" "$workbase" + +for origin in \ + devel/bmake \ + devel/gmake \ + devel/libudev-garden \ + sysutils/seatd \ + x11/tuigreet \ + sysutils/greetd \ + devel/libffi \ + textproc/expat \ + graphics/wayland-protocols \ + graphics/wayland \ + graphics/libdrm \ + misc/hwdata \ + graphics/libdisplay-info \ + x11/libevdev \ + x11/mtdev \ + x11/libinput \ + x11/xkeyboard-config \ + x11/libxkbcommon \ + graphics/pixman \ + x11/wlroots \ + x11/havoc \ + x11/dwl +do + name=${origin##*/} + stage=$workbase/$name-stage + PATH="/usr/local/bin:$PATH" \ + PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/local/share/pkgconfig \ + "$bmake" -C "$ports_dir/ports/$origin" stage \ + BUILD_DEPENDS= RUN_DEPENDS= \ + DISTDIR="$distdir" \ + WRKDIR="$workbase/$name-work" \ + STAGEDIR="$stage" \ + MOUSE_FETCH=/usr/bin/curl \ + MOUSE_SHA256=/usr/bin/sha256sum \ + EXTRACT_CMD=/bin/tar \ + MESON=/usr/bin/meson \ + NINJA=/usr/bin/ninja \ + GMAKE="${GMAKE:-/usr/bin/make}" + rust_binary= + case "$origin" in + x11/tuigreet) rust_binary="$stage/usr/local/bin/tuigreet" ;; + sysutils/greetd) rust_binary="$stage/usr/local/sbin/greetd" ;; + esac + if [ -n "$rust_binary" ]; then + [ -x "$rust_binary" ] || fail "missing Rust executable: $rust_binary" + if /usr/bin/readelf -d "$rust_binary" 2>/dev/null | grep -q '(NEEDED)'; then + fail "Rust executable is dynamically linked: $rust_binary" + fi + fi + cp -R "$stage/usr/local/." /usr/local/ + cp -R "$stage/usr/local/." "$seed/usr/local/" + if [ "$origin" = devel/bmake ]; then + bmake=/usr/local/bin/bmake + [ -x "$bmake" ] || fail "staged BSD make is not executable: $bmake" + fi + if [ "$origin" = devel/gmake ]; then + GMAKE=/usr/local/bin/gmake + [ -x "$GMAKE" ] || fail "staged GNU make is not executable: $GMAKE" + fi +done + +install -d -m 0755 "$seed/usr/local/src" +cp -R "$ports_dir" "$seed/usr/local/src/mouse-ports" +printf '%s\n' "built mouse-ports desktop seed" diff --git a/scripts/build-pkgsrc-seed.sh b/scripts/build-pkgsrc-seed.sh deleted file mode 100755 index 63fc5a8..0000000 --- a/scripts/build-pkgsrc-seed.sh +++ /dev/null @@ -1,89 +0,0 @@ -#!/bin/sh -set -eu - -archive=${MOUSE_PKGSRC_ARCHIVE:-/usr/share/mouse/pkgsrc-2026Q2.tar.gz} -patch_file=${MOUSE_PKGSRC_PATCH:-/usr/share/mouse/pkgsrc-bootstrap-mouse.patch} -source_parent=/usr/local/src -pkgsrc=$source_parent/pkgsrc -mk_conf=/usr/local/etc/mk.conf -build_busybox=/usr/libexec/mouse-build-busybox - -fail() { - printf '%s\n' "build-pkgsrc-seed: $*" >&2 - exit 1 -} - -[ "$(id -u)" -eq 0 ] || fail "must run as root" -[ -f "$archive" ] || fail "missing pinned pkgsrc archive: $archive" -[ -f "$patch_file" ] || fail "missing MOUSE pkgsrc bootstrap patch: $patch_file" -[ -x "$build_busybox" ] || fail "missing build-only copy helper" -[ ! -e /usr/local/bin/bmake ] || fail "pkgsrc seed root is not empty" -[ ! -e /var/db/pkg ] || fail "pkgsrc package database already exists" - -mkdir -p \ - "$source_parent" \ - /usr/local/etc/rc.d \ - /tmp \ - /var/cache/pkgsrc/distfiles \ - /var/cache/pkgsrc/packages -chmod 1777 /tmp -tar -xzf "$archive" -C "$source_parent" -[ -x "$pkgsrc/bootstrap/bootstrap" ] || fail "archive did not produce a pkgsrc tree" -[ -f "$pkgsrc/mk/init/bsd.init.mk" ] || fail "pkgsrc tree lacks init-system support" -patch -d "$pkgsrc" -p1 <"$patch_file" -grep -Fq 'bootstrap_awk=/usr/bin/awk' "$pkgsrc/bootstrap/bootstrap" || - fail "pkgsrc tree lacks the MOUSE World awk policy" - -# Apple Rosetta reports ENOSYS for the copy operation used by MOUSE's static -# cp. Use an amd64 build-only applet while pkgsrc populates its work directory; -# only /usr/local and /var/db/pkg leave this stage. -mv /bin/cp /bin/cp.mouse -ln -s "$build_busybox" /bin/cp - -( - cd "$pkgsrc/bootstrap" - env \ - AWK=/usr/bin/awk \ - CC=/usr/bin/cc \ - CXX=/usr/bin/c++ \ - SH=/bin/sh \ - ./bootstrap \ - --compiler clang \ - --make-jobs "${MOUSE_BUILD_JOBS:-1}" \ - --pkgdbdir /var/db/pkg \ - --prefer-pkgsrc yes \ - --prefix /usr/local \ - --sysconfbase /usr/local/etc \ - --sysconfdir /usr/local/etc \ - --varbase /var -) - -rm /bin/cp -mv /bin/cp.mouse /bin/cp -rm "$build_busybox" - -cat >>"$mk_conf" <<'EOF' - -# MOUSE pkgsrc policy -PKGSRC_COMPILER= clang -LOCALBASE= /usr/local -PKG_SYSCONFBASE= /usr/local/etc -PKG_DBDIR= /var/db/pkg -VARBASE= /var -DISTDIR= /var/cache/pkgsrc/distfiles -PACKAGES= /var/cache/pkgsrc/packages -INIT_SYSTEM= rc.d -RCD_SCRIPTS_DIR= /usr/local/etc/rc.d -PKG_RCD_SCRIPTS= YES -PREFER_PKGSRC= yes -EOF - -ln -s /etc/rc.subr /usr/local/etc/rc.subr -rm -rf "$pkgsrc/bootstrap/work" - -[ -x /usr/local/bin/bmake ] || fail "bootstrap did not install bmake" -[ -x /usr/local/sbin/pkg_info ] || fail "bootstrap did not install pkg_info" -[ -d /var/db/pkg ] || fail "bootstrap did not create the package database" -grep -Eq '^TOOLS_PLATFORM\.awk\?=[[:space:]]*/usr/bin/awk$' "$mk_conf" || - fail "bootstrap did not preserve the World awk policy" -printf '%s\n' "built pkgsrc 2026Q2 seed" diff --git a/scripts/build-world-autotools.sh b/scripts/build-world-autotools.sh new file mode 100755 index 0000000..2da69ec --- /dev/null +++ b/scripts/build-world-autotools.sh @@ -0,0 +1,136 @@ +#!/bin/sh +set -eu + +source_dir=${MOUSE_SOURCE_DIR:-/opt/mouse-sources} +static_dir=${MOUSE_STATIC_DIR:-/work/mouse-src/build/static} +destination=${MOUSE_AUTOTOOLS_ROOT:-/opt/mouse-autotools} +jobs=${MOUSE_BUILD_JOBS:-1} + +case "$destination" in + /opt/mouse-autotools) ;; + *) + printf '%s\n' "refusing unexpected autotools destination: $destination" >&2 + exit 1 + ;; +esac + +build_root=$(mktemp -d /tmp/mouse-autotools.XXXXXX) +cleanup() +{ + rm -rf "$build_root" +} +trap cleanup EXIT HUP INT TERM + +install -d -m 0755 "$destination" "$build_root/bin" +extract() +{ + archive=$1 + [ -f "$source_dir/$archive" ] || { + printf '%s\n' "missing World source: $archive" >&2 + exit 1 + } + tar -xf "$source_dir/$archive" -C "$build_root" +} + +extract m4-1.4.21.tar.xz +extract perl-5.44.0.tar.xz +extract autoconf-2.72.tar.xz +extract automake-1.16.3.tar.xz + +cc=$(find "$static_dir/cross-tools/bin" -name '*-cc' -type l -print | head -1) +ar=$(find "$static_dir/cross-tools/bin" -name '*-ar' -type l -print | head -1) +ranlib=$(find "$static_dir/cross-tools/bin" -name '*-ranlib' -type l -print | head -1) +for tool in "$cc" "$ar" "$ranlib"; do + [ -x "$tool" ] || { + printf '%s\n' "missing MOUSE cross-build tool: $tool" >&2 + exit 1 + } +done +ln -s "$(command -v llvm-nm)" "$build_root/bin/nm" +PATH="$build_root/bin:$PATH" +export PATH + +( + cd "$build_root/m4-1.4.21" + CC="$cc" AR="$ar" RANLIB="$ranlib" \ + CFLAGS=-O2 LDFLAGS=-static \ + ./configure \ + --prefix=/usr \ + --disable-dependency-tracking \ + --disable-nls + make -s -j"$jobs" + make -s DESTDIR="$destination" install +) + +( + cd "$build_root/perl-5.44.0" + sh Configure -des \ + -Dprefix=/usr \ + -Dvendorprefix=/usr \ + -Dsiteprefix=/usr/local \ + -Dman1dir=/usr/share/man/man1 \ + -Dman3dir=/usr/share/man/man3 \ + -Dcc="$cc" \ + -Dld="$cc" \ + -Dar="$ar" \ + -Dnm=nm \ + -Dranlib="$ranlib" \ + -Dccflags=-O2 \ + -Dldflags=-static \ + -Doptimize=-O2 \ + -Duseithreads \ + -Uusedl \ + -Uuseshrplib + make -s -j"$jobs" + make -s install DESTDIR="$destination" +) + +# Autoconf is architecture-independent, but configure must record the paths +# that exist in the finished MOUSE image rather than the staging prefix. +install -m 0755 "$destination/usr/bin/m4" /usr/bin/m4 +( + cd "$build_root/autoconf-2.72" + PERL=/usr/bin/perl M4=/usr/bin/m4 \ + ./configure \ + --prefix=/usr + make -s -j"$jobs" + make -s DESTDIR="$destination" install +) + +# Automake's build needs the Autoconf we just staged. Its installed scripts +# record the final /usr paths, so mirror those files into this disposable +# builder rather than teaching the finished image about a staging prefix. +for tool in autoconf autoheader autom4te autoreconf autoscan autoupdate ifnames; do + install -m 0755 "$destination/usr/bin/$tool" "/usr/bin/$tool" +done +cp -R "$destination/usr/share/autoconf" /usr/share/autoconf + +( + cd "$build_root/automake-1.16.3" + PERL=/usr/bin/perl ./configure --prefix=/usr + make -s -j"$jobs" + make -s DESTDIR="$destination" install +) + +for executable in "$destination/usr/bin/m4" "$destination/usr/bin/perl"; do + readelf -l "$executable" | grep -q INTERP && { + printf '%s\n' "World executable is dynamically linked: $executable" >&2 + exit 1 + } + readelf -d "$executable" 2>/dev/null | grep -q NEEDED && { + printf '%s\n' "World executable has a dynamic dependency: $executable" >&2 + exit 1 + } +done + +"$destination/usr/bin/m4" --version | grep -Fq 'm4 (GNU M4) 1.4.21' +PERL5LIB="$destination/usr/share/automake-1.16" \ + "$destination/usr/bin/automake-1.16" --version | + grep -Fq 'automake (GNU automake) 1.16.3' +perl_config=$(find "$destination/usr/lib/perl5/5.44.0" -name Config.pm -type f -print | head -1) +[ -n "$perl_config" ] || { + printf '%s\n' 'World Perl installation is missing Config.pm' >&2 + exit 1 +} +PERL5LIB="$destination/usr/lib/perl5/5.44.0:$(dirname "$perl_config")" \ + "$destination/usr/bin/perl" -e 'use Config; die if $Config{usedl} eq "define"' diff --git a/scripts/check-source-locks.sh b/scripts/check-source-locks.sh index e6a5c3d..e52b648 100755 --- a/scripts/check-source-locks.sh +++ b/scripts/check-source-locks.sh @@ -16,15 +16,20 @@ MOUSE_VALIDATE_ONLY=1 "$script_dir/fetch-sources.sh" awk 'NF && $1 !~ /^#/ { print $3 }' \ "$lock_dir/toolchain.lock" \ "$lock_dir/kernel.lock" \ + "$lock_dir/wireless.lock" \ + "$lock_dir/autotools.lock" \ "$lock_dir/facilities.lock" \ "$lock_dir/storage.lock" \ "$lock_dir/software.lock" | LC_ALL=C sort -u >"$temporary/locked" -awk '$1 == "extract" { print $2 }' "$script_dir/static-base"/*.sh | +awk '$1 == "extract" { print $2 }' \ + "$script_dir/static-base"/*.sh \ + "$script_dir/build-world-autotools.sh" | LC_ALL=C sort -u >"$temporary/referenced-archives" sed -n 's/.*"$source_dir\/\([^"$]*\)".*/\1/p' \ "$script_dir/static-base"/*.sh \ + "$script_dir/build-world-autotools.sh" \ "$script_dir/build-boot-disk.sh" | LC_ALL=C sort -u >"$temporary/referenced-files" cat "$temporary/referenced-archives" "$temporary/referenced-files" | @@ -53,22 +58,40 @@ then printf '%s\n' "kernel.lock must contain exactly the Linux source" >&2 exit 1 fi -pkgsrc_count=$(awk 'NF && $1 !~ /^#/ { count++ } END { print count + 0 }' \ - "$lock_dir/pkgsrc.lock") -if [ "$pkgsrc_count" -ne 1 ] || \ - ! awk 'NF && $1 !~ /^#/ { print $3 }' "$lock_dir/pkgsrc.lock" | - grep -Eq '^pkgsrc-[0-9]{4}Q[1-4]\.tar\.gz$' -then - printf '%s\n' "pkgsrc.lock must contain exactly one stable pkgsrc archive" >&2 - exit 1 -fi firmware_count=$(awk 'NF && $1 !~ /^#/ { count++ } END { print count + 0 }' \ "$lock_dir/firmware.lock") -if [ "$firmware_count" -ne 1 ] || \ - ! awk 'NF && $1 !~ /^#/ { print $3 }' "$lock_dir/firmware.lock" | - grep -Eq '^ovmf-[^/]+\.apk$' +firmware_names=$(awk 'NF && $1 !~ /^#/ { print $3 }' \ + "$lock_dir/firmware.lock") +if [ "$firmware_count" -ne 2 ] || \ + [ "$(printf '%s\n' "$firmware_names" | grep -Ec '^aavmf-[^/]+\.apk$')" -ne 1 ] || \ + [ "$(printf '%s\n' "$firmware_names" | grep -Ec '^ovmf-[^/]+\.apk$')" -ne 1 ] then - printf '%s\n' "firmware.lock must contain exactly one OVMF package" >&2 + printf '%s\n' \ + "firmware.lock must contain exactly one AAVMF and one OVMF package" >&2 + exit 1 +fi +device_firmware_count=$(awk 'NF && $1 !~ /^#/ { count++ } END { print count + 0 }' \ + "$lock_dir/device-firmware.lock") +if [ "$device_firmware_count" -ne 1 ] || \ + ! awk 'NF && $1 !~ /^#/ { print $3 }' "$lock_dir/device-firmware.lock" | + grep -Eq '^linux-firmware-[0-9]{8}\.tar\.xz$' +then + printf '%s\n' \ + "device-firmware.lock must contain exactly one linux-firmware archive" >&2 + exit 1 +fi +autotools_count=$(awk 'NF && $1 !~ /^#/ { count++ } END { print count + 0 }' \ + "$lock_dir/autotools.lock") +autotools_names=$(awk 'NF && $1 !~ /^#/ { print $3 }' \ + "$lock_dir/autotools.lock") +if [ "$autotools_count" -ne 4 ] || \ + [ "$(printf '%s\n' "$autotools_names" | grep -Ec '^m4-[^/]+\.tar\.xz$')" -ne 1 ] || \ + [ "$(printf '%s\n' "$autotools_names" | grep -Ec '^perl-[^/]+\.tar\.xz$')" -ne 1 ] || \ + [ "$(printf '%s\n' "$autotools_names" | grep -Ec '^autoconf-[^/]+\.tar\.xz$')" -ne 1 ] || \ + [ "$(printf '%s\n' "$autotools_names" | grep -Ec '^automake-1\.16\.[^/]+\.tar\.xz$')" -ne 1 ] +then + printf '%s\n' \ + "autotools.lock must contain GNU m4, Perl, Autoconf, and Automake 1.16" >&2 exit 1 fi storage_count=$(awk 'NF && $1 !~ /^#/ { count++ } END { print count + 0 }' \ @@ -81,11 +104,20 @@ then exit 1 fi if awk 'NF && $1 !~ /^#/ { print $3 }' "$lock_dir/software.lock" | - grep -Eq '^(llvm-project|linux|btrfs-progs|less|mandoc|iproute2|nftables)-' + grep -Eq '^(llvm-project|linux|btrfs-progs|m4|perl|autoconf|automake|less|mandoc|iproute2|nftables)-' then printf '%s\n' "software.lock contains a source owned by another cache domain" >&2 exit 1 fi +if [ "$(awk 'NF && $1 !~ /^#/ && $3 ~ /^gardendevd-/ { count++ } END { print count + 0 }' \ + "$lock_dir/software.lock")" -ne 1 ] || \ + ! grep -Fq \ + 'gardendevd-611350ed44a116cffe6a53bbe8cfb13c721718f1.tar' \ + "$lock_dir/software.lock" +then + printf '%s\n' "software.lock must pin the audited gardendevd commit" >&2 + exit 1 +fi if awk 'NF && $1 !~ /^#/ { print $3 }' "$lock_dir/facilities.lock" | grep -Eq '^(llvm-project|linux|btrfs-progs)-' then @@ -131,6 +163,7 @@ for stage_script in \ static-base-bootstrap:bootstrap.sh \ static-base-libraries:libraries-and-accounts.sh \ static-base-system:system-services.sh \ + static-base-wireless:wireless.sh \ static-base-facilities:facilities.sh \ static-base-toolchain:native-toolchain.sh \ static-base-storage:storage.sh \ diff --git a/scripts/configure-cross-toolchain.sh b/scripts/configure-cross-toolchain.sh index f6419de..e80e1b7 100755 --- a/scripts/configure-cross-toolchain.sh +++ b/scripts/configure-cross-toolchain.sh @@ -9,6 +9,7 @@ fi script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) repo_dir=$(dirname "$script_dir") +. "$script_dir/mouse-arch.sh" destination=$1 sysroot=$2 clang=$3 @@ -18,7 +19,7 @@ builtins=$6 rust_eh_personality=$7 llvm_ar=$8 llvm_strip=$9 -target=x86_64-mouse-linux-musl +target=$MOUSE_CROSS_TARGET for requirement in \ "$clang" "$clangxx" "$lld" "$builtins" "$rust_eh_personality" "$llvm_ar" "$llvm_strip" @@ -41,6 +42,7 @@ printf '%s\n' \ "$lld" \ "$builtins" \ "$rust_eh_personality" \ + "$MOUSE_RUST_TARGET" \ >"$destination/compiler.conf" ln -sf compiler-driver "$destination/bin/$target-cc" diff --git a/scripts/extract-build-firmware.sh b/scripts/extract-build-firmware.sh new file mode 100755 index 0000000..25d8b7b --- /dev/null +++ b/scripts/extract-build-firmware.sh @@ -0,0 +1,23 @@ +#!/bin/sh +set -eu + +case "${MOUSE_ARCH:-}" in + x86_64) + firmware_apk=ovmf-0.0.202605-r0.apk + firmware_path=usr/share/OVMF/OVMF_CODE.fd + ;; + aarch64) + firmware_apk=aavmf-0.0.202605-r0.apk + firmware_path=usr/share/AAVMF/AAVMF_CODE.fd + ;; + *) + printf '%s\n' "unsupported MOUSE architecture: ${MOUSE_ARCH:-unset}" >&2 + exit 2 + ;; +esac + +install -d -m 0755 /opt/firmware +tar -xf "/opt/mouse-sources/$firmware_apk" \ + -C /opt/firmware \ + "$firmware_path" +install -m 0644 "/opt/firmware/$firmware_path" /uefi-code.fd diff --git a/scripts/fetch-sources.sh b/scripts/fetch-sources.sh index 494cc65..e2af636 100755 --- a/scripts/fetch-sources.sh +++ b/scripts/fetch-sources.sh @@ -3,8 +3,8 @@ set -eu script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) repo_dir=$(dirname "$script_dir") -build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build"} -source_dir=${MOUSE_SOURCE_DIR:-"$build_dir/sources"} +. "$script_dir/mouse-arch.sh" +source_dir=${MOUSE_SOURCE_DIR:-"$repo_dir/build/sources"} lock_dir="$repo_dir/release" if [ "$#" -eq 0 ]; then @@ -12,15 +12,19 @@ if [ "$#" -eq 0 ]; then "$lock_dir/toolchain.lock" \ "$lock_dir/kernel.lock" \ "$lock_dir/firmware.lock" \ + "$lock_dir/device-firmware.lock" \ + "$lock_dir/wireless.lock" \ + "$lock_dir/autotools.lock" \ "$lock_dir/facilities.lock" \ - "$lock_dir/pkgsrc.lock" \ "$lock_dir/storage.lock" \ "$lock_dir/software.lock" fi seen=$(mktemp "${TMPDIR:-/tmp}/mouse-source-locks.XXXXXX") +repository= cleanup() { rm -f "$seen" + [ -z "$repository" ] || rm -rf "$repository" } trap cleanup EXIT HUP INT TERM @@ -75,6 +79,7 @@ if [ "${MOUSE_VALIDATE_ONLY:-0}" = 1 ]; then fi mkdir -p "$source_dir" +source_dir=$(CDPATH= cd -- "$source_dir" && pwd) for lock_file in "$@"; do while read -r expected url filename extra; do @@ -86,16 +91,47 @@ for lock_file in "$@"; do if [ ! -f "$destination" ]; then temporary="$destination.part" printf '%s\n' "fetching $filename" - curl \ - --fail \ - --location \ - --proto '=https' \ - --tlsv1.2 \ - --connect-timeout 20 \ - --retry 4 \ - --retry-all-errors \ - "$url" \ - -o "$temporary" + case "$url" in + *.git) + project=${url##*/} + project=${project%.git} + revision=${filename#"$project-"} + revision=${revision%.tar} + case "$revision" in + ????????????????????????????????????????) ;; + *) printf '%s\n' "invalid Git archive revision: $filename" >&2; exit 1 ;; + esac + case "$revision" in + *[!0-9a-f]*) printf '%s\n' "invalid Git revision: $revision" >&2; exit 1 ;; + esac + repository=$(mktemp -d "${TMPDIR:-/tmp}/mouse-git-source.XXXXXX") + if git clone --quiet --no-checkout \ + "$url" "$repository" && + git -C "$repository" cat-file -e "$revision^{commit}" && + git -C "$repository" archive --format=tar \ + --prefix="$project/" -o "$temporary" "$revision" + then + : + else + rm -rf "$repository" "$temporary" + exit 1 + fi + rm -rf "$repository" + repository= + ;; + *) + curl \ + --fail \ + --location \ + --proto '=https' \ + --tlsv1.2 \ + --connect-timeout 20 \ + --retry 4 \ + --retry-all-errors \ + "$url" \ + -o "$temporary" + ;; + esac mv "$temporary" "$destination" fi @@ -112,3 +148,23 @@ for lock_file in "$@"; do fi done <"$lock_file" done + +command -v cargo >/dev/null 2>&1 || { + printf '%s\n' "cargo is required to prefetch cheesed dependencies" >&2 + exit 1 +} +cargo_home="$source_dir/cargo" +mkdir -p "$cargo_home" +if ! CARGO_HOME="$cargo_home" cargo fetch \ + --locked \ + --offline \ + --target "$MOUSE_RUST_TARGET" \ + --manifest-path "$repo_dir/base/cheesed/Cargo.toml" \ + 2>/dev/null +then + printf '%s\n' "fetching locked cheesed dependencies" + CARGO_HOME="$cargo_home" cargo fetch \ + --locked \ + --target "$MOUSE_RUST_TARGET" \ + --manifest-path "$repo_dir/base/cheesed/Cargo.toml" +fi diff --git a/scripts/mouse-arch.sh b/scripts/mouse-arch.sh new file mode 100644 index 0000000..6af4947 --- /dev/null +++ b/scripts/mouse-arch.sh @@ -0,0 +1,94 @@ +#!/bin/sh + +# MOUSE_ARCH describes the guest system. It is deliberately independent of +# MOUSE_BUILDER_PLATFORM, which describes the container host used to build it. +if [ -n "${MOUSE_ARCH:-}" ]; then + mouse_arch=$MOUSE_ARCH +elif [ -n "${MOUSE_BUILDER_PLATFORM:-}" ]; then + case "$MOUSE_BUILDER_PLATFORM" in + linux/amd64|linux/x86_64) mouse_arch=x86_64 ;; + linux/arm64|linux/arm64/v8|linux/aarch64) mouse_arch=aarch64 ;; + *) + printf '%s\n' \ + "cannot derive MOUSE_ARCH from MOUSE_BUILDER_PLATFORM: $MOUSE_BUILDER_PLATFORM" >&2 + return 2 2>/dev/null || exit 2 + ;; + esac +else + mouse_arch=$(uname -m) +fi +case "$mouse_arch" in + x86_64|amd64) MOUSE_ARCH=x86_64 ;; + aarch64|arm64) MOUSE_ARCH=aarch64 ;; + *) + printf '%s\n' "unsupported MOUSE architecture: $mouse_arch" >&2 + return 2 2>/dev/null || exit 2 + ;; +esac + +case "$MOUSE_ARCH" in + x86_64) + MOUSE_RUST_TARGET=x86_64-unknown-linux-musl + MOUSE_GNU_TARGET=x86_64-linux-musl + MOUSE_CROSS_TARGET=x86_64-mouse-linux-musl + MOUSE_MUSL_TARGET=x86_64 + MOUSE_KERNEL_ARCH=x86 + MOUSE_KERNEL_BUILD_PATH=arch/x86/boot/bzImage + MOUSE_KERNEL_TARGET=bzImage + MOUSE_LLVM_TARGET=X86 + MOUSE_CMAKE_PROCESSOR=x86_64 + MOUSE_COMPILER_RT_ARCH=x86_64 + MOUSE_OPENSSL_TARGET=linux-x86_64 + MOUSE_MUSL_LOADER=ld-musl-x86_64.so.1 + MOUSE_EFI_LOADER=BOOTX64.EFI + MOUSE_FIRMWARE_APK=ovmf-0.0.202605-r0.apk + MOUSE_FIRMWARE_PATH=usr/share/OVMF/OVMF_CODE.fd + MOUSE_TARGET_CONTAINER_PLATFORM=linux/amd64 + MOUSE_QEMU_SYSTEM=qemu-system-x86_64 + MOUSE_QEMU_MACHINE=q35 + MOUSE_CONSOLE=ttyS0 + ;; + aarch64) + MOUSE_RUST_TARGET=aarch64-unknown-linux-musl + MOUSE_GNU_TARGET=aarch64-linux-musl + MOUSE_CROSS_TARGET=aarch64-mouse-linux-musl + MOUSE_MUSL_TARGET=aarch64 + MOUSE_KERNEL_ARCH=arm64 + MOUSE_KERNEL_BUILD_PATH=arch/arm64/boot/Image + MOUSE_KERNEL_TARGET=Image + MOUSE_LLVM_TARGET=AArch64 + MOUSE_CMAKE_PROCESSOR=aarch64 + MOUSE_COMPILER_RT_ARCH=aarch64 + MOUSE_OPENSSL_TARGET=linux-aarch64 + MOUSE_MUSL_LOADER=ld-musl-aarch64.so.1 + MOUSE_EFI_LOADER=BOOTAA64.EFI + MOUSE_FIRMWARE_APK=aavmf-0.0.202605-r0.apk + MOUSE_FIRMWARE_PATH=usr/share/AAVMF/AAVMF_CODE.fd + MOUSE_TARGET_CONTAINER_PLATFORM=linux/arm64 + MOUSE_QEMU_SYSTEM=qemu-system-aarch64 + MOUSE_QEMU_MACHINE=virt + MOUSE_CONSOLE=ttyAMA0 + ;; +esac + +export \ + MOUSE_ARCH \ + MOUSE_RUST_TARGET \ + MOUSE_GNU_TARGET \ + MOUSE_CROSS_TARGET \ + MOUSE_MUSL_TARGET \ + MOUSE_KERNEL_ARCH \ + MOUSE_KERNEL_BUILD_PATH \ + MOUSE_KERNEL_TARGET \ + MOUSE_LLVM_TARGET \ + MOUSE_CMAKE_PROCESSOR \ + MOUSE_COMPILER_RT_ARCH \ + MOUSE_OPENSSL_TARGET \ + MOUSE_MUSL_LOADER \ + MOUSE_EFI_LOADER \ + MOUSE_FIRMWARE_APK \ + MOUSE_FIRMWARE_PATH \ + MOUSE_TARGET_CONTAINER_PLATFORM \ + MOUSE_QEMU_SYSTEM \ + MOUSE_QEMU_MACHINE \ + MOUSE_CONSOLE diff --git a/scripts/run-qemu.sh b/scripts/run-qemu.sh index e8d7f76..f70f4a3 100755 --- a/scripts/run-qemu.sh +++ b/scripts/run-qemu.sh @@ -3,22 +3,33 @@ set -eu script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) repo_dir=$(dirname "$script_dir") -build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build"} +. "$script_dir/mouse-arch.sh" +build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build/$MOUSE_ARCH"} boot_mode=${MOUSE_BOOT_MODE:-firmware} kernel_args=${MOUSE_KERNEL_ARGS:-} disk_image=${MOUSE_DISK_IMAGE:-"$build_dir/mouse-disk.img"} disk_bus=${MOUSE_DISK_BUS:-virtio} -firmware=${MOUSE_FIRMWARE:-bios} -uefi_code=${MOUSE_UEFI_CODE:-"$build_dir/ovmf-code.fd"} +if [ "$MOUSE_ARCH" = x86_64 ]; then + default_firmware=bios +else + default_firmware=uefi +fi +firmware=${MOUSE_FIRMWARE:-$default_firmware} +uefi_code=${MOUSE_UEFI_CODE:-"$build_dir/uefi-code.fd"} network=${MOUSE_NETWORK:-0} network_backend=${MOUSE_NETWORK_BACKEND:-user} network_device=${MOUSE_NETWORK_DEVICE:-virtio} memory=${MOUSE_MEMORY:-512M} +graphical=${MOUSE_GRAPHICAL:-0} -if [ -n "${QEMU_SYSTEM_X86_64:-}" ]; then +if [ -n "${MOUSE_QEMU:-}" ]; then + qemu=$MOUSE_QEMU +elif [ "$MOUSE_ARCH" = x86_64 ] && [ -n "${QEMU_SYSTEM_X86_64:-}" ]; then qemu=$QEMU_SYSTEM_X86_64 +elif [ "$MOUSE_ARCH" = aarch64 ] && [ -n "${QEMU_SYSTEM_AARCH64:-}" ]; then + qemu=$QEMU_SYSTEM_AARCH64 else - qemu=qemu-system-x86_64 + qemu=$MOUSE_QEMU_SYSTEM fi case "$qemu" in @@ -30,7 +41,7 @@ case "$qemu" in ;; *) if ! command -v "$qemu" >/dev/null 2>&1; then - printf '%s\n' "qemu-system-x86_64 is required to boot the image" >&2 + printf '%s\n' "$MOUSE_QEMU_SYSTEM is required to boot the image" >&2 exit 1 fi ;; @@ -48,7 +59,7 @@ case "$disk_bus" in disk_device="virtio-blk-pci,drive=mouse-root,disable-legacy=on" ;; sata) - disk_controller="ich9-ahci,id=mouse-ahci" + disk_controller="ahci,id=mouse-ahci" disk_device="ide-hd,drive=mouse-root,bus=mouse-ahci.0" ;; nvme) @@ -61,16 +72,39 @@ case "$disk_bus" in esac set -- "$qemu" \ - -machine q35,accel=tcg \ + -machine "$MOUSE_QEMU_MACHINE,accel=tcg" \ -cpu max \ -m "$memory" \ -no-reboot \ - -display none \ - -nographic \ -nic none +case "$graphical" in + 0) + if [ "$MOUSE_ARCH" = aarch64 ]; then + set -- "$@" -device virtio-gpu-pci + fi + set -- "$@" -display none -nographic + ;; + 1) + set -- "$@" \ + -device virtio-gpu-pci \ + -device virtio-keyboard-pci \ + -device virtio-tablet-pci \ + -serial stdio + ;; + *) + printf '%s\n' "invalid MOUSE_GRAPHICAL: $graphical" >&2 + exit 2 + ;; +esac + case "$firmware" in - bios) ;; + bios) + if [ "$MOUSE_ARCH" != x86_64 ]; then + printf '%s\n' "BIOS boot is only supported for MOUSE_ARCH=x86_64" >&2 + exit 2 + fi + ;; uefi) if [ ! -f "$uefi_code" ]; then printf '%s\n' "missing pinned UEFI firmware: $uefi_code" >&2 @@ -102,7 +136,7 @@ case "$boot_mode" in printf '%s\n' "missing root disk: $disk_image" >&2 exit 1 fi - kernel_args=${kernel_args:-"console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed panic=-1"} + kernel_args=${kernel_args:-"console=$MOUSE_CONSOLE root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed panic=-1"} set -- "$@" \ -kernel "$build_dir/vmlinuz-virt" \ -drive "$disk_drive" @@ -120,7 +154,7 @@ esac case "$network" in 0) ;; 1) - if ! "$qemu" -netdev help 2>&1 | + if ! "$qemu" -machine "$MOUSE_QEMU_MACHINE" -netdev help 2>&1 | grep -Fxq "$network_backend"; then printf '%s\n' \ "QEMU does not provide the requested network backend: $network_backend" \ diff --git a/scripts/static-base/bootstrap.sh b/scripts/static-base/bootstrap.sh index a65ab9d..8880c6d 100644 --- a/scripts/static-base/bootstrap.sh +++ b/scripts/static-base/bootstrap.sh @@ -24,78 +24,91 @@ extract() { tar -xf "$source_dir/$1" -C "$source_build_dir" } -extract meson-1.9.1.tar.gz -extract ninja-1.13.1.tar.gz -extract pkgconf-2.5.1.tar.gz -extract linux-6.18.35.tar.xz +extract meson-1.11.2.tar.gz +extract ninja-1.13.2.tar.gz +extract pkgconf-3.0.5.tar.gz +extract linux-7.1.6.tar.xz extract musl-1.2.6.tar.gz extract zlib-1.3.2.tar.gz -extract libarchive-3.8.7.tar.xz -extract llvm-project-22.1.3.src.tar.xz +extract libarchive-3.8.9.tar.xz +extract llvm-project-22.1.8.src.tar.xz extract netbsd-curses-0.3.2.tar.gz -extract attr-2.5.2.tar.gz -extract acl-2.3.2.tar.gz +extract attr-2.6.0.tar.gz +extract acl-2.4.0.tar.gz extract libxo-1.7.5.tar.gz extract tcsh-6.24.16.tar.gz extract chimerautils-15.0.3.tar.gz -extract openssl-3.5.7.tar.gz +extract openssl-4.0.1.tar.gz extract util-linux-2.42.2.tar.xz extract libxcrypt-4.5.2.tar.xz -extract shadow-4.19.4.tar.xz -extract dhcpcd-8b312918d8f1885d7fe8fcc03a7e06ae8a0314b4.tar.gz +extract shadow-4.20.0.tar.xz +extract opendoas-6.8.2.tar.xz +extract dhcpcd-e3363cf477aa53d4ed74d00ce5d3d4c7e5b7f2c3.tar.gz extract make-4.4.1.tar.gz extract cronie-1.7.2.tar.gz extract openntpd-7.9p1.tar.gz -extract procps-ng-4.0.5.tar.xz +extract procps-ng-4.0.6.tar.xz extract iputils-20250605.tar.gz extract kmod-34.2.tar.xz -extract skalibs-2.15.1.0.tar.gz -extract mdevd-0.1.8.2.tar.gz +extract gardendevd-611350ed44a116cffe6a53bbe8cfb13c721718f1.tar extract sysklogd-2.7.2.tar.gz ( - cd "$source_build_dir/ninja-1.13.1" + cd "$source_build_dir/ninja-1.13.2" python3 configure.py --bootstrap install -m 0755 ninja "$tools_dir/bin/ninja" ) -meson_source="$source_build_dir/meson-1.9.1/meson.py" +meson_source="$source_build_dir/meson-1.11.2/meson.py" PATH="$tools_dir/bin:$PATH" export PATH python3 "$meson_source" setup \ - "$source_build_dir/pkgconf-pkgconf-2.5.1/build" \ - "$source_build_dir/pkgconf-pkgconf-2.5.1" \ + "$source_build_dir/pkgconf-pkgconf-3.0.5/build" \ + "$source_build_dir/pkgconf-pkgconf-3.0.5" \ --prefix="$tools_dir" \ --buildtype=release \ --default-library=static -python3 "$meson_source" compile -C "$source_build_dir/pkgconf-pkgconf-2.5.1/build" -python3 "$meson_source" install -C "$source_build_dir/pkgconf-pkgconf-2.5.1/build" +python3 "$meson_source" compile -C "$source_build_dir/pkgconf-pkgconf-3.0.5/build" +python3 "$meson_source" install -C "$source_build_dir/pkgconf-pkgconf-3.0.5/build" -musl_cc="$clang --target=x86_64-unknown-linux-musl --ld-path=$lld" -musl_mulxc3="$static_dir/musl-mulxc3.o" +musl_cc="$clang --target=$MOUSE_RUST_TARGET --ld-path=$lld" +rust_eh_personality="$static_dir/rust-eh-personality.o" "$clang" \ - --target=x86_64-unknown-linux-musl \ + --target="$MOUSE_RUST_TARGET" \ --sysroot="$sysroot" \ - -fPIC \ - -I"$source_build_dir/llvm-project-22.1.3.src/compiler-rt/lib/builtins" \ - -c "$source_build_dir/llvm-project-22.1.3.src/compiler-rt/lib/builtins/mulxc3.c" \ - -o "$musl_mulxc3" + -c "$repo_dir/base/support/rust-eh-personality.c" \ + -o "$rust_eh_personality" +musl_libcc="$builtins $rust_eh_personality" +if [ "$MOUSE_ARCH" = x86_64 ]; then + # Rust's x86_64 musl builtins omit the 80-bit long-double complex helper + # required by musl. AArch64 uses 128-bit long double and its target archive + # already provides the corresponding helper. + musl_mulxc3="$static_dir/musl-mulxc3.o" + "$clang" \ + --target="$MOUSE_RUST_TARGET" \ + --sysroot="$sysroot" \ + -fPIC \ + -I"$source_build_dir/llvm-project-22.1.8.src/compiler-rt/lib/builtins" \ + -c "$source_build_dir/llvm-project-22.1.8.src/compiler-rt/lib/builtins/mulxc3.c" \ + -o "$musl_mulxc3" + musl_libcc="$musl_libcc $musl_mulxc3" +fi ( cd "$source_build_dir/musl-1.2.6" CC="$musl_cc" \ AR="$llvm_ar" \ RANLIB="$llvm_ranlib" \ ./configure \ - --target=x86_64 \ + --target="$MOUSE_MUSL_TARGET" \ --prefix=/usr \ --syslibdir=/lib - make -s -j"$jobs" LIBCC="$builtins $musl_mulxc3" - make -s DESTDIR="$sysroot" LIBCC="$builtins $musl_mulxc3" install + make -s -j"$jobs" LIBCC="$musl_libcc" + make -s DESTDIR="$sysroot" LIBCC="$musl_libcc" install ) -make -s -C "$source_build_dir/linux-6.18.35" \ - ARCH=x86 \ +make -s -C "$source_build_dir/linux-7.1.6" \ + ARCH="$MOUSE_KERNEL_ARCH" \ headers_install \ INSTALL_HDR_PATH="$sysroot/usr" @@ -105,13 +118,6 @@ install -m 0644 "$source_dir/queue.h" "$sysroot/usr/include/sys/queue.h" install -m 0644 "$source_dir/tree.h" "$sysroot/usr/include/sys/tree.h" install -m 0644 "$source_dir/error.h" "$sysroot/usr/include/error.h" -rust_eh_personality="$static_dir/rust-eh-personality.o" -"$clang" \ - --target=x86_64-unknown-linux-musl \ - --sysroot="$sysroot" \ - -c "$repo_dir/base/support/rust-eh-personality.c" \ - -o "$rust_eh_personality" - "$script_dir/configure-cross-toolchain.sh" \ "$cross_tools_dir" \ "$sysroot" \ @@ -123,7 +129,7 @@ rust_eh_personality="$static_dir/rust-eh-personality.o" "$llvm_ar" \ "$llvm_strip" -target=x86_64-mouse-linux-musl +target=$MOUSE_CROSS_TARGET cc="$cross_tools_dir/bin/$target-cc" cxx="$cross_tools_dir/bin/$target-c++" bootstrap_cxx="$cross_tools_dir/bin/$target-bootstrap-c++" @@ -134,17 +140,18 @@ strip="$cross_tools_dir/bin/$target-strip" llvm_runtimes_build="$source_build_dir/llvm-runtimes-build" cmake \ -G Ninja \ - -S "$source_build_dir/llvm-project-22.1.3.src/runtimes" \ + -S "$source_build_dir/llvm-project-22.1.8.src/runtimes" \ -B "$llvm_runtimes_build" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr \ -DCMAKE_C_COMPILER="$cc" \ - -DCMAKE_C_COMPILER_TARGET=x86_64-unknown-linux-musl \ + -DCMAKE_C_COMPILER_TARGET="$MOUSE_RUST_TARGET" \ -DCMAKE_CXX_COMPILER="$bootstrap_cxx" \ - -DCMAKE_CXX_COMPILER_TARGET=x86_64-unknown-linux-musl \ + -DCMAKE_CXX_COMPILER_TARGET="$MOUSE_RUST_TARGET" \ -DCMAKE_AR="$ar" \ -DCMAKE_RANLIB="$ranlib" \ -DCMAKE_SYSTEM_NAME=Linux \ + -DCMAKE_SYSTEM_PROCESSOR="$MOUSE_CMAKE_PROCESSOR" \ -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \ -DLLVM_ENABLE_RUNTIMES="compiler-rt;libcxx;libcxxabi;libunwind" \ -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF \ @@ -176,26 +183,40 @@ cmake \ cmake --build "$llvm_runtimes_build" -j "$jobs" DESTDIR="$sysroot" cmake --install "$llvm_runtimes_build" -clang_runtime_dir="$sysroot/usr/lib/clang/22/lib/x86_64-unknown-linux-musl" +clang_runtime_dir=$compiler_rt_dir install -d -m 0755 "$clang_runtime_dir" install -m 0644 \ - "$sysroot/usr/lib/linux/libclang_rt.builtins-x86_64.a" \ + "$sysroot/usr/lib/linux/libclang_rt.builtins-$MOUSE_COMPILER_RT_ARCH.a" \ "$clang_runtime_dir/libclang_rt.builtins.a" for runtime_object in \ - clang_rt.crtbegin-x86_64.o \ - clang_rt.crtend-x86_64.o + "clang_rt.crtbegin-$MOUSE_COMPILER_RT_ARCH.o" \ + "clang_rt.crtend-$MOUSE_COMPILER_RT_ARCH.o" do install -m 0644 \ "$sysroot/usr/lib/linux/$runtime_object" \ "$clang_runtime_dir/$runtime_object" done install -m 0644 \ - "$sysroot/usr/lib/linux/clang_rt.crtbegin-x86_64.o" \ + "$sysroot/usr/lib/linux/clang_rt.crtbegin-$MOUSE_COMPILER_RT_ARCH.o" \ "$sysroot/usr/lib/crtbeginT.o" install -m 0644 \ - "$sysroot/usr/lib/linux/clang_rt.crtend-x86_64.o" \ + "$sysroot/usr/lib/linux/clang_rt.crtend-$MOUSE_COMPILER_RT_ARCH.o" \ "$sysroot/usr/lib/crtend.o" +# Rust's target builtins are only the seed needed to build compiler-rt. Use +# MOUSE's complete target runtime for every later base-system link; AArch64 in +# particular needs its instruction-cache helper when linking LLVM Support. +"$script_dir/configure-cross-toolchain.sh" \ + "$cross_tools_dir" \ + "$sysroot" \ + "$clang" \ + "$clangxx" \ + "$lld" \ + "$compiler_rt" \ + "$rust_eh_personality" \ + "$llvm_ar" \ + "$llvm_strip" + { printf '%s\n' \ '[binaries]' \ @@ -207,8 +228,8 @@ install -m 0644 \ '' \ '[host_machine]' \ "system = 'linux'" \ - "cpu_family = 'x86_64'" \ - "cpu = 'x86_64'" \ + "cpu_family = '$MOUSE_CMAKE_PROCESSOR'" \ + "cpu = '$MOUSE_CMAKE_PROCESSOR'" \ "endian = 'little'" \ '' \ '[built-in options]' \ diff --git a/scripts/static-base/common.sh b/scripts/static-base/common.sh index 4eb1990..8e70bbf 100644 --- a/scripts/static-base/common.sh +++ b/scripts/static-base/common.sh @@ -3,8 +3,9 @@ component_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) script_dir=$(dirname "$component_dir") repo_dir=$(dirname "$script_dir") -build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build"} -source_dir=${MOUSE_SOURCE_DIR:-"$build_dir/sources"} +. "$script_dir/mouse-arch.sh" +build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build/$MOUSE_ARCH"} +source_dir=${MOUSE_SOURCE_DIR:-"$repo_dir/build/sources"} static_dir="$build_dir/static" source_build_dir="$static_dir/src" sysroot="$static_dir/sysroot" @@ -14,14 +15,14 @@ cross_tools_dir="$static_dir/cross-tools" jobs=${MOUSE_BUILD_JOBS:-$(getconf _NPROCESSORS_ONLN 2>/dev/null || printf '2')} case "$static_dir" in - "$repo_dir"/build/static) ;; + "$repo_dir"/build/static|"$repo_dir"/build/"$MOUSE_ARCH"/static) ;; *) printf '%s\n' "refusing to clear unexpected static build path: $static_dir" >&2 exit 1 ;; esac -target_libdir=$(rustc --print target-libdir --target x86_64-unknown-linux-musl) +target_libdir=$(rustc --print target-libdir --target "$MOUSE_RUST_TARGET") builtins=$(find "$target_libdir" -maxdepth 1 -name 'libcompiler_builtins-*.rlib' -print | head -1) clang=$(command -v clang) @@ -42,10 +43,10 @@ do done llvm_ranlib="$tools_dir/bin/llvm-ranlib" -meson_source="$source_build_dir/meson-1.9.1/meson.py" +meson_source="$source_build_dir/meson-1.11.2/meson.py" PATH="$tools_dir/bin:$PATH" export PATH -target=x86_64-mouse-linux-musl +target=$MOUSE_CROSS_TARGET cc="$cross_tools_dir/bin/$target-cc" cxx="$cross_tools_dir/bin/$target-c++" bootstrap_cxx="$cross_tools_dir/bin/$target-bootstrap-c++" @@ -53,3 +54,5 @@ ar="$cross_tools_dir/bin/$target-ar" ranlib="$cross_tools_dir/bin/$target-ranlib" strip="$cross_tools_dir/bin/$target-strip" cross_file="$static_dir/chimerautils.cross" +compiler_rt_dir="$sysroot/usr/lib/clang/22/lib/$MOUSE_RUST_TARGET" +compiler_rt="$compiler_rt_dir/libclang_rt.builtins.a" diff --git a/scripts/static-base/dynamic-runtime.sh b/scripts/static-base/dynamic-runtime.sh index 9132542..6a9c177 100755 --- a/scripts/static-base/dynamic-runtime.sh +++ b/scripts/static-base/dynamic-runtime.sh @@ -5,7 +5,7 @@ component_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) . "$component_dir/common.sh" for runtime_file in \ - /lib/ld-musl-x86_64.so.1 \ + "/lib/$MOUSE_MUSL_LOADER" \ /usr/lib/libc.so \ /usr/lib/crt1.o \ /usr/lib/Scrt1.o \ @@ -59,9 +59,9 @@ EOF chmod 0755 "$wrapper" } -dynamic_cc="$cross_tools_dir/bin/x86_64-mouse-linux-musl-dynamic-cc" -dynamic_cxx="$cross_tools_dir/bin/x86_64-mouse-linux-musl-dynamic-c++" -dynamic_builtins="$sysroot/usr/lib/clang/22/lib/x86_64-unknown-linux-musl/libclang_rt.builtins.a" +dynamic_cc="$cross_tools_dir/bin/$MOUSE_CROSS_TARGET-dynamic-cc" +dynamic_cxx="$cross_tools_dir/bin/$MOUSE_CROSS_TARGET-dynamic-c++" +dynamic_builtins=$compiler_rt if [ ! -f "$dynamic_builtins" ]; then printf '%s\n' "missing compiler-rt builtins: $dynamic_builtins" >&2 exit 1 @@ -69,20 +69,27 @@ fi make_dynamic_compiler "$dynamic_cc" "$cc" make_dynamic_compiler "$dynamic_cxx" "$bootstrap_cxx" +llvm_source_dir="$source_build_dir/llvm-project-22.1.8.src" +if [ ! -d "$llvm_source_dir/runtimes" ]; then + tar -C "$source_build_dir" \ + -xf "$source_dir/llvm-project-22.1.8.src.tar.xz" +fi + shared_runtimes_build="$source_build_dir/llvm-shared-runtimes-build" cmake \ -G Ninja \ - -S "$source_build_dir/llvm-project-22.1.3.src/runtimes" \ + -S "$llvm_source_dir/runtimes" \ -B "$shared_runtimes_build" \ -DCMAKE_BUILD_TYPE=MinSizeRel \ -DCMAKE_INSTALL_PREFIX=/usr \ -DCMAKE_C_COMPILER="$dynamic_cc" \ - -DCMAKE_C_COMPILER_TARGET=x86_64-unknown-linux-musl \ + -DCMAKE_C_COMPILER_TARGET="$MOUSE_RUST_TARGET" \ -DCMAKE_CXX_COMPILER="$dynamic_cxx" \ - -DCMAKE_CXX_COMPILER_TARGET=x86_64-unknown-linux-musl \ + -DCMAKE_CXX_COMPILER_TARGET="$MOUSE_RUST_TARGET" \ -DCMAKE_AR="$ar" \ -DCMAKE_RANLIB="$ranlib" \ -DCMAKE_SYSTEM_NAME=Linux \ + -DCMAKE_SYSTEM_PROCESSOR="$MOUSE_CMAKE_PROCESSOR" \ -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \ -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF \ @@ -107,15 +114,17 @@ cmake --build "$shared_runtimes_build" -j "$jobs" DESTDIR="$sysroot" cmake --install "$shared_runtimes_build" cp -R "$sysroot/usr/lib/." "$base_root/usr/lib/" -cat >"$base_root/usr/bin/clang.cfg" <<'EOF' ---target=x86_64-unknown-linux-musl +rm -rf "$shared_runtimes_build" "$llvm_source_dir" + +cat >"$base_root/usr/bin/clang.cfg" <"$base_root/usr/bin/clang++.cfg" <<'EOF' ---target=x86_64-unknown-linux-musl +cat >"$base_root/usr/bin/clang++.cfg" <"$base_root/usr/bin/clang.cfg" <<'EOF' ---target=x86_64-unknown-linux-musl +cat >"$base_root/usr/bin/clang.cfg" <"$base_root/usr/bin/clang++.cfg" <<'EOF' ---target=x86_64-unknown-linux-musl +cat >"$base_root/usr/bin/clang++.cfg" <"$wpa_build/.config" <<'EOF' +CONFIG_DRIVER_NL80211=y +CONFIG_LIBNL32=y +CONFIG_CTRL_IFACE=y +CONFIG_BACKEND=file +CONFIG_TLS=openssl +CONFIG_IEEE8021X_EAPOL=y +CONFIG_EAP_MD5=y +CONFIG_EAP_MSCHAPV2=y +CONFIG_EAP_TLS=y +CONFIG_EAP_PEAP=y +CONFIG_EAP_TTLS=y +CONFIG_EAP_GTC=y +CONFIG_WPS=y +CONFIG_SAE=y +CONFIG_OWE=y +CONFIG_BGSCAN_SIMPLE=y +CONFIG_NO_CONFIG_BLOBS=y +EOF + +( + cd "$wpa_build" + CC="$cc" \ + PKG_CONFIG="$tools_dir/bin/pkgconf" \ + PKG_CONFIG_LIBDIR="$sysroot/usr/lib/pkgconfig" \ + PKG_CONFIG_SYSROOT_DIR="$sysroot" \ + CFLAGS="-O2 -I$sysroot/usr/include" \ + LDFLAGS="-static" \ + make -s -j"$jobs" wpa_supplicant wpa_cli wpa_passphrase +) + +install -m 0755 "$wpa_build/wpa_supplicant" "$base_root/sbin/wpa_supplicant" +install -m 0755 "$wpa_build/wpa_cli" "$base_root/usr/bin/wpa_cli" +install -m 0755 "$wpa_build/wpa_passphrase" "$base_root/usr/bin/wpa_passphrase" diff --git a/tests/acceptance/admin.exp b/tests/acceptance/admin.exp new file mode 100755 index 0000000..be21b08 --- /dev/null +++ b/tests/acceptance/admin.exp @@ -0,0 +1,56 @@ +#!/usr/bin/expect -f + +if {$argc != 2} { + puts stderr "usage: admin.exp RUNNER DISK" + exit 2 +} +set runner [file normalize [lindex $argv 0]] +set disk [file normalize [lindex $argv 1]] +set timeout 180 +set acceptance_name "admin" +source [file join [file dirname [info script]] harness.exp] + +acceptance_log +set env(MOUSE_BOOT_MODE) disk +set env(MOUSE_DISK_IMAGE) $disk +set env(MOUSE_NETWORK) 0 +set env(MOUSE_GRAPHICAL) 0 +set env(MOUSE_KERNEL_ARGS) "console=$env(MOUSE_CONSOLE) root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed panic=-1 quiet loglevel=3" +spawn -noecho $runner + +await_exact "mousehole login: " "the administrator login prompt" +sendline {mouse} +await_exact "Password: " "the administrator password prompt" +sendline {cheddar} +await_exact "mouse:~> " "the administrator shell" +sendline {sh -c 'test -u /usr/bin/doas && test "$(stat -f "%u %g" /usr/bin/doas)" = "0 0"'; echo DOAS_METADATA_$status} +await_exact "DOAS_METADATA_0\r" "the installed doas metadata" +await_exact "mouse:~> " "the prompt after the doas metadata check" +sendline {sh -c '! findmnt -n -o OPTIONS / | tr , "\n" | grep -qx nosuid'; echo ROOT_SUID_$status} +await_exact "ROOT_SUID_0\r" "a root mount that permits setuid execution" +await_exact "mouse:~> " "the prompt after the root mount check" +sendline {grep -Eq '^NoNewPrivs:[[:space:]]+0$' /proc/self/status; echo NO_NEW_PRIVS_$status} +await_exact "NO_NEW_PRIVS_0\r" "the login process privilege state" +await_exact "mouse:~> " "the prompt after the privilege-state check" +sendline {test -c /dev/dri/card0; echo GRAPHICS_$status} +await_exact "GRAPHICS_0\r" "the virtio GPU DRM device" +await_exact "mouse:~> " "the prompt after the graphics-device check" +sendline {doas id} +await_exact "doas (mouse@mousehole) password: " "the doas password prompt" +sendline {cheddar} +await_exact "uid=0(root) gid=0(root) groups=0(root)\r" "authenticated doas elevation" +await_exact "mouse:~> " "the administrator prompt after doas" +sendline {exit} +await_exact "mousehole login: " "the respawned login prompt" +sendline {mouse} +await_exact "Password: " "the administrator password prompt after respawn" +sendline {cheddar} +await_exact "mouse:~> " "the administrator shell after login respawn" +sendline {doas poweroff} +await_exact "doas (mouse@mousehole) password: " "the doas password prompt for poweroff" +sendline {cheddar} +await_exact "cheesed: received poweroff request" "the privileged poweroff request" +await_exact "cheesed: root filesystem remounted read-only" "the read-only root remount" +await_clean_exit "poweroff" + +puts "administrator and graphical-console prerequisites passed" diff --git a/tests/acceptance/admin.sh b/tests/acceptance/admin.sh new file mode 100755 index 0000000..499af7d --- /dev/null +++ b/tests/acceptance/admin.sh @@ -0,0 +1,10 @@ +#!/bin/sh +set -eu + +acceptance_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +. "$acceptance_dir/harness.sh" +acceptance_init +acceptance_require_commands "the administrator acceptance test" expect +acceptance_copy_disk admin + +exec expect "$acceptance_dir/admin.exp" "$runner" "$test_disk" diff --git a/tests/acceptance/boot.exp b/tests/acceptance/boot.exp index c0da336..8764c4a 100755 --- a/tests/acceptance/boot.exp +++ b/tests/acceptance/boot.exp @@ -15,14 +15,15 @@ proc boot_mouse {runner} { spawn -noecho $runner await_exact "Cheesed to meet you! v0.1.0" "the cheesed startup banner" await_exact "cheesed: base bootstrap complete; cheesed is PID 1" "PID 1 confirmation" - await_exact "MOUSE 0.1.0 (x86_64)" "the MOUSE login banner" + global env + await_exact "MOUSE 0.1.0 ($env(MOUSE_ARCH))" "the MOUSE login banner" await_exact "mouse:~# " "the root shell prompt" } boot_mouse $runner send -- "hostname\r" -await_exact "mouse\r" "the configured hostname" +await_exact "mousehole\r" "the configured hostname" await_exact "mouse:~# " "the prompt after hostname" send -- "cat /proc/1/comm\r" @@ -33,6 +34,16 @@ send -- "sh -c 'test -c /dev/null'; echo DEV_STATUS_\$?\r" await_exact "DEV_STATUS_0\r" "a mounted devtmpfs" await_exact "mouse:~# " "the prompt after the devtmpfs check" +send -- {sh -c 'test -r /run/gardendevd.pid && test -d /run/udev/data && gardendevctl settle -t 1'; echo GARDENDEV_STATUS_$?} +send -- "\r" +await_exact "GARDENDEV_STATUS_0\r" "settled gardendevd trigger queue" +await_exact "mouse:~# " "the prompt after the gardendevd check" + +send -- {sh -c 'test -c /dev/rtc0 && test "$(cat /sys/class/rtc/rtc0/hctosys)" = 1 && test "$(date -u +%Y)" -ge 2024'; echo RTC_STATUS_$?} +send -- "\r" +await_exact "RTC_STATUS_0\r" "the hardware-backed system clock" +await_exact "mouse:~# " "the prompt after the RTC check" + send -- "clear; echo CLEAR_STATUS_\$?\r" await_exact "CLEAR_STATUS_0\r" "a successful clear command" await_exact "mouse:~# " "the prompt after clear" diff --git a/tests/acceptance/boot.sh b/tests/acceptance/boot.sh index badf7db..34db6ef 100755 --- a/tests/acceptance/boot.sh +++ b/tests/acceptance/boot.sh @@ -7,7 +7,7 @@ acceptance_init acceptance_require_commands "the boot acceptance test" expect acceptance_copy_disk boot -MOUSE_KERNEL_ARGS="console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1 quiet loglevel=3" +MOUSE_KERNEL_ARGS="console=$MOUSE_CONSOLE root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1 quiet loglevel=3" MOUSE_BOOT_MODE=disk MOUSE_DISK_IMAGE="$test_disk" MOUSE_NETWORK=0 diff --git a/tests/acceptance/btrfs.exp b/tests/acceptance/btrfs.exp index 6104cd3..1da2294 100755 --- a/tests/acceptance/btrfs.exp +++ b/tests/acceptance/btrfs.exp @@ -21,17 +21,17 @@ set env(MOUSE_DISK_IMAGE) $disk set env(MOUSE_MEMORY) 1G set env(MOUSE_BOOT_MODE) disk -set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1" +set env(MOUSE_KERNEL_ARGS) "console=$env(MOUSE_CONSOLE) root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1" spawn -noecho $runner await_exact "cheesed: base bootstrap complete; cheesed is PID 1" "PID 1 confirmation" -await_exact "mouse login: root (automatic login)" "the serial login" +await_exact "mousehole login: root (automatic login)" "the serial login" await_prompt sendline {sh -c "grep -Eq '^[^ ]+ / btrfs ' /proc/mounts && grep -Eq '^[^ ]+ /usr/local btrfs ' /proc/mounts && grep -Eq '^[^ ]+ /var btrfs ' /proc/mounts && grep -Eq '^[^ ]+ /home btrfs ' /proc/mounts && grep -Eq '^[^ ]+ /srv btrfs ' /proc/mounts"; echo MOUNTS_$?} await_exact "MOUNTS_0\r" "the btrfs root and persistent subvolume mounts" await_exact "mouse:~# " "the prompt after mount verification" sendline {btrfs version; echo VERSION_$?} -await_exact "btrfs-progs v7.0\r" "the pinned btrfs userspace version" +await_exact "btrfs-progs v7.1\r" "the pinned btrfs userspace version" await_exact "VERSION_0\r" "the btrfs version status" await_exact "mouse:~# " "the prompt after version" diff --git a/tests/acceptance/firmware.exp b/tests/acceptance/firmware.exp index e4b8eee..f8a763c 100755 --- a/tests/acceptance/firmware.exp +++ b/tests/acceptance/firmware.exp @@ -15,7 +15,7 @@ source [file join [file dirname [info script]] harness.exp] acceptance_log spawn -noecho $runner await_exact "Cheesed to meet you! v0.1.0" "MOUSE through the Limine firmware path" -await_exact "mouse login: " "the authenticated firmware-boot login" +await_exact "mousehole login: " "the authenticated firmware-boot login" sendline {root} await_exact "Password: " "the root password prompt" sendline {cheddar} @@ -27,6 +27,9 @@ switch -- $check { raw-sata { set check_command {[ -e /sys/block/sda ]} } + raw-uefi-virtio { + set check_command {[ -d /sys/firmware/efi ] && [ -e /sys/block/vda ]} + } raw-uefi-sata { set check_command {[ -d /sys/firmware/efi ] && [ -e /sys/block/sda ]} } @@ -38,8 +41,8 @@ switch -- $check { exit 2 } } -sendline "sh -c 'grep -q \"root=PARTUUID=4d4f5553-4500-4000-8000-000000000002\" /proc/cmdline && grep -Eq \"^\[^ \]+ / btrfs \" /proc/mounts && $check_command'; echo FIRMWARE_\$?" -await_exact "FIRMWARE_0\r" "the GPT, Limine, PARTUUID, and Btrfs boot contract" +sendline "sh -c 'grep -q \"root=PARTUUID=4d4f5553-4500-4000-8000-000000000002\" /proc/cmdline && grep -Eq \"^\[^ \]+ / btrfs \" /proc/mounts && test -c /dev/rtc0 && test \"\$(cat /sys/class/rtc/rtc0/hctosys)\" = 1 && test \"\$(date -u +%Y)\" -ge 2024 && $check_command'; echo FIRMWARE_\$?" +await_exact "FIRMWARE_0\r" "the GPT, Limine, PARTUUID, Btrfs, and RTC boot contract" await_exact "mouse:~# " "the prompt after firmware verification" poweroff diff --git a/tests/acceptance/firmware.sh b/tests/acceptance/firmware.sh index 1db6631..f4c176d 100755 --- a/tests/acceptance/firmware.sh +++ b/tests/acceptance/firmware.sh @@ -7,9 +7,9 @@ acceptance_init acceptance_require_commands "the firmware acceptance test" expect acceptance_require_file \ "$build_dir/mouse-disk.img" \ - "run 'make check' before checking BIOS firmware" + "run 'make check' before checking firmware" acceptance_require_file \ - "$build_dir/ovmf-code.fd" \ + "$build_dir/uefi-code.fd" \ "run 'make check' before checking UEFI firmware" acceptance_make_temporary firmware @@ -28,18 +28,22 @@ run_firmware() MOUSE_DISK_IMAGE="$disk" \ MOUSE_DISK_BUS="$bus" \ MOUSE_FIRMWARE="$firmware" \ - MOUSE_UEFI_CODE="$build_dir/ovmf-code.fd" \ + MOUSE_UEFI_CODE="$build_dir/uefi-code.fd" \ MOUSE_MEMORY="${MOUSE_MEMORY:-1G}" \ expect "$acceptance_dir/firmware.exp" "$runner" "$label" "$check" } -run_firmware "BIOS raw VirtIO" raw-virtio \ - "$raw_disk" virtio bios -run_firmware "BIOS raw AHCI" raw-sata \ - "$raw_disk" sata bios -run_firmware "UEFI raw AHCI" raw-uefi-sata \ - "$raw_disk" sata uefi +if [ "$MOUSE_ARCH" = x86_64 ]; then + run_firmware "BIOS raw VirtIO" raw-virtio \ + "$raw_disk" virtio bios + run_firmware "BIOS raw AHCI" raw-sata \ + "$raw_disk" sata bios + run_firmware "UEFI raw AHCI" raw-uefi-sata \ + "$raw_disk" sata uefi +fi +run_firmware "UEFI raw VirtIO" raw-uefi-virtio \ + "$raw_disk" virtio uefi run_firmware "UEFI raw NVMe" raw-uefi-nvme \ "$raw_disk" nvme uefi -printf '%s\n' "BIOS and UEFI firmware acceptance passed" +printf '%s\n' "$MOUSE_ARCH firmware acceptance passed" diff --git a/tests/acceptance/harness.sh b/tests/acceptance/harness.sh index 8da567f..2c2fc24 100644 --- a/tests/acceptance/harness.sh +++ b/tests/acceptance/harness.sh @@ -3,8 +3,9 @@ acceptance_init() { acceptance_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) repo_dir=$(CDPATH= cd -- "$acceptance_dir/../.." && pwd) + . "$repo_dir/scripts/mouse-arch.sh" runner="$repo_dir/scripts/run-qemu.sh" - build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build"} + build_dir=${MOUSE_BUILD_DIR:-"$repo_dir/build/$MOUSE_ARCH"} temporary= } diff --git a/tests/acceptance/multi-user.exp b/tests/acceptance/multi-user.exp index 88a8b1a..892912d 100755 --- a/tests/acceptance/multi-user.exp +++ b/tests/acceptance/multi-user.exp @@ -20,28 +20,28 @@ set env(MOUSE_BOOT_MODE) disk set env(MOUSE_DISK_IMAGE) $disk set env(MOUSE_NETWORK) 0 if {$mode eq "provision"} { - set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1 quiet loglevel=3" + set env(MOUSE_KERNEL_ARGS) "console=$env(MOUSE_CONSOLE) root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1 quiet loglevel=3" } else { - set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed panic=-1 quiet loglevel=3" + set env(MOUSE_KERNEL_ARGS) "console=$env(MOUSE_CONSOLE) root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed panic=-1 quiet loglevel=3" } spawn -noecho $runner if {$mode eq "provision"} { - await "mouse login: root (automatic login)" "the provisioning login" + await "mousehole login: root (automatic login)" "the provisioning login" await "mouse:~# " "the provisioning shell" - sendline {groupadd -R /run/mouse-root/ROOT/default operators; useradd -R /run/mouse-root/ROOT/default -M -g operators -s /bin/tcsh alice; mkdir /run/mouse-root/home/alice; chown 1000:1000 /run/mouse-root/home/alice; echo CREATE_$status} + sendline {groupadd -R /run/mouse-root/ROOT/default operators; useradd -R /run/mouse-root/ROOT/default -M -g operators -s /bin/tcsh alice; mkdir /run/mouse-root/home/alice; chown 1001:1001 /run/mouse-root/home/alice; echo CREATE_$?} await "CREATE_0\r" "account creation" await "mouse:~# " "the provisioning prompt" - sendline {sh -c 'grep -q "^root:x:0:0:root:/root:/bin/sh$" /run/mouse-root/ROOT/default/etc/passwd && grep -q "^toor:x:0:0:BSD-style root account:/root:/bin/tcsh$" /run/mouse-root/ROOT/default/etc/passwd'; echo ADMIN_$status} + sendline {sh -c 'grep -q "^root:x:0:0:root:/root:/bin/sh$" /run/mouse-root/ROOT/default/etc/passwd && grep -q "^toor:x:0:0:BSD-style root account:/root:/bin/tcsh$" /run/mouse-root/ROOT/default/etc/passwd'; echo ADMIN_$?} await "ADMIN_0\r" "the BSD-style administrator accounts" await "mouse:~# " "the provisioning prompt" - sendline {sh -c 'usermod -R /run/mouse-root/ROOT/default -p "$(head -n 1 /run/mouse-root/ROOT/default/etc/shadow | cut -d: -f2)" alice'; echo PASSWORD_$status} + sendline {sh -c 'usermod -R /run/mouse-root/ROOT/default -p "$(head -n 1 /run/mouse-root/ROOT/default/etc/shadow | cut -d: -f2)" alice'; echo PASSWORD_$?} await "PASSWORD_0\r" "the alternate-root password setup" await "mouse:~# " "the provisioning prompt" - sendline {sh -c 'test "$(grep "^alice:" /run/mouse-root/ROOT/default/etc/shadow | cut -d: -f2)" = "$(head -n 1 /run/mouse-root/ROOT/default/etc/shadow | cut -d: -f2)" && grep -q "^alice:x:1000:1000::/home/alice:/bin/tcsh$" /run/mouse-root/ROOT/default/etc/passwd'; echo ACCOUNT_$status} + sendline {sh -c 'test "$(grep "^alice:" /run/mouse-root/ROOT/default/etc/shadow | cut -d: -f2)" = "$(head -n 1 /run/mouse-root/ROOT/default/etc/shadow | cut -d: -f2)" && grep -q "^alice:x:1001:1001::/home/alice:/bin/tcsh$" /run/mouse-root/ROOT/default/etc/passwd'; echo ACCOUNT_$?} await "ACCOUNT_0\r" "the on-disk login account" await "mouse:~# " "the provisioning prompt" - sendline {echo enable_mouse_echo=YES >/run/mouse-root/ROOT/default/etc/rc.conf; echo enable_network=NO >>/run/mouse-root/ROOT/default/etc/rc.conf; echo POLICY_$status} + sendline {echo enable_mouse_echo=YES >/run/mouse-root/ROOT/default/etc/rc.conf; echo enable_network=NO >>/run/mouse-root/ROOT/default/etc/rc.conf; echo POLICY_$?} await "POLICY_0\r" "the offline test policy" await "mouse:~# " "the provisioning prompt" poweroff @@ -49,7 +49,7 @@ if {$mode eq "provision"} { exit 0 } -await "mouse login: " "the authenticated login prompt" +await "mousehole login: " "the authenticated login prompt" set timeout 2 expect { -exact "root (automatic login)" { fail "normal disk enabled root autologin" } @@ -61,14 +61,14 @@ await "Password: " "the password prompt" if {$mode eq "login"} { sendline {wrong-password} await "Login incorrect" "failed authentication rejection" - await "mouse login: " "the retry login prompt" + await "mousehole login: " "the retry login prompt" sendline {alice} await "Password: " "the second password prompt" } sendline {cheddar} await "mouse:~> " "the ordinary user shell" sendline {id} -await "uid=1000(alice) gid=1000(operators) groups=1000(operators)\r" "the ordinary identity" +await "uid=1001(alice) gid=1001(operators) groups=1001(operators)\r" "the ordinary identity" await "mouse:~> " "the user prompt" sendline {sh -c 'test "$HOME" = /home/alice && test "$SHELL" = /bin/tcsh && test -O /home/alice && ! touch /usr/alice-must-not-write'; echo USER_$status} await "USER_0\r" "home ownership and base protection" diff --git a/tests/acceptance/network.exp b/tests/acceptance/network.exp index cf940b3..b41db89 100755 --- a/tests/acceptance/network.exp +++ b/tests/acceptance/network.exp @@ -34,16 +34,16 @@ acceptance_log set env(MOUSE_BOOT_MODE) disk set env(MOUSE_DISK_IMAGE) $disk set env(MOUSE_NETWORK) 1 -set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1" +set env(MOUSE_KERNEL_ARGS) "console=$env(MOUSE_CONSOLE) root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1" spawn -noecho $runner await "Starting network" "the network service" -await "mouse login: root (automatic login)" "the test login" +await "mousehole login: root (automatic login)" "the test login" await "cheesed: service graph started; cgroup supervision active" "the completed service graph" send -- "\r" prompt -sendline {sh -c 'test -s /run/mouse-network.ready && grep -q eth0 /proc/net/route && grep -q 00000000 /proc/net/route && grep -q "^nameserver " /etc/resolv.conf'; echo LEASE_$?} +sendline {sh -c 'i=0; while [ ! -s /run/mouse-network.ready ] && [ "$i" -lt 60 ]; do sleep 1; i=$((i + 1)); done; test -s /run/mouse-network.ready && grep -q eth0 /proc/net/route && grep -q 00000000 /proc/net/route && grep -q "^nameserver " /etc/resolv.conf'; echo LEASE_$?} await "LEASE_0\r" "the DHCP route and resolver state" prompt sendline {nc -z -w 5 1.1.1.1 80; echo IP_$?} @@ -60,7 +60,7 @@ sendline {service network restart} await "Stopping network" "runtime network stop" await "Starting network" "runtime network restart" prompt -sendline {sh -c 'test -s /run/mouse-network.ready'; echo RESTART_$?} +sendline {sh -c 'i=0; while [ ! -s /run/mouse-network.ready ] && [ "$i" -lt 60 ]; do sleep 1; i=$((i + 1)); done; test -s /run/mouse-network.ready'; echo RESTART_$?} await "RESTART_0\r" "the renewed lease" prompt diff --git a/tests/acceptance/pkgsrc.exp b/tests/acceptance/pkgsrc.exp deleted file mode 100755 index 94f45ed..0000000 --- a/tests/acceptance/pkgsrc.exp +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/expect -f - -if {$argc != 3} { - puts stderr "usage: pkgsrc.exp RUNNER DISK MODE" - exit 2 -} -set runner [file normalize [lindex $argv 0]] -set disk [file normalize [lindex $argv 1]] -set mode [lindex $argv 2] -if {$mode ni {install verify}} { - puts stderr "invalid pkgsrc mode: $mode" - exit 2 -} -set timeout 1800 -set acceptance_name "pkgsrc" -source [file join [file dirname [info script]] harness.exp] - -acceptance_log -set env(MOUSE_BOOT_MODE) disk -set env(MOUSE_DISK_IMAGE) $disk -set env(MOUSE_NETWORK) 1 -set env(MOUSE_MEMORY) 2G -set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1" -spawn -noecho $runner - -await_exact "mouse login: root (automatic login)" "the serial login" -await_prompt - -if {$mode eq "install"} { - sendline {sh -c 'test "$(cat /usr/share/mouse/pkgsrc.version)" = 2026Q2 && test ! -e /usr/share/mouse/pkgsrc-2026Q2.tar.gz'; echo SOURCE_$?} - await_exact "SOURCE_0\r" "the pkgsrc release marker without a duplicate archive" - await_exact "mouse:~# " "the prompt after source verification" - - sendline {sh -c "test \"$(command -v make)\" = /usr/bin/make && make --version | grep -q '^GNU Make 4.4.1$' && test \"$(command -v bmake)\" = /usr/local/bin/bmake && test ! -e /usr/share/mk && test \"$(command -v pkg_add)\" = /usr/local/sbin/pkg_add && test \"$(command -v pkg_info)\" = /usr/local/sbin/pkg_info && test \"$(command -v less)\" = /usr/bin/less && test -f /usr/local/share/mk/bsd.own.mk && test -d /var/db/pkg && test -d /usr/local/src/pkgsrc && pkg_info -e 'bootstrap-mk-files-[0-9]*' >/dev/null && pkg_info -e 'bmake-[0-9]*' >/dev/null && pkg_info -e 'pkg_install-[0-9]*' >/dev/null"; echo SEED_$?} - await_exact "SEED_0\r" "the release-built pkgsrc seed" - await_exact "mouse:~# " "the prompt after seed verification" - - sendline {sh -c "grep -Eq '^TOOLS_PLATFORM\.awk\?=[[:space:]]*/usr/bin/awk$' /usr/local/etc/mk.conf && grep -Eq '^LOCALBASE=[[:space:]]*/usr/local$' /usr/local/etc/mk.conf && grep -Eq '^PKG_DBDIR=[[:space:]]*/var/db/pkg$' /usr/local/etc/mk.conf && grep -Eq '^INIT_SYSTEM=[[:space:]]*rc\.d$' /usr/local/etc/mk.conf && grep -Eq '^RCD_SCRIPTS_DIR=[[:space:]]*/usr/local/etc/rc\.d$' /usr/local/etc/mk.conf && grep -Eq '^PKG_RCD_SCRIPTS=[[:space:]]*YES$' /usr/local/etc/mk.conf && test -L /usr/local/etc/rc.subr"; echo POLICY_$?} - await_exact "POLICY_0\r" "the pkgsrc prefix, database, service, and MOUSE ABI policy" - await_exact "mouse:~# " "the prompt after policy verification" - - sendline {cp -R /usr/share/mouse/pkgsrc-fixture/local /usr/local/src/pkgsrc/; bmake -C /usr/local/src/pkgsrc/local/mouse-hello install; echo INSTALL_$?} - await_exact "INSTALL_0\r" "the pkgsrc package installation" - await_exact "mouse:~# " "the prompt after package installation" - sendline {/usr/local/bin/mouse-hello; sh -c "test -x /usr/local/etc/rc.d/mouse_hello && /usr/local/sbin/pkg_info -L mouse-hello | grep -qx /usr/local/share/examples/rc.d/mouse_hello && readelf -l /usr/local/bin/mouse-hello | grep -q INTERP && readelf -d /usr/local/bin/mouse-hello | grep -q NEEDED"; /usr/local/sbin/pkg_info -e 'mouse-hello-[0-9]*'; echo PACKAGE_$?} - await_exact "Hello from pkgsrc on MOUSE\r" "the installed pkgsrc command" - await_regexp {mouse-hello-1\.0\r} "the pkgsrc package record" - await_exact "PACKAGE_0\r" "the installed package status" - await_exact "mouse:~# " "the prompt before starting the newly installed service" - sendline {service mouse_hello start; sh -c 'test -f /run/mouse-hello-service.ready'; service mouse_hello status; echo RUNTIME_$?} - await_exact "mouse_hello running\r" "the newly discovered pkgsrc service start" - await_exact "mouse_hello running\r" "the newly discovered pkgsrc service status" - await_exact "RUNTIME_0\r" "the newly installed service runtime control" - await_exact "mouse:~# " "the prompt before enabling the pkgsrc service" - sendline {printf '%s\n' 'enable_mouse_hello=YES' >>/etc/rc.conf; echo ENABLE_$?} - await_exact "ENABLE_0\r" "the persistent pkgsrc service policy" -} else { - sendline {sh -c 'test -x /usr/local/bin/mouse-hello && test -d /var/db/pkg && test -f /run/mouse-hello-service.ready && service mouse_hello status >/dev/null && grep -Eq "^LOCALBASE=[[:space:]]*/usr/local$" /usr/local/etc/mk.conf'; /usr/local/bin/mouse-hello; /usr/local/sbin/pkg_info -e 'mouse-hello-[0-9]*'; echo PERSIST_$?} - await_exact "Hello from pkgsrc on MOUSE\r" "the persistent pkgsrc command" - await_regexp {mouse-hello-1\.0\r} "the persistent package record" - await_exact "PERSIST_0\r" "the persistent pkgsrc state" -} - -await_exact "mouse:~# " "the prompt before poweroff" -poweroff -puts "$mode pkgsrc acceptance passed" diff --git a/tests/acceptance/pkgsrc.sh b/tests/acceptance/pkgsrc.sh deleted file mode 100755 index cd0faa9..0000000 --- a/tests/acceptance/pkgsrc.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh -set -eu - -acceptance_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) -. "$acceptance_dir/harness.sh" -acceptance_init -server_pid= - -acceptance_cleanup_extra() { - if [ -n "$server_pid" ]; then - kill "$server_pid" 2>/dev/null || : - wait "$server_pid" 2>/dev/null || : - fi -} - -acceptance_require_commands "the pkgsrc acceptance test" expect python3 -acceptance_copy_disk pkgsrc - -python3 -m http.server 18080 \ - --bind 127.0.0.1 \ - --directory "$repo_dir/tests/fixtures/pkgsrc/distfiles" \ - >"$temporary/http.log" 2>&1 & -server_pid=$! -sleep 1 -if ! kill -0 "$server_pid" 2>/dev/null; then - printf '%s\n' "pkgsrc source server failed to start" >&2 - cat "$temporary/http.log" >&2 - exit 1 -fi - -"$acceptance_dir/pkgsrc.exp" "$runner" "$test_disk" install -"$acceptance_dir/pkgsrc.exp" "$runner" "$test_disk" verify -printf '%s\n' "pkgsrc seed, rc.d installation, and persistence tests passed" diff --git a/tests/acceptance/service-integration.exp b/tests/acceptance/service-integration.exp index 30a55ad..6b54a97 100755 --- a/tests/acceptance/service-integration.exp +++ b/tests/acceptance/service-integration.exp @@ -21,7 +21,7 @@ set env(MOUSE_BOOT_MODE) disk set env(MOUSE_DISK_IMAGE) $disk set env(MOUSE_NETWORK) 0 set env(MOUSE_MEMORY) 1G -set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1" +set env(MOUSE_KERNEL_ARGS) "console=$env(MOUSE_CONSOLE) root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1" spawn -noecho $runner if {$mode eq "failure"} { @@ -31,7 +31,7 @@ if {$mode eq "failure"} { sendline {sh -c 'set -- `cat /proc/$PPID/stat`; cat /proc/$4/comm'} await_exact "cheesed\r" "the emergency shell parent" await_exact "mouse:~# " "the prompt after the emergency parent check" - sendline {mv /etc/rc.d/console_login.good /etc/rc.d/console_login; chmod 0755 /etc/rc.d/console_login} + sendline {mv /etc/console_login.good /etc/rc.d/console_login; chmod 0755 /etc/rc.d/console_login} await_exact "mouse:~# " "the prompt after restoring console login" poweroff puts "required-service failure acceptance passed" @@ -40,14 +40,14 @@ if {$mode eq "failure"} { await_exact "cheesed: base bootstrap complete; cheesed is PID 1" "PID 1 confirmation" if {$mode eq "disabled"} { - await_exact "cheesed: enabled optional services: (none)" "disabled service policy" + await_exact "cheesed: enabled optional services: cron, gardendevd, greetd, network, ntpd, seatd" "disabled service policy" } else { - await_exact "cheesed: enabled optional services: mouse_echo" "enabled service policy" + await_exact "cheesed: enabled optional services: cron, gardendevd, greetd, mouse_echo, network, ntpd, seatd" "enabled service policy" } await_exact "cheesed: service graph started; cgroup supervision active" "the supervised service graph" await_prompt -sendline {sh -c 'test "$(cat /proc/1/comm)" = cheesed && test -S /run/cheesed.sock && test -f /sys/fs/cgroup/mouse.services/console_login/cgroup.events; echo BASE_$?'} +sendline {sh -c 'test "$(cat /proc/1/comm)" = cheesed && test -S /run/cheesed.sock && test -f /sys/fs/cgroup/mouse.services/gardendevd/cgroup.events && test -f /sys/fs/cgroup/mouse.services/console_login/cgroup.events && test -f /sys/fs/cgroup/mouse.services/seatd/cgroup.events && test -f /sys/fs/cgroup/mouse.services/greetd/cgroup.events; echo BASE_$?'} await_exact "BASE_0\r" "the cheesed and cgroup service contract" await_exact "mouse:~# " "the prompt after the base contract check" sendline {service console_login status} @@ -67,7 +67,7 @@ if {$mode eq "disabled"} { sendline {service mouse_echo stop} await_exact "mouse_echo stopped\r" "the runtime-only service stop" await_exact "mouse:~# " "the prompt after the runtime stop" - sendline {sh -c 'cp /etc/rc.d/console_login /etc/rc.d/console_login.good && printf "#!/bin/sh\nexit 42\n" >/etc/rc.d/console_login && chmod 0755 /etc/rc.d/console_login'; echo FAILURE_$?} + sendline {sh -c 'cp /etc/rc.d/console_login /etc/console_login.good && printf "#!/bin/sh\nexit 42\n" >/etc/rc.d/console_login && chmod 0755 /etc/rc.d/console_login'; echo FAILURE_$?} await_exact "FAILURE_0\r" "the required-service failure setup" await_exact "mouse:~# " "the prompt after failure setup" poweroff diff --git a/tests/acceptance/storage.exp b/tests/acceptance/storage.exp index 2dd581f..af154d8 100755 --- a/tests/acceptance/storage.exp +++ b/tests/acceptance/storage.exp @@ -19,7 +19,7 @@ source [file join [file dirname [info script]] harness.exp] acceptance_log set env(MOUSE_BOOT_MODE) disk set env(MOUSE_DISK_IMAGE) $disk -set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1" +set env(MOUSE_KERNEL_ARGS) "console=$env(MOUSE_CONSOLE) root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1" spawn -noecho $runner @@ -44,7 +44,7 @@ await_exact "cheesed: base bootstrap complete; cheesed is PID 1" "PID 1 confirma if {$mode eq "verify"} { await_exact "cheesed: enabled optional services: (none)" "persisted service policy" } -await_exact "mouse login: root (automatic login)" "the serial login" +await_exact "mousehole login: root (automatic login)" "the serial login" await_prompt if {$mode eq "first"} { diff --git a/tests/acceptance/toolchain.exp b/tests/acceptance/toolchain.exp index f99f562..8a55987 100755 --- a/tests/acceptance/toolchain.exp +++ b/tests/acceptance/toolchain.exp @@ -15,41 +15,53 @@ set env(MOUSE_BOOT_MODE) disk set env(MOUSE_DISK_IMAGE) $disk set env(MOUSE_NETWORK) 0 set env(MOUSE_MEMORY) 1G -set env(MOUSE_KERNEL_ARGS) "console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1" +set env(MOUSE_KERNEL_ARGS) "console=$env(MOUSE_CONSOLE) root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1" spawn -noecho $runner await "mouse:~# " "the root shell" -sendline {cc --version; cc -dumpmachine; make --version; sh -c 'test "$(command -v make)" = /usr/bin/make && test "$(command -v gmake)" = /usr/bin/gmake && test "$(readlink /usr/bin/gmake)" = make && test ! -e /usr/share/mk'; echo MAKE_ID_$status} -await "clang version 22.1.3" "the native Clang version" -await "x86_64-unknown-linux-musl\r" "the MOUSE compiler target" +sendline {cc --version; cc -dumpmachine; make --version; sh -c 'test "$(command -v make)" = /usr/bin/make && test "$(command -v gmake)" = /usr/bin/gmake && test "$(readlink /usr/bin/gmake)" = make'; echo MAKE_ID_$?} +await "clang version 22.1.8" "the native Clang version" +await "$env(MOUSE_RUST_TARGET)\r" "the MOUSE compiler target" await "GNU Make 4.4.1" "the base GNU make version" await "MAKE_ID_0\r" "the base make ownership" await "mouse:~# " "the prompt after compiler identification" -sendline {echo 'int answer(void) { return 42; }' >/tmp/answer.c; echo 'int answer(void);' >/tmp/main.c; echo 'int main(void) { return answer() != 42; }' >>/tmp/main.c; cc -c /tmp/answer.c -o /tmp/answer.o; ar rcs /tmp/libanswer.a /tmp/answer.o; cc /tmp/main.c /tmp/libanswer.a -o /tmp/hello-c; cc -static /tmp/main.c /tmp/libanswer.a -o /tmp/hello-c-static; /tmp/hello-c; /tmp/hello-c-static; echo C_$status} +sendline {sh -c 'make --version | grep -q "GNU Make 4.4.1" && m4 --version | grep -q "m4 (GNU M4) 1.4.21" && perl -e '\''use Config; exit($Config{usedl} eq "define" ? 1 : 0)'\'' && autoconf --version | grep -q "GNU Autoconf.*2.72" && automake-1.16 --version | grep -q "automake (GNU automake) 1.16.3"'; echo AUTOTOOLS_$?} +await "AUTOTOOLS_0\r" "the static World Autoconf toolchain" +await "mouse:~# " "the prompt after the Autoconf toolchain check" + +sendline {mkdir -p /tmp/autoconf; cd /tmp/autoconf; printf 'AC_INIT([mouse-autoconf], [1])\nAC_CONFIG_FILES([Makefile])\nAC_OUTPUT\n' >configure.ac; printf 'all:\n\t@echo configured\n' >Makefile.in; autoconf; ./configure >/dev/null; make | grep -q configured; echo AUTOCONF_BUILD_$?} +await "AUTOCONF_BUILD_0\r" "an Autoconf-generated GNU make build" +await "mouse:~# " "the prompt after the Autoconf build" + +sendline {mkdir -p /tmp/automake; cd /tmp/automake; printf 'AC_INIT([mouse-automake], [1])\nAM_INIT_AUTOMAKE([foreign])\nAC_CONFIG_FILES([Makefile])\nAC_OUTPUT\n' >configure.ac; printf 'bin_SCRIPTS = mouse-automake\n' >Makefile.am; printf '#!/bin/sh\necho generated\n' >mouse-automake; aclocal-1.16; autoconf; automake-1.16 --add-missing --copy; ./configure >/dev/null; make; echo AUTOMAKE_BUILD_$?} +await "AUTOMAKE_BUILD_0\r" "an Automake-generated GNU make build" +await "mouse:~# " "the prompt after the Automake build" + +sendline {echo 'int answer(void) { return 42; }' >/tmp/answer.c; echo 'int answer(void);' >/tmp/main.c; echo 'int main(void) { return answer() != 42; }' >>/tmp/main.c; cc -c /tmp/answer.c -o /tmp/answer.o; ar rcs /tmp/libanswer.a /tmp/answer.o; cc /tmp/main.c /tmp/libanswer.a -o /tmp/hello-c; cc -static /tmp/main.c /tmp/libanswer.a -o /tmp/hello-c-static; /tmp/hello-c; /tmp/hello-c-static; echo C_$?} await "C_0\r" "the native C build" await "mouse:~# " "the prompt after the C build" -sendline {cd /tmp; echo '#include ' >make-main.c; echo 'int main(void) { puts("made"); return 0; }' >>make-main.c; sh -c 'printf "CC=cc\nall: made\nmade: make-main.c\n\t\$(CC) make-main.c -o made\n" >Makefile'; make && ./made && pkgconf --exists libcrypt; echo BUILD_$status} +sendline {cd /tmp; echo '#include ' >make-main.c; echo 'int main(void) { puts("made"); return 0; }' >>make-main.c; sh -c 'printf "CC=cc\nall: made\nmade: make-main.c\n\t\$(CC) make-main.c -o made\n" >Makefile'; make && ./made && pkgconf --exists libcrypt; echo BUILD_$?} await "made\r" "the make-built program output" await "BUILD_0\r" "make and pkgconf" -await "mouse:/tmp# " "the prompt after the make build" +await "mouse:~# " "the prompt after the make build" -sendline {echo '#include ' >/tmp/hello.cpp; echo '#include ' >>/tmp/hello.cpp; echo '#include ' >>/tmp/hello.cpp; echo 'int main() { try { if (std::filesystem::path("/tmp").filename() != "tmp") throw std::runtime_error("filesystem"); } catch (...) { return 1; } return 0; }' >>/tmp/hello.cpp; c++ /tmp/hello.cpp -o /tmp/hello-cxx; c++ -static /tmp/hello.cpp -o /tmp/hello-cxx-static; /tmp/hello-cxx; /tmp/hello-cxx-static; echo CXX_$status} +sendline {echo '#include ' >/tmp/hello.cpp; echo '#include ' >>/tmp/hello.cpp; echo '#include ' >>/tmp/hello.cpp; echo 'int main() { try { if (std::filesystem::path("/tmp").filename() != "tmp") throw std::runtime_error("filesystem"); } catch (...) { return 1; } return 0; }' >>/tmp/hello.cpp; c++ /tmp/hello.cpp -o /tmp/hello-cxx; c++ -static /tmp/hello.cpp -o /tmp/hello-cxx-static; /tmp/hello-cxx; /tmp/hello-cxx-static; echo CXX_$?} await "CXX_0\r" "the native C++ build" -await "mouse:/tmp# " "the prompt after the C++ build" +await "mouse:~# " "the prompt after the C++ build" -sendline {sh -c 'for f in /tmp/hello-c /tmp/hello-cxx; do readelf -l "$f" | grep -q INTERP || { echo "missing INTERP: $f"; exit 1; }; readelf -d "$f" | grep -q NEEDED || { echo "missing NEEDED: $f"; exit 1; }; done; for f in /tmp/hello-c-static /tmp/hello-cxx-static; do if readelf -l "$f" | grep -q INTERP; then echo "unexpected INTERP: $f"; exit 1; fi; if readelf -d "$f" 2>/dev/null | grep -q NEEDED; then echo "unexpected NEEDED: $f"; exit 1; fi; done; exit 0'; echo LINKAGE_$status} +sendline {sh -c 'for f in /tmp/hello-c /tmp/hello-cxx; do readelf -l "$f" | grep -q INTERP || { echo "missing INTERP: $f"; exit 1; }; readelf -d "$f" | grep -q NEEDED || { echo "missing NEEDED: $f"; exit 1; }; done; for f in /tmp/hello-c-static /tmp/hello-cxx-static; do if readelf -l "$f" | grep -q INTERP; then echo "unexpected INTERP: $f"; exit 1; fi; if readelf -d "$f" 2>/dev/null | grep -q NEEDED; then echo "unexpected NEEDED: $f"; exit 1; fi; done; exit 0'; echo LINKAGE_$?} await "LINKAGE_0\r" "dynamic defaults and explicit static builds" -await "mouse:/tmp# " "the prompt after the linkage audit" +await "mouse:~# " "the prompt after the linkage audit" -sendline {echo 'int mouse_shared(void) { return 7; }' >/tmp/shared.c; echo 'int mouse_shared(void); int main(void) { return mouse_shared() != 7; }' >/tmp/shared-user.c; cc -fPIC -shared /tmp/shared.c -o /tmp/libmouse.so; cc /tmp/shared-user.c -L/tmp -Wl,-rpath,/tmp -lmouse -o /tmp/shared-user; /tmp/shared-user; sh -c 'test -f /usr/lib/crtbeginS.o && test -f /usr/lib/crtendS.o && file /tmp/libmouse.so | grep -q "shared object"'; echo SHARED_$status} +sendline {echo 'int mouse_shared(void) { return 7; }' >/tmp/shared.c; echo 'int mouse_shared(void); int main(void) { return mouse_shared() != 7; }' >/tmp/shared-user.c; cc -fPIC -shared /tmp/shared.c -o /tmp/libmouse.so; cc /tmp/shared-user.c -L/tmp -Wl,-rpath,/tmp -lmouse -o /tmp/shared-user; /tmp/shared-user; sh -c 'test -f /usr/lib/crtbeginS.o && test -f /usr/lib/crtendS.o && file /tmp/libmouse.so | grep -q "shared object"'; echo SHARED_$?} await "SHARED_0\r" "building and consuming a shared library" -await "mouse:/tmp# " "the prompt after the shared-library build" +await "mouse:~# " "the prompt after the shared-library build" -sendline {sh -c 'mkdir -p /tmp/tar-source /tmp/tar-output; echo archived >/tmp/tar-source/value; tar -czf /tmp/value.tar.gz -C /tmp/tar-source value; tar -xf /tmp/value.tar.gz -C /tmp/tar-output; test "$(cat /tmp/tar-output/value)" = archived'; echo TAR_$status} +sendline {sh -c 'mkdir -p /tmp/tar-source /tmp/tar-output; echo archived >/tmp/tar-source/value; tar -czf /tmp/value.tar.gz -C /tmp/tar-source value; tar -xf /tmp/value.tar.gz -C /tmp/tar-output; test "$(cat /tmp/tar-output/value)" = archived'; echo TAR_$?} await "TAR_0\r" "the gzip-compressed archive round trip" -await "mouse:/tmp# " "the prompt after the archive round trip" +await "mouse:~# " "the prompt after the archive round trip" poweroff diff --git a/tests/acceptance/world.exp b/tests/acceptance/world.exp index d6889cb..4da3c66 100755 --- a/tests/acceptance/world.exp +++ b/tests/acceptance/world.exp @@ -13,7 +13,7 @@ source [file join [file dirname [info script]] harness.exp] acceptance_log spawn -noecho $runner await_exact "cheesed: base bootstrap complete; cheesed is PID 1" "the World boot" -await_exact "mouse login: root (automatic login)" "the automatic test login" +await_exact "mousehole login: root (automatic login)" "the automatic test login" await_prompt sendline {sh -c 'man -w ls | grep -q /usr/share/man && man ls | grep -q "list directory contents" && apropos "list directory contents" | grep -q "ls(1)"'; echo MANUAL_$?} @@ -24,7 +24,7 @@ sendline {sh -c 'printf mouse-world >/tmp/plain && gzip -c /tmp/plain | gzip -dc await_exact "ARCHIVE_0\r" "the World compression, archive, and file-identification tools" await_exact "mouse:~# " "the prompt after the archive check" -sendline {sh -c 'openssl version | grep -q OpenSSL && free >/dev/null && uptime >/dev/null && vmstat 1 2 >/dev/null && watch --version >/dev/null && sysctl kernel.hostname | grep -q mouse && lsblk >/dev/null && findmnt / >/dev/null && flock /tmp/world.lock true'; echo RUNTIME_$?} +sendline {sh -c 'openssl version | grep -q OpenSSL && free >/dev/null && uptime >/dev/null && vmstat 1 2 >/dev/null && watch --version >/dev/null && test "$(sysctl -n kernel.hostname)" = mousehole && lsblk >/dev/null && findmnt / >/dev/null && flock /tmp/world.lock true'; echo RUNTIME_$?} await_exact "RUNTIME_0\r" "the crypto, process, sysctl, and storage administration tools" await_exact "mouse:~# " "the prompt after the runtime administration check" @@ -36,10 +36,14 @@ sendline {sh -c 'ip link add mouse-dummy type dummy && ip link add mouse-bridge await_exact "VIRTUAL_LINKS_0\r" "the dummy, bridge, and VLAN kernel interfaces" await_exact "mouse:~# " "the prompt after the virtual-link check" -sendline {sh -c 'service loopback status >/dev/null && service mdevd status >/dev/null && service syslogd status >/dev/null && service cron status >/dev/null && service ntpd status >/dev/null'; echo SERVICES_$?} +sendline {sh -c 'service loopback status >/dev/null && service gardendevd status >/dev/null && gardendevctl settle -t 1 && test -d /run/udev/data && service syslogd status >/dev/null && service cron status >/dev/null && service ntpd status >/dev/null'; echo SERVICES_$?} await_exact "SERVICES_0\r" "the device, logging, job, and time services" await_exact "mouse:~# " "the prompt after the World service check" +sendline {sh -c 'printf "mouse\ncheddar\n" | /usr/libexec/mouse-auth && ! printf "mouse\nwrong-password\n" | /usr/libexec/mouse-auth && ! printf "root\ncheddar\n" | /usr/libexec/mouse-auth && ! printf "missing\ncheddar\n" | /usr/libexec/mouse-auth'; echo AUTH_$?} +await_exact "AUTH_0\r" "the PAM-less authentication helper" +await_exact "mouse:~# " "the prompt after the authentication check" + sendline {sh -c 'sleep 8 && service ntpd status >/dev/null && test -S /run/ntpd.sock && ntpctl -s status >/dev/null'; echo NTPD_$?} await_exact "NTPD_0\r" "the supervised time service after the restart window" await_exact "mouse:~# " "the prompt after the time-service stability check" diff --git a/tests/acceptance/world.sh b/tests/acceptance/world.sh index 237bdcf..2526706 100755 --- a/tests/acceptance/world.sh +++ b/tests/acceptance/world.sh @@ -9,6 +9,6 @@ acceptance_copy_disk world MOUSE_BOOT_MODE=disk \ MOUSE_DISK_IMAGE="$test_disk" \ -MOUSE_KERNEL_ARGS="console=ttyS0 root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1" \ +MOUSE_KERNEL_ARGS="console=$MOUSE_CONSOLE root=PARTUUID=4d4f5553-4500-4000-8000-000000000002 rootfstype=btrfs rw rootwait init=/sbin/cheesed mouse.autologin=1 panic=-1" \ MOUSE_MEMORY="${MOUSE_MEMORY:-1G}" \ exec expect "$acceptance_dir/world.exp" "$runner" diff --git a/tests/fixtures/pkgsrc/distfiles/mouse-hello-1.0.c b/tests/fixtures/pkgsrc/distfiles/mouse-hello-1.0.c deleted file mode 100644 index ea5926a..0000000 --- a/tests/fixtures/pkgsrc/distfiles/mouse-hello-1.0.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int -main(void) -{ - puts("Hello from pkgsrc on MOUSE"); - return 0; -} diff --git a/tests/fixtures/pkgsrc/local/mouse-hello/DESCR b/tests/fixtures/pkgsrc/local/mouse-hello/DESCR deleted file mode 100644 index e34ac69..0000000 --- a/tests/fixtures/pkgsrc/local/mouse-hello/DESCR +++ /dev/null @@ -1,2 +0,0 @@ -Small command and rc.d service used to exercise pkgsrc installation and -cheesed supervision on MOUSE. diff --git a/tests/fixtures/pkgsrc/local/mouse-hello/Makefile b/tests/fixtures/pkgsrc/local/mouse-hello/Makefile deleted file mode 100644 index a54e445..0000000 --- a/tests/fixtures/pkgsrc/local/mouse-hello/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -DISTNAME= mouse-hello-1.0 -CATEGORIES= local -MASTER_SITES= http://10.0.2.2:18080/ -DISTFILES= ${DISTNAME}.c -EXTRACT_ONLY= - -MAINTAINER= mouse@localhost -COMMENT= MOUSE pkgsrc acceptance command -LICENSE= 2-clause-bsd - -NO_CONFIGURE= yes -INSTALLATION_DIRS= bin libexec - -RCD_SCRIPTS= mouse_hello - -do-build: - ${CC} ${CFLAGS} ${LDFLAGS} ${DISTDIR}/${DISTNAME}.c \ - -o ${WRKSRC}/mouse-hello - -do-install: - ${INSTALL_PROGRAM} ${WRKSRC}/mouse-hello \ - ${DESTDIR}${PREFIX}/bin/mouse-hello - ${INSTALL_SCRIPT} ${FILESDIR}/mouse-hello-service \ - ${DESTDIR}${PREFIX}/libexec/mouse-hello-service - -.include "../../mk/bsd.pkg.mk" diff --git a/tests/fixtures/pkgsrc/local/mouse-hello/PLIST b/tests/fixtures/pkgsrc/local/mouse-hello/PLIST deleted file mode 100644 index bc25a82..0000000 --- a/tests/fixtures/pkgsrc/local/mouse-hello/PLIST +++ /dev/null @@ -1,3 +0,0 @@ -@comment $NetBSD$ -bin/mouse-hello -libexec/mouse-hello-service diff --git a/tests/fixtures/pkgsrc/local/mouse-hello/distinfo b/tests/fixtures/pkgsrc/local/mouse-hello/distinfo deleted file mode 100644 index 7ec8316..0000000 --- a/tests/fixtures/pkgsrc/local/mouse-hello/distinfo +++ /dev/null @@ -1,5 +0,0 @@ -$NetBSD$ - -BLAKE2s (mouse-hello-1.0.c) = 0b050fc1474665f3aa59da2afe70b7bce1d04acfa8de8f7a62fe5b6b40bc0503 -SHA512 (mouse-hello-1.0.c) = ab0bd1c0c3a4c622029ef9495c58df31b462067b9ff997925fff7047df9a0cdbf1462817e5f9195f73c7994b47d2ddc2c4af06aea78c9f31cb5813d770d2eb50 -Size (mouse-hello-1.0.c) = 87 bytes diff --git a/tests/fixtures/pkgsrc/local/mouse-hello/files/mouse-hello-service b/tests/fixtures/pkgsrc/local/mouse-hello/files/mouse-hello-service deleted file mode 100644 index d33d79d..0000000 --- a/tests/fixtures/pkgsrc/local/mouse-hello/files/mouse-hello-service +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -set -eu - -ready=/run/mouse-hello-service.ready - -cleanup() { - rm -f "$ready" - exit 0 -} -trap cleanup INT TERM - -: >"$ready" -while :; do - sleep 3600 & - wait "$!" -done diff --git a/tests/fixtures/pkgsrc/local/mouse-hello/files/mouse_hello.sh b/tests/fixtures/pkgsrc/local/mouse-hello/files/mouse_hello.sh deleted file mode 100644 index bf9d640..0000000 --- a/tests/fixtures/pkgsrc/local/mouse-hello/files/mouse_hello.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!@RCD_SCRIPTS_SHELL@ -# PROVIDE: mouse_hello -# REQUIRE: NETWORKING - -. /etc/rc.subr - -name=mouse_hello -command=@PREFIX@/libexec/mouse-hello-service -command_args="&" - -run_rc_command "$1"