Compare commits
68 Commits
bookworm
...
trixie-dev
| Author | SHA1 | Date | |
|---|---|---|---|
| cce226198c | |||
| 3769527869 | |||
| 3605a5d6d9 | |||
| e192680586 | |||
| e623db2e4b | |||
| 235a12a5ed | |||
| 53ffdefe2e | |||
| 49d398fd6a | |||
| 8a573b2607 | |||
| b804679127 | |||
| 4e163d64be | |||
| 01f7143e9d | |||
| c2676fb3a2 | |||
| 9b556d2151 | |||
| d4ad00d796 | |||
| 135c13cada | |||
| 4017f4c727 | |||
| 7ac792cb05 | |||
| 2f51d3d82a | |||
| a7e6e0178d | |||
| 370c0f435a | |||
| 74e2382e56 | |||
| 2d698e6643 | |||
| 247d318f0f | |||
| e726efa2a1 | |||
| 5da74d42ea | |||
| ca0b8ab84f | |||
| 011b11a163 | |||
| 99e6532afe | |||
| dc8792f39f | |||
| 50d7468379 | |||
| 5ddf03bfbb | |||
| d6c501b94c | |||
| 9e64b989da | |||
| 96294e9f10 | |||
| d0139cfb68 | |||
| ae50844db4 | |||
| 2b923dedf4 | |||
| 67d766af84 | |||
| 0666b4d8ce | |||
| eeab7c0066 | |||
| 6ff686f46a | |||
| 4fac4173d8 | |||
| 3a2392dbe0 | |||
| dfbeff3a8f | |||
| ba03830786 | |||
| 5dd1df81e2 | |||
| 9171b33eb2 | |||
| d2d9121392 | |||
| b93580ba3b | |||
| aa82b77d91 | |||
| ee1ff065d7 | |||
| cfe6f5a670 | |||
| 239f5e37df | |||
| aaf0466521 | |||
| 34d6df8eb9 | |||
| 194d65db6b | |||
| 810b9743f6 | |||
| 692d3fbad9 | |||
| 618e154632 | |||
| 7f75c718b4 | |||
| 2db3002313 | |||
| 4916473dc9 | |||
| 1f6e023eab | |||
| 7d499ebb72 | |||
| 86538fe574 | |||
| 104e7bd4cc | |||
|
|
07b8db1a74 |
@@ -6,7 +6,7 @@ ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get -y update && \
|
||||
apt-get -y install --no-install-recommends \
|
||||
git vim parted \
|
||||
quilt coreutils qemu-user-static debootstrap zerofree zip dosfstools \
|
||||
quilt coreutils qemu-user-static debootstrap zerofree zip dosfstools e2fsprogs \
|
||||
libarchive-tools libcap2-bin rsync grep udev xz-utils curl xxd file kmod bc \
|
||||
binfmt-support ca-certificates fdisk gpg pigz arch-test \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
1
LICENSE
@@ -1,3 +1,4 @@
|
||||
Copyright (c) 2026 Seth Olivarez
|
||||
Copyright (c) 2015 Raspberry Pi (Trading) Ltd.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
26
README.md
@@ -1,37 +1,33 @@
|
||||
# ChillcraftOS Build System
|
||||
# VesperOS Build System
|
||||
|
||||
ChillcraftOS is a custom Raspberry Pi OS built using a system based on `pi-gen`. This build system is specifically designed to create **ChillcraftOS** images, not general Raspberry Pi OS images.
|
||||
|
||||
**Important Notes:**
|
||||
- The 32-bit versions of ChillcraftOS are based on Raspbian.
|
||||
- The 64-bit versions of ChillcraftOS are based on Debian.
|
||||
VesperOS is a custom Debian-based OS built using a system based on `pi-gen`.
|
||||
|
||||
## Dependencies
|
||||
|
||||
The ChillcraftOS Build System relies on `pi-gen` and is compatible with Debian-based operating systems released after 2017. We recommend using the latest OS versions for better security.
|
||||
The VesperOS Build System relies on `pi-gen` and is compatible with Debian-based operating systems released after 2017. We recommend using the latest OS versions for better security.
|
||||
|
||||
For other Linux distributions, you can use the Docker-based build method provided below.
|
||||
|
||||
To install the required dependencies for building ChillcraftOS, run the following command:
|
||||
To install the required dependencies for building VesperOS, run the following command:
|
||||
|
||||
```bash
|
||||
apt-get install coreutils quilt parted qemu-user-static debootstrap zerofree zip \
|
||||
dosfstools libarchive-tools libcap2-bin grep rsync xz-utils file git curl bc \
|
||||
gpg pigz xxd arch-test
|
||||
apt install coreutils quilt parted qemu-user-static debootstrap zerofree zip \
|
||||
dosfstools e2fsprogs libarchive-tools libcap2-bin grep rsync xz-utils file git curl bc \
|
||||
gpg pigz xxd arch-test bmap-tools kmod squashfs-tools xorriso mtools
|
||||
```
|
||||
|
||||
The `depends` file in the repository lists all the necessary tools, formatted as `<tool>[:<debian-package>]`.
|
||||
|
||||
## Getting Started with Building ChillcraftOS
|
||||
## Getting Started with Building VesperOS
|
||||
|
||||
To start building ChillcraftOS, clone the ChillcraftOS Build System repository:
|
||||
To start building VesperOS, clone the os-builder repository:
|
||||
|
||||
```bash
|
||||
git clone https://git.oxmc.me/Chillcraft/ChillcraftOS.git
|
||||
git clone https://git.oxmc.me/VesperOS/os-builder.git
|
||||
```
|
||||
|
||||
For a shallow clone containing only the latest revision, you can add `--depth 1`. **However, avoid using this on your development machine**.
|
||||
|
||||
Make sure the repository is cloned to a directory **without spaces**, as spaces in the base path may cause `pi-gen` to fail.
|
||||
|
||||
Once cloned, you're ready to configure and start building ChillcraftOS.
|
||||
Once cloned, you're ready to configure and start building VesperOS.
|
||||
@@ -85,10 +85,10 @@ BUILD_OPTS="$(echo "${BUILD_OPTS:-}" | sed -E 's@\-c\s?([^ ]+)@-c /config@')"
|
||||
# Check the arch of the machine we're running on. If it's 64-bit, use a 32-bit base image instead
|
||||
case "$(uname -m)" in
|
||||
x86_64|aarch64)
|
||||
BASE_IMAGE=i386/debian:bookworm
|
||||
BASE_IMAGE=i386/debian:trixie
|
||||
;;
|
||||
*)
|
||||
BASE_IMAGE=debian:bookworm
|
||||
BASE_IMAGE=debian:trixie
|
||||
;;
|
||||
esac
|
||||
${DOCKER} build --build-arg BASE_IMAGE=${BASE_IMAGE} -t pi-gen "${DIR}"
|
||||
@@ -151,7 +151,7 @@ time ${DOCKER} run \
|
||||
pi-gen \
|
||||
bash -e -o pipefail -c "
|
||||
dpkg-reconfigure qemu-user-static &&
|
||||
# binfmt_misc is sometimes not mounted with debian bookworm image
|
||||
# binfmt_misc is sometimes not mounted with debian trixie image
|
||||
(mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc || true) &&
|
||||
cd /pi-gen; ./build.sh ${BUILD_OPTS} &&
|
||||
rsync -av work/*/build.log deploy/
|
||||
|
||||
103
build.sh
@@ -5,7 +5,7 @@ run_sub_stage() {
|
||||
log "Begin ${SUB_STAGE_DIR}"
|
||||
pushd "${SUB_STAGE_DIR}" >/dev/null
|
||||
for i in {00..99}; do
|
||||
for DEBCONF_FILE in "${i}-debconf-${ARCH}" "${i}-debconf-arm-only" "${i}-debconf"; do
|
||||
for DEBCONF_FILE in "${i}-debconf-${ARCH}" "${i}-debconf-${PLATFORM}-only" "${i}-debconf-arm-only" "${i}-debconf"; do
|
||||
if [ -f "${SUB_STAGE_DIR}/${DEBCONF_FILE}" ]; then
|
||||
# Skip arm-only if not arm
|
||||
if [[ "${DEBCONF_FILE}" == *"-debconf-arm-only" ]] && [[ "${ARCH}" != "armhf" && "${ARCH}" != "arm64" ]]; then
|
||||
@@ -23,7 +23,7 @@ EOF
|
||||
log "End ${SUB_STAGE_DIR}/${DEBCONF_FILE}"
|
||||
fi
|
||||
done
|
||||
for PACKAGE_LIST in "${i}-packages-nr-${ARCH}" "${i}-packages-nr-arm-only" "${i}-packages-nr"; do
|
||||
for PACKAGE_LIST in "${i}-packages-nr-${ARCH}" "${i}-packages-nr-${PLATFORM}-only" "${i}-packages-nr-arm-only" "${i}-packages-nr"; do
|
||||
if [ -f "${SUB_STAGE_DIR}/${PACKAGE_LIST}" ]; then
|
||||
# Skip arm-only packages if not arm architecture
|
||||
if [[ "${PACKAGE_LIST}" == *"-nr-arm-only" ]] && [[ "${ARCH}" != "armhf" && "${ARCH}" != "arm64" ]]; then
|
||||
@@ -43,7 +43,7 @@ EOF
|
||||
log "End ${SUB_STAGE_DIR}/${PACKAGE_LIST}"
|
||||
fi
|
||||
done
|
||||
for PACKAGE_LIST in "${i}-packages-${ARCH}" "${i}-packages-arm-only" "${i}-packages"; do
|
||||
for PACKAGE_LIST in "${i}-packages-${ARCH}" "${i}-packages-${PLATFORM}-only" "${i}-packages-arm-only" "${i}-packages"; do
|
||||
if [ -f "${SUB_STAGE_DIR}/${PACKAGE_LIST}" ]; then
|
||||
# Skip arm-only packages if not arm architecture
|
||||
if [[ "${PACKAGE_LIST}" == *"-packages-arm-only" ]] && [[ "${ARCH}" != "armhf" && "${ARCH}" != "arm64" ]]; then
|
||||
@@ -63,7 +63,7 @@ EOF
|
||||
log "End ${SUB_STAGE_DIR}/${PACKAGE_LIST}"
|
||||
fi
|
||||
done
|
||||
for PATCH_DIR in "${i}-patches-${ARCH}" "${i}-patches-arm-only" "${i}-patches"; do
|
||||
for PATCH_DIR in "${i}-patches-${ARCH}" "${i}-patches-${PLATFORM}-only" "${i}-patches-arm-only" "${i}-patches"; do
|
||||
if [ -d "${SUB_STAGE_DIR}/${PATCH_DIR}" ]; then
|
||||
# Check arm-only patches should only apply for armhf/arm64
|
||||
if [[ "${PATCH_DIR}" == *"-patches-arm-only" ]] && [[ "${ARCH}" != "armhf" && "${ARCH}" != "arm64" ]]; then
|
||||
@@ -101,7 +101,7 @@ EOF
|
||||
log "End ${SUB_STAGE_DIR}/${PATCH_DIR}"
|
||||
fi
|
||||
done
|
||||
for RUN_SCRIPT in "${i}-run-${ARCH}.sh" "${i}-run-arm-only.sh" "${i}-run.sh"; do
|
||||
for RUN_SCRIPT in "${i}-run-${ARCH}.sh" "${i}-run-${PLATFORM}-only.sh" "${i}-run-arm-only.sh" "${i}-run.sh"; do
|
||||
if [ -x "${SUB_STAGE_DIR}/${RUN_SCRIPT}" ]; then
|
||||
# Skip arm-only if not arm
|
||||
if [[ "${RUN_SCRIPT}" == *"-arm-only.sh" ]] && [[ "${ARCH}" != "armhf" && "${ARCH}" != "arm64" ]]; then
|
||||
@@ -111,9 +111,11 @@ EOF
|
||||
log "Begin ${SUB_STAGE_DIR}/${RUN_SCRIPT}"
|
||||
"./${RUN_SCRIPT}"
|
||||
log "End ${SUB_STAGE_DIR}/${RUN_SCRIPT}"
|
||||
elif [ "${RUN_SCRIPT}" = "${i}-run.sh" ] && [ -f "${SUB_STAGE_DIR}/${i}-run.sh" ]; then
|
||||
log "Skip ${SUB_STAGE_DIR}/${i}-run.sh (not executable)"
|
||||
fi
|
||||
done
|
||||
for CHROOT_SCRIPT in "${i}-run-chroot-${ARCH}.sh" "${i}-run-chroot-arm-only.sh" "${i}-run-chroot.sh"; do
|
||||
for CHROOT_SCRIPT in "${i}-run-chroot-${ARCH}.sh" "${i}-run-chroot-${PLATFORM}-only.sh" "${i}-run-chroot-arm-only.sh" "${i}-run-chroot.sh"; do
|
||||
if [ -f "${SUB_STAGE_DIR}/${CHROOT_SCRIPT}" ]; then
|
||||
# Skip arm-only if not arm
|
||||
if [[ "${CHROOT_SCRIPT}" == *"-arm-only.sh" ]] && [[ "${ARCH}" != "armhf" && "${ARCH}" != "arm64" ]]; then
|
||||
@@ -141,11 +143,6 @@ run_stage() {
|
||||
|
||||
unmount "${WORK_DIR}/${STAGE}"
|
||||
|
||||
if [ ! -f SKIP_IMAGES ]; then
|
||||
if [ -f "${STAGE_DIR}/EXPORT_IMAGE" ]; then
|
||||
EXPORT_DIRS="${EXPORT_DIRS} ${STAGE_DIR}"
|
||||
fi
|
||||
fi
|
||||
if [ ! -f SKIP ]; then
|
||||
if [ "${CLEAN}" = "1" ]; then
|
||||
if [ -d "${ROOTFS_DIR}" ]; then
|
||||
@@ -159,7 +156,7 @@ run_stage() {
|
||||
fi
|
||||
for SUB_STAGE_DIR in "${STAGE_DIR}"/*; do
|
||||
if [ -d "${SUB_STAGE_DIR}" ]; then
|
||||
if [ ! -f "${SUB_STAGE_DIR}/SKIP" ] && [ ! -f "${SUB_STAGE_DIR}/SKIP_${ARCH}" ]; then
|
||||
if [ ! -f "${SUB_STAGE_DIR}/SKIP" ] && [ ! -f "${SUB_STAGE_DIR}/SKIP_${ARCH}" ] && { [ -z "${PLATFORM}" ] || [ ! -f "${SUB_STAGE_DIR}/SKIP_${PLATFORM}" ]; }; then
|
||||
run_sub_stage
|
||||
fi
|
||||
fi
|
||||
@@ -182,7 +179,7 @@ term() {
|
||||
log "Build finished"
|
||||
fi
|
||||
unmount "${STAGE_WORK_DIR}"
|
||||
if [ "$STAGE" = "export-image" ]; then
|
||||
if [ "$STAGE" = "exports/img" ]; then
|
||||
for img in "${STAGE_WORK_DIR}/"*.img; do
|
||||
unmount_image "$img"
|
||||
done
|
||||
@@ -226,8 +223,9 @@ export PI_GEN_REPO=${PI_GEN_REPO:-https://github.com/RPi-Distro/pi-gen}
|
||||
export PI_GEN_RELEASE=${PI_GEN_RELEASE:-Raspberry Pi reference}
|
||||
|
||||
export ARCH="${ARCH:-arm64}"
|
||||
export RELEASE=${RELEASE:-bookworm}
|
||||
export IMG_NAME="${IMG_NAME:-chillcraftos-$RELEASE-$ARCH}"
|
||||
export PLATFORM="${PLATFORM:-}"
|
||||
export RELEASE=${RELEASE:-trixie}
|
||||
export IMG_NAME="${IMG_NAME:-vesperos-$RELEASE-$ARCH}"
|
||||
|
||||
export USE_QEMU="${USE_QEMU:-0}"
|
||||
export IMG_DATE="${IMG_DATE:-"$(date +%Y-%m-%d)"}"
|
||||
@@ -242,9 +240,7 @@ export DEPLOY_COMPRESSION=${DEPLOY_COMPRESSION:-xz}
|
||||
export COMPRESSION_LEVEL=${COMPRESSION_LEVEL:-6}
|
||||
export LOG_FILE="${WORK_DIR}/build.log"
|
||||
|
||||
export TARGET_HOSTNAME=${TARGET_HOSTNAME:-chillcraftos}
|
||||
export FIRST_USER_NAME=${FIRST_USER_NAME:-system}
|
||||
export FIRST_USER_ISSYSTEM=${FIRST_USER_ISSYSTEM:-true}
|
||||
export TARGET_HOSTNAME=${TARGET_HOSTNAME:-vesperos}
|
||||
export WPA_COUNTRY
|
||||
export ENABLE_SSH="${ENABLE_SSH:-0}"
|
||||
export PUBKEY_ONLY_SSH="${PUBKEY_ONLY_SSH:-0}"
|
||||
@@ -254,12 +250,10 @@ export LOCALE_DEFAULT="${LOCALE_DEFAULT:-en_US.UTF-8}"
|
||||
export KEYBOARD_KEYMAP="${KEYBOARD_KEYMAP:-us}"
|
||||
export KEYBOARD_LAYOUT="${KEYBOARD_LAYOUT:-English (US)}"
|
||||
|
||||
export TIMEZONE_DEFAULT="${TIMEZONE_DEFAULT:-Americas/Los_Angeles}"
|
||||
export TIMEZONE_DEFAULT="${TIMEZONE_DEFAULT:-America/Los_Angeles}"
|
||||
|
||||
export GIT_HASH=${GIT_HASH:-"$(git rev-parse HEAD)"}
|
||||
|
||||
export PUBKEY_SSH_FIRST_USER
|
||||
|
||||
export CLEAN
|
||||
export APT_PROXY
|
||||
export TEMP_REPO
|
||||
@@ -272,8 +266,6 @@ export PREV_STAGE_DIR
|
||||
export ROOTFS_DIR
|
||||
export PREV_ROOTFS_DIR
|
||||
export IMG_SUFFIX
|
||||
export NOOBS_NAME
|
||||
export NOOBS_DESCRIPTION
|
||||
export EXPORT_DIR
|
||||
export EXPORT_ROOTFS_DIR
|
||||
|
||||
@@ -282,6 +274,10 @@ export QUILT_NO_DIFF_INDEX=1
|
||||
export QUILT_NO_DIFF_TIMESTAMPS=1
|
||||
export QUILT_REFRESH_ARGS="-p ab"
|
||||
|
||||
export ENABLE_CLOUD_INIT=${ENABLE_CLOUD_INIT:-1}
|
||||
export LIVEBOOT=${LIVEBOOT:-0}
|
||||
export EXPORTS="${EXPORTS:-}"
|
||||
|
||||
# shellcheck source=scripts/common
|
||||
source "${SCRIPT_DIR}/common"
|
||||
# shellcheck source=scripts/dependencies_check
|
||||
@@ -317,12 +313,6 @@ if ! arch-test -n "$ARCH"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
#check username is valid
|
||||
if [[ ! "$FIRST_USER_NAME" =~ ^[a-z][-a-z0-9_]*$ ]]; then
|
||||
echo "Invalid FIRST_USER_NAME: $FIRST_USER_NAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -n "${APT_PROXY}" ]] && ! curl --silent "${APT_PROXY}" >/dev/null; then
|
||||
echo "Could not reach APT_PROXY server: ${APT_PROXY}"
|
||||
exit 1
|
||||
@@ -333,53 +323,44 @@ if [[ -n "${WPA_PASSWORD}" && ${#WPA_PASSWORD} -lt 8 || ${#WPA_PASSWORD} -gt 63
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${PUBKEY_ONLY_SSH}" = "1" && -z "${PUBKEY_SSH_FIRST_USER}" ]]; then
|
||||
echo "Must set 'PUBKEY_SSH_FIRST_USER' to a valid SSH public key if using PUBKEY_ONLY_SSH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Begin ${BASE_DIR}"
|
||||
|
||||
STAGE_LIST=${STAGE_LIST:-${BASE_DIR}/stage*}
|
||||
export STAGE_LIST
|
||||
|
||||
EXPORT_CONFIG_DIR=$(realpath "${EXPORT_CONFIG_DIR:-"${BASE_DIR}/export-image"}")
|
||||
if [ ! -d "${EXPORT_CONFIG_DIR}" ]; then
|
||||
echo "EXPORT_CONFIG_DIR invalid: ${EXPORT_CONFIG_DIR} does not exist"
|
||||
exit 1
|
||||
fi
|
||||
export EXPORT_CONFIG_DIR
|
||||
|
||||
for STAGE_DIR in $STAGE_LIST; do
|
||||
STAGE_DIR=$(realpath "${STAGE_DIR}")
|
||||
run_stage
|
||||
done
|
||||
|
||||
CLEAN=1
|
||||
for EXPORT_DIR in ${EXPORT_DIRS}; do
|
||||
STAGE_DIR=${EXPORT_CONFIG_DIR}
|
||||
# shellcheck source=/dev/null
|
||||
source "${EXPORT_DIR}/EXPORT_IMAGE"
|
||||
EXPORT_ROOTFS_DIR=${WORK_DIR}/$(basename "${EXPORT_DIR}")/rootfs
|
||||
if [ -e "${EXPORT_DIR}/EXPORT_ISO" ]; then
|
||||
# shellcheck source=/dev/null
|
||||
source "${EXPORT_DIR}/EXPORT_ISO"
|
||||
STAGE_DIR="${BASE_DIR}/export-iso"
|
||||
|
||||
# Exports declared in config: EXPORTS="stage3:squashfs stage2:img ..."
|
||||
for export_spec in ${EXPORTS}; do
|
||||
stage_name="${export_spec%%:*}"
|
||||
export_type="${export_spec##*:}"
|
||||
EXPORT_DIR="${BASE_DIR}/${stage_name}"
|
||||
EXPORT_ROOTFS_DIR="${WORK_DIR}/${stage_name}/rootfs"
|
||||
case "${export_type}" in
|
||||
img)
|
||||
STAGE_DIR="${BASE_DIR}/exports/img"
|
||||
run_stage
|
||||
elif [ -e "${EXPORT_DIR}/EXPORT_IMAGE" ]; then
|
||||
# shellcheck source=/dev/null
|
||||
source "${EXPORT_DIR}/EXPORT_IMAGE"
|
||||
STAGE_DIR="${BASE_DIR}/export-image"
|
||||
;;
|
||||
squashfs)
|
||||
STAGE_DIR="${BASE_DIR}/exports/squashfs"
|
||||
run_stage
|
||||
fi
|
||||
if [ "${USE_QEMU}" != "1" ]; then
|
||||
if [ -e "${EXPORT_DIR}/EXPORT_NOOBS" ]; then
|
||||
# shellcheck source=/dev/null
|
||||
source "${EXPORT_DIR}/EXPORT_NOOBS"
|
||||
STAGE_DIR="${BASE_DIR}/export-noobs"
|
||||
;;
|
||||
noobs)
|
||||
if [ "${USE_QEMU}" != "1" ]; then
|
||||
STAGE_DIR="${BASE_DIR}/exports/noobs"
|
||||
run_stage
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log "Unknown export type '${export_type}' in EXPORTS spec '${export_spec}'"
|
||||
false
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -x "${BASE_DIR}/postrun.sh" ]; then
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
ARCH=amd64
|
||||
@@ -1 +0,0 @@
|
||||
ARCH=arm64
|
||||
21
configs/amd64
Normal file
@@ -0,0 +1,21 @@
|
||||
# This builds VesperOS for amd64
|
||||
ARCH=amd64
|
||||
|
||||
# Suffix to append to the image name
|
||||
#IMG_SUFFIX="-rainier"
|
||||
|
||||
# Exports to produce
|
||||
EXPORTS="stage3:squashfs"
|
||||
|
||||
# Weather to export the image with compression (zip, gz, xz) or not (none)
|
||||
DEPLOY_COMPRESSION="none"
|
||||
|
||||
# Set LIVEBOOT=1 to also produce a livefs.squashfs with Calamares installed
|
||||
# for use with gen-installmedia. Outputs deploy/livefs.{squashfs,vmlinuz,initrd.img}
|
||||
# alongside the clean deploy/rootfs.squashfs.
|
||||
LIVEBOOT=1
|
||||
|
||||
# Live boot options
|
||||
LIVE_USERNAME="vesper"
|
||||
LIVE_USER_FULLNAME="VesperOS Live User"
|
||||
LIVE_USER_PASSWORD="vesper"
|
||||
11
configs/arm64
Normal file
@@ -0,0 +1,11 @@
|
||||
# This builds VesperOS for arm64
|
||||
ARCH=arm64
|
||||
|
||||
# Suffix to append to the image name
|
||||
#IMG_SUFFIX="-rainier"
|
||||
|
||||
# Exports to produce
|
||||
EXPORTS="stage3:squashfs"
|
||||
|
||||
# Weather to export the image with compression (zip, gz, xz) or not (none)
|
||||
DEPLOY_COMPRESSION="none"
|
||||
17
configs/rpi4
Normal file
@@ -0,0 +1,17 @@
|
||||
# Raspberry Pi OS only targets arm64 since the rpi4.
|
||||
# So VesperOS will also only target arm64 for the rpi4 and up.
|
||||
|
||||
# This builds VesperOS for arm64
|
||||
ARCH=arm64
|
||||
|
||||
# This tells the build system we are targetting a raspberry pi
|
||||
PLATFORM=rpi
|
||||
|
||||
# Suffix to append to the image name
|
||||
IMG_SUFFIX="-rainier-rpi"
|
||||
|
||||
# Exports to produce
|
||||
EXPORTS="stage3:squashfs"
|
||||
|
||||
# Weather to export the image with compression (zip, gz, xz) or not (none)
|
||||
DEPLOY_COMPRESSION="none"
|
||||
4
depends
@@ -6,6 +6,7 @@ debootstrap
|
||||
zerofree
|
||||
zip
|
||||
mkdosfs:dosfstools
|
||||
mke2fs:e2fsprogs
|
||||
capsh:libcap2-bin
|
||||
bsdtar:libarchive-tools
|
||||
grep
|
||||
@@ -20,3 +21,6 @@ bc
|
||||
gpg
|
||||
pigz
|
||||
arch-test
|
||||
mksquashfs:squashfs-tools
|
||||
xorriso
|
||||
grub-mkrescue:grub-common
|
||||
289
docs/config.md
@@ -1,172 +1,133 @@
|
||||
## Config
|
||||
# Config
|
||||
|
||||
Upon execution, `build.sh` will source the file `config` in the current
|
||||
working directory. This bash shell fragment is intended to set needed
|
||||
environment variables.
|
||||
|
||||
The following environment variables are supported:
|
||||
|
||||
* `IMG_NAME` (Default: `raspios-$RELEASE-$ARCH`, for example: `raspios-bookworm-armhf`)
|
||||
|
||||
The name of the image to build with the current stage directories. Use this
|
||||
variable to set the root name of your OS, eg `IMG_NAME=Frobulator`.
|
||||
Export files in stages may add suffixes to `IMG_NAME`.
|
||||
|
||||
* `PI_GEN_RELEASE` (Default: `Raspberry Pi reference`)
|
||||
|
||||
The release name to use in `/etc/issue.txt`. The default should only be used
|
||||
for official Raspberry Pi builds.
|
||||
|
||||
* `RELEASE` (Default: `bookworm`)
|
||||
|
||||
The release version to build images against. Valid values are any supported
|
||||
Debian release. However, since different releases will have different sets of
|
||||
packages available, you'll need to either modify your stages accordingly, or
|
||||
checkout the appropriate branch. For example, if you'd like to build a
|
||||
`bullseye` image, you should do so from the `bullseye` branch.
|
||||
|
||||
* `APT_PROXY` (Default: unset)
|
||||
|
||||
If you require the use of an apt proxy, set it here. This proxy setting
|
||||
will not be included in the image, making it safe to use an `apt-cacher` or
|
||||
similar package for development.
|
||||
|
||||
* `TEMP_REPO` (Default: unset)
|
||||
|
||||
An additional temporary apt repo to be used during the build process. This
|
||||
could be useful if you require pre-release software to be included in the
|
||||
image. The variable should contain sources in [one-line-style format](https://manpages.debian.org/stable/apt/sources.list.5.en.html#ONE-LINE-STYLE_FORMAT).
|
||||
"RELEASE" will be replaced with the RELEASE variable.
|
||||
|
||||
* `BASE_DIR` (Default: location of `build.sh`)
|
||||
|
||||
**CAUTION**: Currently, changing this value will probably break build.sh
|
||||
|
||||
Top-level directory for `pi-gen`. Contains stage directories, build
|
||||
scripts, and by default both work and deployment directories.
|
||||
|
||||
* `WORK_DIR` (Default: `$BASE_DIR/work`)
|
||||
|
||||
Directory in which `pi-gen` builds the target system. This value can be
|
||||
changed if you have a suitably large, fast storage location for stages to
|
||||
be built and cached. Note, `WORK_DIR` stores a complete copy of the target
|
||||
system for each build stage, amounting to tens of gigabytes in the case of
|
||||
Raspbian.
|
||||
|
||||
**CAUTION**: If your working directory is on an NTFS partition you probably won't be able to build: make sure this is a proper Linux filesystem.
|
||||
|
||||
* `DEPLOY_DIR` (Default: `$BASE_DIR/deploy`)
|
||||
|
||||
Output directory for target system images and NOOBS bundles.
|
||||
|
||||
* `DEPLOY_COMPRESSION` (Default: `zip`)
|
||||
|
||||
Set to:
|
||||
* `none` to deploy the actual image (`.img`).
|
||||
* `zip` to deploy a zipped image (`.zip`).
|
||||
* `gz` to deploy a gzipped image (`.img.gz`).
|
||||
* `xz` to deploy a xzipped image (`.img.xz`).
|
||||
|
||||
|
||||
* `DEPLOY_ZIP` (Deprecated)
|
||||
|
||||
This option has been deprecated in favor of `DEPLOY_COMPRESSION`.
|
||||
|
||||
If `DEPLOY_ZIP=0` is still present in your config file, the behavior is the
|
||||
same as with `DEPLOY_COMPRESSION=none`.
|
||||
|
||||
* `COMPRESSION_LEVEL` (Default: `6`)
|
||||
|
||||
Compression level to be used when using `zip`, `gz` or `xz` for
|
||||
`DEPLOY_COMPRESSION`. From 0 to 9 (refer to the tool man page for more
|
||||
information on this. Usually 0 is no compression but very fast, up to 9 with
|
||||
the best compression but very slow ).
|
||||
|
||||
* `USE_QEMU` (Default: `0`)
|
||||
|
||||
Setting to '1' enables the QEMU mode - creating an image that can be mounted via QEMU for an emulated
|
||||
environment. These images include "-qemu" in the image file name.
|
||||
|
||||
* `LOCALE_DEFAULT` (Default: 'en_GB.UTF-8' )
|
||||
|
||||
Default system locale.
|
||||
|
||||
* `TARGET_HOSTNAME` (Default: 'raspberrypi' )
|
||||
|
||||
Setting the hostname to the specified value.
|
||||
|
||||
* `KEYBOARD_KEYMAP` (Default: 'gb' )
|
||||
|
||||
Default keyboard keymap.
|
||||
|
||||
To get the current value from a running system, run `debconf-show
|
||||
keyboard-configuration` and look at the
|
||||
`keyboard-configuration/xkb-keymap` value.
|
||||
|
||||
* `KEYBOARD_LAYOUT` (Default: 'English (UK)' )
|
||||
|
||||
Default keyboard layout.
|
||||
|
||||
To get the current value from a running system, run `debconf-show
|
||||
keyboard-configuration` and look at the
|
||||
`keyboard-configuration/variant` value.
|
||||
|
||||
* `TIMEZONE_DEFAULT` (Default: 'Europe/London' )
|
||||
|
||||
Default time zone.
|
||||
|
||||
To get the current value from a running system, look in
|
||||
`/etc/timezone`.
|
||||
|
||||
* `FIRST_USER_NAME` (Default: `system`)
|
||||
|
||||
Username for the first user. This user only exists during the image creation process.
|
||||
|
||||
* `WPA_COUNTRY` (Default: unset)
|
||||
|
||||
Sets the default WLAN regulatory domain and unblocks WLAN interfaces. This should be a 2-letter ISO/IEC 3166 country Code, i.e. `GB`
|
||||
|
||||
* `ENABLE_SSH` (Default: `0`)
|
||||
|
||||
Setting to `1` will enable ssh server for remote log in. Note that if you are using a common password such as the defaults there is a high risk of attackers taking over you Raspberry Pi.
|
||||
|
||||
* `PUBKEY_SSH_FIRST_USER` (Default: unset)
|
||||
|
||||
Setting this to a value will make that value the contents of the FIRST_USER_NAME's ~/.ssh/authorized_keys. Obviously the value should
|
||||
therefore be a valid authorized_keys file. Note that this does not
|
||||
automatically enable SSH.
|
||||
|
||||
* `PUBKEY_ONLY_SSH` (Default: `0`)
|
||||
|
||||
* Setting to `1` will disable password authentication for SSH and enable
|
||||
public key authentication. Note that if SSH is not enabled this will take
|
||||
effect when SSH becomes enabled.
|
||||
|
||||
* `SETFCAP` (Default: unset)
|
||||
|
||||
* Setting to `1` will prevent pi-gen from dropping the "capabilities"
|
||||
feature. Generating the root filesystem with capabilities enabled and running
|
||||
it from a filesystem that does not support capabilities (like NFS) can cause
|
||||
issues. Only enable this if you understand what it is.
|
||||
|
||||
* `STAGE_LIST` (Default: `stage*`)
|
||||
|
||||
If set, then instead of working through the numeric stages in order, this list will be followed. For example setting to `"stage0 stage1 mystage stage2"` will run the contents of `mystage` before stage2. Note that quotes are needed around the list. An absolute or relative path can be given for stages outside the pi-gen directory.
|
||||
|
||||
* `EXPORT_CONFIG_DIR` (Default: `$BASE_DIR/export-image`)
|
||||
|
||||
If set, use this directory path as the location of scripts to run when generating images. An absolute or relative path can be given for a location outside the pi-gen directory.
|
||||
|
||||
A simple example for building Raspberry Pi OS:
|
||||
`build.sh` sources the file `config` in the current working directory at startup. It can also be specified explicitly:
|
||||
|
||||
```bash
|
||||
IMG_NAME='raspios'
|
||||
sudo ./build.sh -c build_amd64
|
||||
```
|
||||
|
||||
The config file can also be specified on the command line as an argument the `build.sh` or `build-docker.sh` scripts.
|
||||
## Variables
|
||||
|
||||
```
|
||||
./build.sh -c myconfig
|
||||
### Core
|
||||
|
||||
* `IMG_NAME` (Default: `vesperos-$RELEASE-$ARCH`)
|
||||
|
||||
Base name for output files.
|
||||
|
||||
* `RELEASE` (Default: `trixie`)
|
||||
|
||||
Debian release to build against.
|
||||
|
||||
* `ARCH` (Default: `arm64`)
|
||||
|
||||
Target architecture. One of: `arm64`, `armhf`, `amd64`.
|
||||
|
||||
### Directories
|
||||
|
||||
* `WORK_DIR` (Default: `$BASE_DIR/work`)
|
||||
|
||||
Where stage rootfs directories are built. Should be on a Linux filesystem — NTFS will not work.
|
||||
|
||||
* `DEPLOY_DIR` (Default: `$BASE_DIR/deploy`)
|
||||
|
||||
Where finished images and archives are placed.
|
||||
|
||||
### Network / SSH
|
||||
|
||||
* `ENABLE_SSH` (Default: `0`)
|
||||
|
||||
Set to `1` to enable the SSH server in the built image.
|
||||
|
||||
* `PUBKEY_SSH_FIRST_USER` (Default: unset)
|
||||
|
||||
If set, written to `~/.ssh/authorized_keys` for the first user.
|
||||
|
||||
* `PUBKEY_ONLY_SSH` (Default: `0`)
|
||||
|
||||
Set to `1` to disable password auth and require public key auth for SSH.
|
||||
|
||||
* `APT_PROXY` (Default: unset)
|
||||
|
||||
Apt proxy URL (e.g. `http://192.168.1.1:3142`). Not included in the final image.
|
||||
|
||||
* `TEMP_REPO` (Default: unset)
|
||||
|
||||
Additional temporary apt repo used only during the build. Supports `RELEASE` substitution.
|
||||
|
||||
### Locale / Keyboard
|
||||
|
||||
* `LOCALE_DEFAULT` (Default: `en_US.UTF-8`)
|
||||
|
||||
* `KEYBOARD_KEYMAP` (Default: `en`)
|
||||
|
||||
* `KEYBOARD_LAYOUT` (Default: `English (US)`)
|
||||
|
||||
* `TIMEZONE_DEFAULT` (Default: `America/Los Angeles`)
|
||||
|
||||
### Cloud-init
|
||||
|
||||
* `ENABLE_CLOUD_INIT` (Default: `1`)
|
||||
|
||||
Set to `1` to install and configure cloud-init. On RPi, seed files go to `/boot/firmware/`. On amd64, they go to `/var/lib/cloud/seed/nocloud/`.
|
||||
|
||||
### Other
|
||||
|
||||
* `USE_QEMU` (Default: `0`)
|
||||
|
||||
Set to `1` to produce a QEMU-compatible image (adds `-qemu` suffix).
|
||||
|
||||
* `SETFCAP` (Default: unset)
|
||||
|
||||
Set to `1` to preserve Linux capabilities in the rootfs. Only needed for NFS or capability-sensitive deployments.
|
||||
|
||||
* `STAGE_LIST` (Default: `stage*`)
|
||||
|
||||
Override the list of stages to run. Example: `"stage0 stage1 mystage stage2"`.
|
||||
|
||||
* `EXPORTS` (Default: unset)
|
||||
|
||||
Space-separated list of `stage:type` pairs declaring what to export and from which stage. Supported types: `squashfs`, `img`, `noobs`. Example:
|
||||
|
||||
```bash
|
||||
EXPORTS="stage3:squashfs"
|
||||
EXPORTS="stage3:squashfs stage2:img"
|
||||
```
|
||||
|
||||
### Live boot (squashfs only)
|
||||
|
||||
* `LIVEBOOT` (Default: `0`)
|
||||
|
||||
Set to `1` to produce a second `-live` squashfs alongside the raw one. Installs `live-boot`, configures GDM autologin, and rebuilds the initramfs. Only applies to `amd64`.
|
||||
|
||||
* `LIVE_USERNAME` (Default: `vesperos`)
|
||||
* `LIVE_USER_FULLNAME` (Default: `Live User`)
|
||||
* `LIVE_USER_PASSWORD` (Default: `vesperos`)
|
||||
|
||||
### NOOBS
|
||||
|
||||
* `NOOBS_NAME` — Display name shown in the NOOBS menu.
|
||||
* `NOOBS_DESCRIPTION` — Short description shown in the NOOBS menu.
|
||||
|
||||
Both must be set in the config when using `noobs` in `EXPORTS`.
|
||||
|
||||
## Example Config Files
|
||||
|
||||
### amd64 with live boot
|
||||
|
||||
```bash
|
||||
ARCH='amd64'
|
||||
EXPORTS="stage3:squashfs"
|
||||
DEPLOY_COMPRESSION="none"
|
||||
LIVEBOOT=1
|
||||
LIVE_USERNAME="vesper"
|
||||
LIVE_USER_PASSWORD="vesper"
|
||||
```
|
||||
|
||||
This is parsed after `config` so can be used to override values set there.
|
||||
### Raspberry Pi (arm64)
|
||||
|
||||
```bash
|
||||
ARCH='arm64'
|
||||
EXPORTS="stage3:squashfs"
|
||||
DEPLOY_COMPRESSION="none"
|
||||
ENABLE_CLOUD_INIT=1
|
||||
```
|
||||
|
||||
@@ -1,47 +1,55 @@
|
||||
## Docker Build
|
||||
# Docker Build
|
||||
|
||||
Docker can be used to perform the build inside a container. This partially isolates
|
||||
the build from the host system, and allows using the script on non-debian based
|
||||
systems (e.g. Fedora Linux). The isolation is not complete due to the need to use
|
||||
some kernel level services for arm emulation (binfmt) and loop devices (losetup).
|
||||
Docker can be used to run the build inside a container. This is useful on non-Debian hosts (e.g. Fedora, Arch, macOS with Linux VM) or to keep the build environment isolated from the host system.
|
||||
|
||||
To build:
|
||||
> **Note**: The Docker build is not fully isolated — it still needs kernel-level access for `binfmt_misc` (ARM emulation) and `losetup` (loop devices for `.img` builds).
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
vi config # Edit your config file. See above.
|
||||
cp config.example config # edit as needed
|
||||
./build-docker.sh
|
||||
```
|
||||
|
||||
If everything goes well, your finished image will be in the `deploy/` folder.
|
||||
You can then remove the build container with `docker rm -v pigen_work`
|
||||
Output will be in `deploy/`.
|
||||
|
||||
If you encounter errors during the build, you can edit the corresponding scripts, and
|
||||
continue:
|
||||
## Continuing After a Failure
|
||||
|
||||
Edit the failing script, then resume without restarting from scratch:
|
||||
|
||||
```bash
|
||||
CONTINUE=1 ./build-docker.sh
|
||||
```
|
||||
|
||||
To examine the container after a failure you can enter a shell within it using:
|
||||
## Inspecting the Container After a Failure
|
||||
|
||||
```bash
|
||||
sudo docker run -it --privileged --volumes-from=pigen_work pi-gen /bin/bash
|
||||
sudo docker run -it --privileged --volumes-from=pigen_work vesperos-build /bin/bash
|
||||
```
|
||||
|
||||
After successful build, the build container is by default removed. This may be undesired when making incremental changes to a customized build. To prevent the build script from remove the container add
|
||||
## Preserving the Container Between Runs
|
||||
|
||||
By default the container is removed after a successful build. To keep it for incremental development:
|
||||
|
||||
```bash
|
||||
PRESERVE_CONTAINER=1 ./build-docker.sh
|
||||
```
|
||||
|
||||
There is a possibility that even when running from a docker container, the
|
||||
installation of `qemu-user-static` will silently fail when building the image
|
||||
because `binfmt-support` _must be enabled on the underlying kernel_. An easy
|
||||
fix is to ensure `binfmt-support` is installed on the host machine before
|
||||
starting the `./build-docker.sh` script (or using your own docker build
|
||||
solution).
|
||||
## Passing Extra Docker Arguments
|
||||
|
||||
### Passing arguments to Docker
|
||||
Use `PIGEN_DOCKER_OPTS` to pass additional flags to `docker run`:
|
||||
|
||||
When the docker image is run various required command line arguments are provided. For example the system mounts the `/dev` directory to the `/dev` directory within the docker container. If other arguments are required they may be specified in the PIGEN_DOCKER_OPTS environment variable. For example setting `PIGEN_DOCKER_OPTS="--add-host foo:192.168.0.23"` will add '192.168.0.23 foo' to the `/etc/hosts` file in the container. The `--name`
|
||||
and `--privileged` options are already set by the script and should not be redefined.
|
||||
```bash
|
||||
PIGEN_DOCKER_OPTS="--add-host myrepo:192.168.1.10" ./build-docker.sh
|
||||
```
|
||||
|
||||
The `--name` and `--privileged` flags are already set by the script and should not be redefined.
|
||||
|
||||
## binfmt_misc on Docker Hosts
|
||||
|
||||
If building ARM images, `binfmt_misc` must be enabled on the host kernel before starting the build:
|
||||
|
||||
```bash
|
||||
sudo apt-get install binfmt-support qemu-user-static
|
||||
sudo update-binfmts --enable
|
||||
```
|
||||
|
||||
@@ -1,48 +1,73 @@
|
||||
# pi-gen
|
||||
# Getting Started
|
||||
|
||||
Tool used to create Raspberry Pi OS images, and custom images based on Raspberry Pi OS,
|
||||
which was in turn derived from the Raspbian project.
|
||||
VesperOS is a Debian Trixie-based OS for Raspberry Pi (arm64/armhf) and amd64, built using a modified pi-gen pipeline.
|
||||
|
||||
**Note**: Raspberry Pi OS 32 bit images are based primarily on Raspbian, while
|
||||
Raspberry Pi OS 64 bit images are based primarily on Debian.
|
||||
## Supported Architectures
|
||||
|
||||
**Note**: 32 bit images should be built from the `master` branch.
|
||||
64 bit images should be built from the `arm64` branch.
|
||||
| Arch | Target | Output |
|
||||
|---------|-------------------------------|----------------|
|
||||
| `arm64` | Raspberry Pi 3/4/5 (64-bit) | `.squashfs` / `.img` |
|
||||
| `amd64` | x86_64 PCs | `.squashfs` |
|
||||
|
||||
## Dependencies
|
||||
## Build Host Requirements
|
||||
|
||||
pi-gen runs on Debian-based operating systems released after 2017, and we
|
||||
always advise you use the latest OS for security reasons.
|
||||
The build must run on a Debian-based Linux host. Ubuntu 22.04+ or Debian Bookworm/Trixie are recommended.
|
||||
|
||||
On other Linux distributions it may be possible to use the Docker build described
|
||||
below.
|
||||
|
||||
To install the required dependencies for `pi-gen` you should run:
|
||||
Install dependencies:
|
||||
|
||||
```bash
|
||||
apt-get install coreutils quilt parted qemu-user-static debootstrap zerofree zip \
|
||||
sudo apt-get install coreutils quilt parted qemu-user-static debootstrap zerofree zip \
|
||||
dosfstools libarchive-tools libcap2-bin grep rsync xz-utils file git curl bc \
|
||||
gpg pigz xxd arch-test
|
||||
gpg pigz xxd arch-test squashfs-tools xorriso grub-common
|
||||
```
|
||||
|
||||
The file `depends` contains a list of tools needed. The format of this
|
||||
package is `<tool>[:<debian-package>]`.
|
||||
The `depends` file in the repo root lists all required tools in `<tool>[:<debian-package>]` format.
|
||||
|
||||
## Getting started with building your images
|
||||
|
||||
Getting started is as simple as cloning this repository on your build machine. You
|
||||
can do so with:
|
||||
## Cloning
|
||||
|
||||
```bash
|
||||
git clone https://github.com/RPI-Distro/pi-gen.git
|
||||
git clone https://github.com/oxmc/VesperOS.git
|
||||
cd VesperOS
|
||||
```
|
||||
|
||||
`--depth 1` can be added after `git clone` to create a shallow clone, only containing
|
||||
the latest revision of the repository. Do not do this on your development machine.
|
||||
Do not clone to a path containing spaces — `debootstrap` does not support them.
|
||||
|
||||
Also, be careful to clone the repository to a base path **NOT** containing spaces.
|
||||
This configuration is not supported by debootstrap and will lead to `pi-gen` not
|
||||
running.
|
||||
## Configuration
|
||||
|
||||
After cloning the repository, you can move to the next step and start configuring
|
||||
your build.
|
||||
Use one of the provided configs in `configs/`:
|
||||
|
||||
```bash
|
||||
sudo ./build.sh -c configs/amd64
|
||||
sudo ./build.sh -c configs/arm64
|
||||
sudo ./build.sh -c configs/rpi4
|
||||
```
|
||||
|
||||
Or create your own. See [config.md](config.md) for all available options. At minimum set:
|
||||
|
||||
```bash
|
||||
ARCH='amd64' # or arm64
|
||||
EXPORTS="stage3:squashfs"
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
sudo ./build.sh -c configs/amd64
|
||||
```
|
||||
|
||||
Output files are placed in `deploy/`.
|
||||
|
||||
- `squashfs` builds produce a `.squashfs` (and `-live.squashfs` if `LIVEBOOT=1`).
|
||||
- `img` builds produce a `.img` file you can flash with Balena Etcher or `dd`.
|
||||
|
||||
## Skipping Stages (Faster Iteration)
|
||||
|
||||
Add a `SKIP` file to any stage you don't want to re-run:
|
||||
|
||||
```bash
|
||||
# Skip stages 0-2 to iterate on stage3 only
|
||||
touch stage0/SKIP stage1/SKIP stage2/SKIP
|
||||
sudo CLEAN=1 ./build.sh -c configs/amd64
|
||||
```
|
||||
|
||||
Remove the `SKIP` files before a full clean build.
|
||||
|
||||
@@ -1,43 +1,56 @@
|
||||
## How the build process works
|
||||
# How the Build Process Works
|
||||
|
||||
The following process is followed to build images:
|
||||
`build.sh` iterates through stage directories in alphanumeric order and processes each one.
|
||||
|
||||
* Iterate through all of the stage directories in alphanumeric order
|
||||
## Stage Processing
|
||||
|
||||
* Bypass a stage directory if it contains a file called
|
||||
"SKIP"
|
||||
For each stage directory:
|
||||
|
||||
* Run the script `prerun.sh` which is generally just used to copy the build
|
||||
directory between stages.
|
||||
1. Skip the stage entirely if a `SKIP` file is present.
|
||||
2. Run `prerun.sh` — typically copies the rootfs from the previous stage.
|
||||
3. Iterate through each numbered subdirectory (e.g. `00-configure-apt`, `01-sys-tweaks`) in order.
|
||||
4. Within each subdirectory, process these files if present:
|
||||
|
||||
* In each stage directory iterate through each subdirectory and then run each of the
|
||||
install scripts it contains, again in alphanumeric order. **These need to be named
|
||||
with a two digit padded number at the beginning.**
|
||||
There are a number of different files and directories which can be used to
|
||||
control different parts of the build process:
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| `00-run.sh` | Shell script run on the host (must be executable) |
|
||||
| `00-run-chroot.sh` | Shell script run inside the chroot (must be executable) |
|
||||
| `00-debconf` | Passed to `debconf-set-selections` |
|
||||
| `00-packages` | Packages installed via `apt-get install` |
|
||||
| `00-packages-nr` | Same, but with `--no-install-recommends` |
|
||||
| `00-packages-<arch>` | Arch-specific packages (e.g. `00-packages-amd64`, `00-packages-arm-only`) |
|
||||
| `00-packages-nr-<arch>` | Arch-specific packages without recommends |
|
||||
| `00-patches` | Directory of quilt patches applied to the rootfs |
|
||||
| `00-patches-<arch>` | Arch-specific quilt patches |
|
||||
|
||||
- **00-run.sh** - A unix shell script. Needs to be made executable for it to run.
|
||||
## Export Pipeline
|
||||
|
||||
- **00-run-chroot.sh** - A unix shell script which will be run in the chroot
|
||||
of the image build directory. Needs to be made executable for it to run.
|
||||
After all stages are processed, the build runs the export pipelines declared in the config via the `EXPORTS` variable:
|
||||
|
||||
- **00-debconf** - Contents of this file are passed to debconf-set-selections
|
||||
to configure things like locale, etc.
|
||||
```bash
|
||||
EXPORTS="stage3:squashfs" # single export
|
||||
EXPORTS="stage3:squashfs stage2:img" # multiple exports
|
||||
```
|
||||
|
||||
- **00-packages** - A list of packages to install. Can have more than one, space
|
||||
separated, per line.
|
||||
| Export type | Pipeline | Output |
|
||||
|-------------|----------|--------|
|
||||
| `squashfs` | `exports/squashfs/` | `.squashfs` filesystem archive |
|
||||
| `img` | `exports/img/` | `.img` disk image |
|
||||
| `noobs` | `exports/noobs/` | NOOBS-compatible archive |
|
||||
|
||||
- **00-packages-nr** - As 00-packages, except these will be installed using
|
||||
the `--no-install-recommends -y` parameters to apt-get.
|
||||
### squashfs pipeline
|
||||
|
||||
- **00-patches** - A directory containing patch files to be applied, using quilt.
|
||||
If a file named 'EDIT' is present in the directory, the build process will
|
||||
be interrupted with a bash session, allowing an opportunity to create/revise
|
||||
the patches.
|
||||
1. `prerun.sh` — rsync rootfs into work dir
|
||||
2. `01-set-sources` — clean apt sources
|
||||
3. `02-network` — configure resolv.conf
|
||||
4. `03-finalise` — rebuild initramfs, clean up rootfs
|
||||
5. `04-export` — build squashfs; if `LIVEBOOT=1`, also applies live-boot config and produces a second `-live` squashfs
|
||||
|
||||
* If the stage directory contains files called "EXPORT_NOOBS" or "EXPORT_IMAGE" then
|
||||
add this stage to a list of images to generate
|
||||
## Arch-Specific Logic
|
||||
|
||||
* Generate the images for any stages that have specified them
|
||||
Scripts and package files support arch suffixes:
|
||||
- `-arm-only` — runs on `arm64` and `armhf` only
|
||||
- `-amd64` — runs on `amd64` only
|
||||
- `-${ARCH}` — can be any specific arch string
|
||||
|
||||
It is recommended to examine build.sh for finer details.
|
||||
Scripts that handle arch themselves check `${ARCH}` and exit early if not applicable.
|
||||
|
||||
@@ -1,84 +1,61 @@
|
||||
## Stage Anatomy
|
||||
# Stage Anatomy
|
||||
|
||||
### Raspbian Stage Overview
|
||||
VesperOS is built in stages. Each stage builds on the previous one.
|
||||
|
||||
The build of Raspbian is divided up into several stages for logical clarity
|
||||
and modularity. This causes some initial complexity, but it simplifies
|
||||
maintenance and allows for more easy customization.
|
||||
## Stages
|
||||
|
||||
- **Stage 0** - bootstrap. The primary purpose of this stage is to create a
|
||||
usable filesystem. This is accomplished largely through the use of
|
||||
`debootstrap`, which creates a minimal filesystem suitable for use as a
|
||||
base.tgz on Debian systems. This stage also configures apt settings and
|
||||
installs `raspberrypi-bootloader` which is missed by debootstrap. The
|
||||
minimal core is installed but not configured. As a result, this stage will not boot.
|
||||
### Stage 0 — Bootstrap
|
||||
|
||||
- **Stage 1** - truly minimal system. This stage makes the system bootable by
|
||||
installing system files like `/etc/fstab`, configures the bootloader, makes
|
||||
the network operable, and installs packages like raspi-config. At this
|
||||
stage the system should boot to a local console from which you have the
|
||||
means to perform basic tasks needed to configure and install the system.
|
||||
Bootstraps a minimal Debian Trixie filesystem using `debootstrap`. Configures apt sources (including the VesperOS apt repo), installs firmware packages, and sets up the base package state. Does not produce a bootable system.
|
||||
|
||||
- **Stage 2** - lite system. This stage produces the Raspberry Pi OS Lite image.
|
||||
Stage 2 installs some optimized memory functions, sets timezone and charmap
|
||||
defaults, installs fake-hwclock and ntp, wireless LAN and bluetooth support,
|
||||
dphys-swapfile, and other basics for managing the hardware. It also
|
||||
creates necessary groups and gives the pi user access to sudo and the
|
||||
standard console hardware permission groups.
|
||||
- RPi: installs `raspi-firmware`, `linux-image-rpi-v8`, `linux-image-rpi-2712`
|
||||
- amd64: installs `grub2`, `linux-image-amd64`
|
||||
|
||||
Note: Raspberry Pi OS Lite contains a number of tools for development,
|
||||
including `Python`, `Lua` and the `build-essential` package. If you are
|
||||
creating an image to deploy in products, be sure to remove extraneous development
|
||||
tools before deployment.
|
||||
### Stage 1 — Minimal Bootable System
|
||||
|
||||
- **Stage 3** - desktop system. Here's where you get the full desktop system
|
||||
with X11 and LXDE, web browsers, git for development, Raspberry Pi OS custom UI
|
||||
enhancements, etc. This is a base desktop system, with some development
|
||||
tools installed.
|
||||
Makes the system bootable. Installs `/etc/fstab` (arch-specific), configures the hostname, locale, and basic networking. At this stage the system can boot to a console.
|
||||
|
||||
- **Stage 4** - Normal Raspberry Pi OS image. System meant to fit on a 4GB card.
|
||||
This is the stage that installs most things that make Raspberry Pi OS friendly
|
||||
to new users - e.g. system documentation.
|
||||
- RPi fstab: `/boot/firmware` (vfat) + btrfs root with subvolumes
|
||||
- amd64 fstab: `/boot` (vfat) + `/boot/efi` + btrfs root with subvolumes
|
||||
|
||||
- **Stage 5** - The Raspberry Pi OS Full image. More development
|
||||
tools, an email client, learning tools like Scratch, specialized packages
|
||||
like sonic-pi, office productivity, etc.
|
||||
Both use btrfs subvolumes: `@`, `@home`, `@var`, `@snapshots`.
|
||||
|
||||
### Stage specification
|
||||
### Stage 2 — System Layer
|
||||
|
||||
If you wish to build up to a specified stage (such as building up to stage 2
|
||||
for a lite system), place an empty file named `SKIP` in each of the `./stage`
|
||||
directories you wish not to include.
|
||||
Installs the core system utilities, tools, and services. This is the "lite" layer.
|
||||
|
||||
Then add an empty file named `SKIP_IMAGES` to `./stage4` and `./stage5` (if building up to stage 2) or
|
||||
to `./stage2` (if building a minimal system).
|
||||
Key additions:
|
||||
- `zsh` as the system-wide default shell
|
||||
- `btrfs-progs` + `snapper` for filesystem snapshots
|
||||
- `cloud-init` + `netplan` for first-boot configuration
|
||||
- Bluetooth, Wi-Fi, avahi, SSH, cups, and other system services
|
||||
- Python 3, Lua, build tools
|
||||
|
||||
### Stage 3 — Desktop
|
||||
|
||||
Installs the full GNOME desktop environment and user-facing applications.
|
||||
|
||||
Key additions:
|
||||
- GNOME Shell and core apps
|
||||
- Firefox ESR
|
||||
- amd64: `live-boot`, `live-config`, `live-config-systemd`, `grub-efi-amd64`
|
||||
|
||||
This stage triggers the export pipeline via `EXPORT_ISO` and/or `EXPORT_SQUASHFS` for amd64, and `EXPORT_IMAGE` for RPi.
|
||||
|
||||
## Export Outputs
|
||||
|
||||
| Stage | Arch | Marker | Output |
|
||||
|-------|------|--------|--------|
|
||||
| stage3 | amd64 | `EXPORT_ISO` | Bootable live ISO |
|
||||
| stage3 | amd64 | `EXPORT_SQUASHFS` | Raw squashfs archive |
|
||||
| stage3 | arm64/armhf | `EXPORT_IMAGE` | Flashable `.img` |
|
||||
|
||||
## Skipping Stages for Development
|
||||
|
||||
Place a `SKIP` file in any stage directory to skip it. Use `SKIP_IMAGES` to prevent an export from running without skipping the stage itself.
|
||||
|
||||
```bash
|
||||
# Example for building a lite system
|
||||
echo "IMG_NAME='raspios'" > config
|
||||
touch ./stage3/SKIP ./stage4/SKIP ./stage5/SKIP
|
||||
touch ./stage4/SKIP_IMAGES ./stage5/SKIP_IMAGES
|
||||
sudo ./build.sh # or ./build-docker.sh
|
||||
# Only rebuild stage3 (assumes stage0-2 already built)
|
||||
touch stage0/SKIP stage1/SKIP stage2/SKIP
|
||||
sudo CLEAN=1 ./build.sh -c config
|
||||
```
|
||||
|
||||
If you wish to build further configurations upon (for example) the lite
|
||||
system, you can also delete the contents of `./stage3` and `./stage4` and
|
||||
replace with your own contents in the same format.
|
||||
|
||||
|
||||
## Skipping stages to speed up development
|
||||
|
||||
If you're working on a specific stage the recommended development process is as
|
||||
follows:
|
||||
|
||||
* Add a file called SKIP_IMAGES into the directories containing EXPORT_* files
|
||||
(currently stage2, stage4 and stage5)
|
||||
* Add SKIP files to the stages you don't want to build. For example, if you're
|
||||
basing your image on the lite image you would add these to stages 3, 4 and 5.
|
||||
* Run build.sh to build all stages
|
||||
* Add SKIP files to the earlier successfully built stages
|
||||
* Modify the last stage
|
||||
* Rebuild just the last stage using `sudo CLEAN=1 ./build.sh` (or, for docker builds
|
||||
`PRESERVE_CONTAINER=1 CONTINUE=1 CLEAN=1 ./build-docker.sh`)
|
||||
* Once you're happy with the image you can remove the SKIP_IMAGES files and
|
||||
export your image to test
|
||||
@@ -1,45 +1,59 @@
|
||||
# Troubleshooting
|
||||
|
||||
## `64 Bit Systems`
|
||||
A 64 bit image can be generated from the `arm64` branch in this repository. Just
|
||||
replace the command from [this section](#getting-started-with-building-your-images)
|
||||
by the one below, and follow the rest of the documentation:
|
||||
```bash
|
||||
git clone --branch arm64 https://github.com/RPI-Distro/pi-gen.git
|
||||
```
|
||||
## binfmt_misc (cross-arch builds)
|
||||
|
||||
If you want to generate a 64 bits image from a Raspberry Pi running a 32 bits
|
||||
version, you need to add `arm_64bit=1` to your `config.txt` file and reboot your
|
||||
machine. This will restart your machine with a 64 bits kernel. This will only
|
||||
work from a Raspberry Pi with a 64-bit capable processor (i.e. Raspberry Pi Zero
|
||||
2, Raspberry Pi 3 or Raspberry Pi 4).
|
||||
|
||||
|
||||
## `binfmt_misc`
|
||||
|
||||
Linux is able to execute binaries from other architectures, meaning that it should be
|
||||
possible to make use of `pi-gen` on an x86_64 system, even though it will be running
|
||||
ARM binaries. This requires support from the [`binfmt_misc`](https://en.wikipedia.org/wiki/Binfmt_misc)
|
||||
kernel module.
|
||||
|
||||
You may see one of the following errors:
|
||||
When building ARM images on an x86_64 host, Linux uses `binfmt_misc` to run ARM binaries via QEMU. If you see:
|
||||
|
||||
```
|
||||
update-binfmts: warning: Couldn't load the binfmt_misc module.
|
||||
```
|
||||
```
|
||||
W: Failure trying to run: chroot "/pi-gen/work/test/stage0/rootfs" /bin/true
|
||||
and/or
|
||||
chroot: failed to run command '/bin/true': Exec format error
|
||||
```
|
||||
|
||||
To resolve this, ensure that the following files are available (install them if necessary):
|
||||
Fix:
|
||||
|
||||
```
|
||||
/lib/modules/$(uname -r)/kernel/fs/binfmt_misc.ko
|
||||
/usr/bin/qemu-aarch64-static
|
||||
```bash
|
||||
sudo modprobe binfmt_misc
|
||||
sudo apt-get install qemu-user-static binfmt-support
|
||||
sudo update-binfmts --enable
|
||||
```
|
||||
|
||||
You may also need to load the module by hand - run `modprobe binfmt_misc`.
|
||||
On WSL2 you may need to install `binfmt-support` on the host Windows side or use Docker instead.
|
||||
|
||||
If you are using WSL to build you may have to enable the service `sudo update-binfmts --enable`
|
||||
## "Required dependencies not installed"
|
||||
|
||||
The `depends` file lists tools that must be present on the build host. Read the README for the current install commands.
|
||||
|
||||
Note: `grub-efi-amd64-bin` and `grub-pc-bin` are data packages with no associated binary — they are not checked by the dependency checker but must be installed for `grub-mkrescue` to work.
|
||||
|
||||
## ISO doesn't boot
|
||||
|
||||
- Verify the ISO was written correctly: use Balena Etcher or `dd` — do not just copy the file.
|
||||
- In VMware/VirtualBox, set firmware to UEFI.
|
||||
- If GRUB appears but the system hangs after selecting a menu entry, try the "safe mode" entry (adds `nomodeset`).
|
||||
|
||||
## Squashfs / initramfs errors during export-iso
|
||||
|
||||
- `mkinitramfs: failed to determine device for /` — This happens when `MODULES=dep` is set in a chroot. The build sets `MODULES=most` to avoid this.
|
||||
- `W: Couldn't identify type of root file system` — Expected during initramfs generation in a live build; the fstab is rewritten for live-boot and has no real block devices to detect.
|
||||
|
||||
## Stage fails despite SKIP file
|
||||
|
||||
`SKIP` files only skip re-running the stage scripts. They do not skip the export pipeline. Use `SKIP_IMAGES` to skip exports while still running the stage.
|
||||
|
||||
## Build fails on NTFS / exFAT partition
|
||||
|
||||
The work directory must be on a Linux filesystem (ext4, btrfs, xfs). NTFS and exFAT do not support the required file attributes. Set `WORK_DIR` to a path on a Linux filesystem:
|
||||
|
||||
```bash
|
||||
export WORK_DIR=/mnt/linux-disk/vesperos-work
|
||||
```
|
||||
|
||||
## Apt errors: "doesn't support architecture"
|
||||
|
||||
The VesperOS apt repo (`cdn.oxmc.me/apt`) currently only supports `arm64`/`armhf`. On amd64 builds you will see:
|
||||
|
||||
```
|
||||
Notice: Skipping ... doesn't support architecture 'amd64'
|
||||
```
|
||||
|
||||
This is expected and not an error — standard Debian repos are used for amd64 packages.
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
|
||||
|
||||
IMGID="$(dd if="${IMG_FILE}" skip=440 bs=1 count=4 2>/dev/null | xxd -e | cut -f 2 -d' ')"
|
||||
|
||||
BOOT_PARTUUID="${IMGID}-01"
|
||||
ROOT_PARTUUID="${IMGID}-02"
|
||||
#HOME_PARTUUID="${IMGID}-03"
|
||||
|
||||
sed -i "s/BOOTDEV/PARTUUID=${BOOT_PARTUUID}/" "${ROOTFS_DIR}/etc/fstab"
|
||||
sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${ROOTFS_DIR}/etc/fstab"
|
||||
#sed -i "s/HOMEDEV/PARTUUID=${HOME_PARTUUID}/" "${ROOTFS_DIR}/etc/fstab"
|
||||
|
||||
sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${ROOTFS_DIR}/boot/firmware/cmdline.txt"
|
||||
@@ -1,141 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
|
||||
INFO_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.info"
|
||||
SBOM_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.sbom"
|
||||
BMAP_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.bmap"
|
||||
|
||||
on_chroot << EOF
|
||||
update-initramfs -k all -c
|
||||
if [ -x /etc/init.d/fake-hwclock ]; then
|
||||
/etc/init.d/fake-hwclock stop
|
||||
fi
|
||||
if hash hardlink 2>/dev/null; then
|
||||
hardlink -t /usr/share/doc
|
||||
fi
|
||||
EOF
|
||||
|
||||
if [ -f "${ROOTFS_DIR}/etc/initramfs-tools/update-initramfs.conf" ]; then
|
||||
sed -i 's/^update_initramfs=.*/update_initramfs=yes/' "${ROOTFS_DIR}/etc/initramfs-tools/update-initramfs.conf"
|
||||
sed -i 's/^MODULES=.*/MODULES=dep/' "${ROOTFS_DIR}/etc/initramfs-tools/initramfs.conf"
|
||||
fi
|
||||
|
||||
#if [ -d "${ROOTFS_DIR}/home/${FIRST_USER_NAME}/.config" ]; then
|
||||
# chmod 700 "${ROOTFS_DIR}/home/${FIRST_USER_NAME}/.config"
|
||||
#fi
|
||||
|
||||
rm -f "${ROOTFS_DIR}/usr/bin/qemu-arm-static"
|
||||
|
||||
if [ "${USE_QEMU}" != "1" ]; then
|
||||
if [ -e "${ROOTFS_DIR}/etc/ld.so.preload.disabled" ]; then
|
||||
mv "${ROOTFS_DIR}/etc/ld.so.preload.disabled" "${ROOTFS_DIR}/etc/ld.so.preload"
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f "${ROOTFS_DIR}/etc/network/interfaces.dpkg-old"
|
||||
|
||||
rm -f "${ROOTFS_DIR}/etc/apt/sources.list~"
|
||||
rm -f "${ROOTFS_DIR}/etc/apt/trusted.gpg~"
|
||||
|
||||
rm -f "${ROOTFS_DIR}/etc/passwd-"
|
||||
rm -f "${ROOTFS_DIR}/etc/group-"
|
||||
rm -f "${ROOTFS_DIR}/etc/shadow-"
|
||||
rm -f "${ROOTFS_DIR}/etc/gshadow-"
|
||||
rm -f "${ROOTFS_DIR}/etc/subuid-"
|
||||
rm -f "${ROOTFS_DIR}/etc/subgid-"
|
||||
|
||||
rm -f "${ROOTFS_DIR}"/var/cache/debconf/*-old
|
||||
rm -f "${ROOTFS_DIR}"/var/lib/dpkg/*-old
|
||||
|
||||
rm -f "${ROOTFS_DIR}"/usr/share/icons/*/icon-theme.cache
|
||||
|
||||
rm -f "${ROOTFS_DIR}/var/lib/dbus/machine-id"
|
||||
|
||||
true > "${ROOTFS_DIR}/etc/machine-id"
|
||||
|
||||
ln -nsf /proc/mounts "${ROOTFS_DIR}/etc/mtab"
|
||||
|
||||
find "${ROOTFS_DIR}/var/log/" -type f -exec cp /dev/null {} \;
|
||||
|
||||
rm -f "${ROOTFS_DIR}/root/.vnc/private.key"
|
||||
rm -f "${ROOTFS_DIR}/etc/vnc/updateid"
|
||||
|
||||
update_issue "$(basename "${EXPORT_DIR}")"
|
||||
install -m 644 "${ROOTFS_DIR}/etc/rpi-issue" "${ROOTFS_DIR}/boot/firmware/issue.txt"
|
||||
if ! [ -L "${ROOTFS_DIR}/boot/issue.txt" ]; then
|
||||
ln -s firmware/issue.txt "${ROOTFS_DIR}/boot/issue.txt"
|
||||
fi
|
||||
|
||||
cp "$ROOTFS_DIR/etc/rpi-issue" "$INFO_FILE"
|
||||
|
||||
{
|
||||
if [ -f "$ROOTFS_DIR/usr/share/doc/raspberrypi-kernel/changelog.Debian.gz" ]; then
|
||||
firmware=$(zgrep "firmware as of" \
|
||||
"$ROOTFS_DIR/usr/share/doc/raspberrypi-kernel/changelog.Debian.gz" | \
|
||||
head -n1 | sed -n 's|.* \([^ ]*\)$|\1|p')
|
||||
printf "\nFirmware: https://github.com/raspberrypi/firmware/tree/%s\n" "$firmware"
|
||||
|
||||
kernel="$(curl -s -L "https://github.com/raspberrypi/firmware/raw/$firmware/extra/git_hash")"
|
||||
printf "Kernel: https://github.com/raspberrypi/linux/tree/%s\n" "$kernel"
|
||||
|
||||
uname="$(curl -s -L "https://github.com/raspberrypi/firmware/raw/$firmware/extra/uname_string7")"
|
||||
printf "Uname string: %s\n" "$uname"
|
||||
fi
|
||||
|
||||
printf "\nPackages:\n"
|
||||
dpkg -l --root "$ROOTFS_DIR"
|
||||
} >> "$INFO_FILE"
|
||||
|
||||
if hash syft 2>/dev/null; then
|
||||
syft scan dir:"${ROOTFS_DIR}" \
|
||||
--base-path="${ROOTFS_DIR}" \
|
||||
--source-name="${IMG_NAME}${IMG_SUFFIX}" \
|
||||
--source-version="${IMG_DATE}" \
|
||||
-o spdx-json="${SBOM_FILE}"
|
||||
fi
|
||||
|
||||
ROOT_DEV="$(awk "\$2 == \"${ROOTFS_DIR}\" {print \$1}" /etc/mtab)"
|
||||
|
||||
unmount "${ROOTFS_DIR}"
|
||||
zerofree "${ROOT_DEV}"
|
||||
|
||||
unmount_image "${IMG_FILE}"
|
||||
|
||||
if hash bmaptool 2>/dev/null; then
|
||||
bmaptool create \
|
||||
-o "${BMAP_FILE}" \
|
||||
"${IMG_FILE}"
|
||||
fi
|
||||
|
||||
mkdir -p "${DEPLOY_DIR}"
|
||||
|
||||
rm -f "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.*"
|
||||
rm -f "${DEPLOY_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
|
||||
|
||||
case "${DEPLOY_COMPRESSION}" in
|
||||
zip)
|
||||
pushd "${STAGE_WORK_DIR}" > /dev/null
|
||||
zip -"${COMPRESSION_LEVEL}" \
|
||||
"${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.zip" "$(basename "${IMG_FILE}")"
|
||||
popd > /dev/null
|
||||
;;
|
||||
gz)
|
||||
pigz --force -"${COMPRESSION_LEVEL}" "$IMG_FILE" --stdout > \
|
||||
"${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.img.gz"
|
||||
;;
|
||||
xz)
|
||||
xz --compress --force --threads 0 --memlimit-compress=50% -"${COMPRESSION_LEVEL}" \
|
||||
--stdout "$IMG_FILE" > "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.img.xz"
|
||||
;;
|
||||
none | *)
|
||||
cp "$IMG_FILE" "$DEPLOY_DIR/"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -f "${SBOM_FILE}" ]; then
|
||||
xz -c "${SBOM_FILE}" > "$DEPLOY_DIR/image_$(basename "${SBOM_FILE}").xz"
|
||||
fi
|
||||
if [ -f "${BMAP_FILE}" ]; then
|
||||
xz -c "${BMAP_FILE}" > "$DEPLOY_DIR/image_$(basename "${BMAP_FILE}").xz"
|
||||
fi
|
||||
cp "$INFO_FILE" "$DEPLOY_DIR/"
|
||||
@@ -1,134 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
IMG_NAME="${IMG_FILENAME}${IMG_SUFFIX}"
|
||||
IMG_FILE="${STAGE_WORK_DIR}/${IMG_NAME}.img"
|
||||
MOUNT_DIR="${ROOTFS_DIR}"
|
||||
BOOT_SIZE=$((512 * 1024 * 1024))
|
||||
EFI_SIZE=$((128 * 1024 * 1024)) # 128MB EFI partition
|
||||
RECOVERY_SIZE=$((256 * 1024 * 1024))
|
||||
ALIGN=$((4 * 1024 * 1024))
|
||||
|
||||
unmount_image "${IMG_FILE}"
|
||||
rm -f "${IMG_FILE}"
|
||||
rm -rf "${MOUNT_DIR}"
|
||||
mkdir -p "${MOUNT_DIR}"
|
||||
|
||||
# Calculate rootfs size
|
||||
ROOT_SIZE=$(du -x --apparent-size -s "${EXPORT_ROOTFS_DIR}" --exclude var/cache/apt/archives --exclude boot/firmware --block-size=1 | cut -f 1)
|
||||
ROOT_MARGIN="$(echo "($ROOT_SIZE * 0.2 + 200 * 1024 * 1024) / 1" | bc)"
|
||||
BOOT_PART_START=$((ALIGN))
|
||||
BOOT_PART_SIZE=$(((BOOT_SIZE + ALIGN - 1) / ALIGN * ALIGN))
|
||||
EFI_PART_START=$((BOOT_PART_START + BOOT_PART_SIZE))
|
||||
EFI_PART_SIZE=$(((EFI_SIZE + ALIGN - 1) / ALIGN * ALIGN))
|
||||
ROOT_PART_START=$((EFI_PART_START + EFI_PART_SIZE))
|
||||
ROOT_PART_SIZE=$(((ROOT_SIZE + ROOT_MARGIN + ALIGN - 1) / ALIGN * ALIGN))
|
||||
RECOVERY_PART_START=$((ROOT_PART_START + ROOT_PART_SIZE))
|
||||
RECOVERY_PART_SIZE=$(((RECOVERY_SIZE + ALIGN - 1) / ALIGN * ALIGN))
|
||||
IMG_SIZE=$((BOOT_PART_START + BOOT_PART_SIZE + EFI_PART_SIZE + ROOT_PART_SIZE + RECOVERY_PART_SIZE))
|
||||
|
||||
# Create raw image
|
||||
truncate -s "${IMG_SIZE}" "${IMG_FILE}"
|
||||
parted --script "${IMG_FILE}" mklabel gpt
|
||||
parted --script "${IMG_FILE}" unit B mkpart primary fat32 "${BOOT_PART_START}" "$((BOOT_PART_START + BOOT_PART_SIZE - 1))"
|
||||
parted --script "${IMG_FILE}" set 1 boot on
|
||||
parted --script "${IMG_FILE}" unit B mkpart primary fat32 "${EFI_PART_START}" "$((EFI_PART_START + EFI_PART_SIZE - 1))"
|
||||
parted --script "${IMG_FILE}" set 2 esp on
|
||||
parted --script "${IMG_FILE}" unit B mkpart primary ext4 "${ROOT_PART_START}" "$((ROOT_PART_START + ROOT_PART_SIZE - 1))"
|
||||
parted --script "${IMG_FILE}" unit B mkpart primary ext4 "${RECOVERY_PART_START}" "$((RECOVERY_PART_START + RECOVERY_PART_SIZE - 1))"
|
||||
|
||||
# Create loop device
|
||||
cnt=0
|
||||
until ensure_next_loopdev && LOOP_DEV="$(losetup --show --find --partscan "$IMG_FILE")"; do
|
||||
((cnt++))
|
||||
if [ $cnt -ge 5 ]; then echo "ERROR: losetup failed"; exit 1; fi
|
||||
echo "Retrying losetup..."; sleep 5
|
||||
done
|
||||
ensure_loopdev_partitions "$LOOP_DEV"
|
||||
|
||||
BOOT_DEV="${LOOP_DEV}p1"
|
||||
EFI_DEV="${LOOP_DEV}p2"
|
||||
ROOT_DEV="${LOOP_DEV}p3"
|
||||
RECOVERY_DEV="${LOOP_DEV}p4"
|
||||
|
||||
# Format partitions
|
||||
FAT_SIZE=$([ "$BOOT_SIZE" -lt 134742016 ] && echo 16 || echo 32)
|
||||
mkdosfs -n bootfs -F "$FAT_SIZE" -s 4 "$BOOT_DEV"
|
||||
mkfs.fat -F 32 -n EFI "$EFI_DEV"
|
||||
mkfs.ext4 -L rootfs -O "^64bit,^huge_file" "$ROOT_DEV"
|
||||
mkfs.ext4 -L recovery "$RECOVERY_DEV"
|
||||
|
||||
|
||||
# Mount and copy rootfs
|
||||
mount "$ROOT_DEV" "$MOUNT_DIR" -t ext4
|
||||
mkdir -p "${MOUNT_DIR}/boot"
|
||||
mount "$BOOT_DEV" "${MOUNT_DIR}/boot" -t vfat
|
||||
mkdir -p "${MOUNT_DIR}/boot/efi"
|
||||
mount "$EFI_DEV" "${MOUNT_DIR}/boot/efi" -t vfat
|
||||
rsync -aHAXx --exclude /var/cache/apt/archives --exclude /boot/firmware --exclude /boot/overlays "${EXPORT_ROOTFS_DIR}/" "${MOUNT_DIR}/"
|
||||
|
||||
# Recovery partition
|
||||
mkdir -p "${MOUNT_DIR}/recovery"
|
||||
mount "$RECOVERY_DEV" "${MOUNT_DIR}/recovery" -t ext4
|
||||
# Optionally copy recovery tools
|
||||
# cp recovery-tools/recovery.sh "${MOUNT_DIR}/recovery/"
|
||||
|
||||
# Install GRUB (BIOS)
|
||||
mkdir -p "${MOUNT_DIR}/boot/grub"
|
||||
cat > "${MOUNT_DIR}/boot/grub/grub.cfg" <<EOF
|
||||
set default=0
|
||||
set timeout=5
|
||||
|
||||
menuentry "Linux" {
|
||||
linux /boot/vmlinuz root=/dev/sda3
|
||||
initrd /boot/initrd.img
|
||||
}
|
||||
EOF
|
||||
|
||||
grub-install \
|
||||
--target=i386-pc \
|
||||
--boot-directory="${MOUNT_DIR}/boot" \
|
||||
--modules="part_msdos ext2 fat normal biosdisk" \
|
||||
--force \
|
||||
--no-floppy \
|
||||
--boot-directory="${MOUNT_DIR}/boot" \
|
||||
"$LOOP_DEV"
|
||||
|
||||
# Install GRUB (UEFI)
|
||||
mkdir -p "${MOUNT_DIR}/boot/efi/EFI/boot"
|
||||
grub-install \
|
||||
--target=x86_64-efi \
|
||||
--efi-directory="${MOUNT_DIR}/boot/efi" \
|
||||
--boot-directory="${MOUNT_DIR}/boot" \
|
||||
--removable \
|
||||
--no-nvram \
|
||||
--modules="part_gpt part_msdos ext2 fat normal efi_gop efi_uga biosdisk" \
|
||||
--bootloader-id=GRUB \
|
||||
--recheck
|
||||
|
||||
# Unmount all
|
||||
umount -l "${MOUNT_DIR}/boot/efi"
|
||||
umount -l "${MOUNT_DIR}/boot"
|
||||
umount -l "${MOUNT_DIR}/recovery"
|
||||
umount -l "${MOUNT_DIR}"
|
||||
losetup -d "$LOOP_DEV"
|
||||
|
||||
# Create hybrid ISO using xorriso (make sure it's installed)
|
||||
ISO_FILE="${STAGE_WORK_DIR}/${IMG_NAME}.iso"
|
||||
EFI_IMG="${STAGE_WORK_DIR}/efi.img"
|
||||
dd if=/dev/zero of="${EFI_IMG}" bs=1M count=128
|
||||
mkfs.vfat "${EFI_IMG}"
|
||||
mmd -i "${EFI_IMG}" ::/EFI ::/EFI/boot
|
||||
mcopy -i "${EFI_IMG}" "${MOUNT_DIR}/boot/efi/EFI/boot/bootx64.efi" ::/EFI/boot/bootx64.efi
|
||||
xorriso -as mkisofs \
|
||||
-r -J -joliet -l \
|
||||
-b boot/grub/i386-pc/eltorito.img \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
-eltorito-alt-boot \
|
||||
-e efi.img \
|
||||
-no-emul-boot \
|
||||
-isohybrid-gpt-basdat \
|
||||
-o "${ISO_FILE}" \
|
||||
"${MOUNT_DIR}" \
|
||||
--efi-boot-part --efi-boot-image --protective-msdos-label
|
||||
|
||||
echo "Bootable ISO with BIOS and UEFI support created at ${ISO_FILE}"
|
||||
@@ -5,14 +5,17 @@ INFO_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.info"
|
||||
SBOM_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.sbom"
|
||||
BMAP_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.bmap"
|
||||
|
||||
on_chroot << EOF
|
||||
update-initramfs -k all -c
|
||||
if [ -x /etc/init.d/fake-hwclock ]; then
|
||||
/etc/init.d/fake-hwclock stop
|
||||
fi
|
||||
if hash hardlink 2>/dev/null; then
|
||||
hardlink -t /usr/share/doc
|
||||
fi
|
||||
on_chroot <<- EOF
|
||||
update-initramfs -k all -c
|
||||
if hash hardlink 2>/dev/null; then
|
||||
hardlink -t /usr/share/doc
|
||||
fi
|
||||
if [ -f /usr/lib/systemd/system/apt-listchanges.service ]; then
|
||||
python3 -m apt_listchanges.populate_database --profile apt
|
||||
systemctl disable apt-listchanges.timer
|
||||
fi
|
||||
install -m 755 -o systemd-timesync -g systemd-timesync -d /var/lib/systemd/timesync
|
||||
install -m 644 -o systemd-timesync -g systemd-timesync /dev/null /var/lib/systemd/timesync/clock
|
||||
EOF
|
||||
|
||||
if [ -f "${ROOTFS_DIR}/etc/initramfs-tools/update-initramfs.conf" ]; then
|
||||
@@ -51,7 +54,7 @@ rm -f "${ROOTFS_DIR}"/usr/share/icons/*/icon-theme.cache
|
||||
|
||||
rm -f "${ROOTFS_DIR}/var/lib/dbus/machine-id"
|
||||
|
||||
true > "${ROOTFS_DIR}/etc/machine-id"
|
||||
echo "uninitialized" > "${ROOTFS_DIR}/etc/machine-id"
|
||||
|
||||
ln -nsf /proc/mounts "${ROOTFS_DIR}/etc/mtab"
|
||||
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 104 KiB |
@@ -1,11 +1,7 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
if [[ "${ARCH}" == "arm64" || "${ARCH}" == "armhf" ]]; then
|
||||
if [ ! -x "${ROOTFS_DIR}/usr/bin/qemu-arm-static" ]; then
|
||||
cp /usr/bin/qemu-arm-static "${ROOTFS_DIR}/usr/bin/"
|
||||
fi
|
||||
|
||||
if [ -e "${ROOTFS_DIR}/etc/ld.so.preload" ]; then
|
||||
mv "${ROOTFS_DIR}/etc/ld.so.preload" "${ROOTFS_DIR}/etc/ld.so.preload.disabled"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -1,10 +1,10 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
rm -f "${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache"
|
||||
rm -f "${ROOTFS_DIR}/etc/apt/sources.list.d/00-temp.list"
|
||||
find "${ROOTFS_DIR}/var/lib/apt/lists/" -type f -delete
|
||||
on_chroot << EOF
|
||||
apt-get update
|
||||
apt-get -y dist-upgrade --auto-remove --purge
|
||||
apt-get clean
|
||||
apt-file update
|
||||
EOF
|
||||
53
exports/squashfs/03-finalise/01-run.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# Ensure update-initramfs actually runs — it silently exits if update_initramfs=no/disabled,
|
||||
# which may have been set during the build to suppress apt-hook rebuilds.
|
||||
if [ -f "${ROOTFS_DIR}/etc/initramfs-tools/update-initramfs.conf" ]; then
|
||||
sed -i 's/^update_initramfs=.*/update_initramfs=yes/' "${ROOTFS_DIR}/etc/initramfs-tools/update-initramfs.conf"
|
||||
fi
|
||||
|
||||
on_chroot <<- EOF
|
||||
# Ensure Plymouth plymouthd.conf has the correct theme before packing initramfs.
|
||||
# update-alternatives only sets the symlink; the initramfs hook reads plymouthd.conf.
|
||||
if which plymouth-set-default-theme > /dev/null 2>&1; then
|
||||
plymouth-set-default-theme vesperos
|
||||
fi
|
||||
update-initramfs -k all -c
|
||||
if hash hardlink 2>/dev/null; then
|
||||
hardlink -t /usr/share/doc
|
||||
fi
|
||||
if [ -f /usr/lib/systemd/system/apt-listchanges.service ]; then
|
||||
python3 -m apt_listchanges.populate_database --profile apt
|
||||
systemctl disable apt-listchanges.timer
|
||||
fi
|
||||
install -m 755 -o systemd-timesync -g systemd-timesync -d /var/lib/systemd/timesync
|
||||
install -m 644 -o systemd-timesync -g systemd-timesync /dev/null /var/lib/systemd/timesync/clock
|
||||
EOF
|
||||
|
||||
rm -f "${ROOTFS_DIR}/usr/bin/qemu-arm-static"
|
||||
|
||||
if [ "${USE_QEMU}" != "1" ]; then
|
||||
if [ -e "${ROOTFS_DIR}/etc/ld.so.preload.disabled" ]; then
|
||||
mv "${ROOTFS_DIR}/etc/ld.so.preload.disabled" "${ROOTFS_DIR}/etc/ld.so.preload"
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f "${ROOTFS_DIR}/etc/network/interfaces.dpkg-old"
|
||||
rm -f "${ROOTFS_DIR}/etc/apt/sources.list~"
|
||||
rm -f "${ROOTFS_DIR}/etc/apt/trusted.gpg~"
|
||||
rm -f "${ROOTFS_DIR}/etc/passwd-"
|
||||
rm -f "${ROOTFS_DIR}/etc/group-"
|
||||
rm -f "${ROOTFS_DIR}/etc/shadow-"
|
||||
rm -f "${ROOTFS_DIR}/etc/gshadow-"
|
||||
rm -f "${ROOTFS_DIR}/etc/subuid-"
|
||||
rm -f "${ROOTFS_DIR}/etc/subgid-"
|
||||
rm -f "${ROOTFS_DIR}"/var/cache/debconf/*-old
|
||||
rm -f "${ROOTFS_DIR}"/var/lib/dpkg/*-old
|
||||
rm -f "${ROOTFS_DIR}"/usr/share/icons/*/icon-theme.cache
|
||||
rm -f "${ROOTFS_DIR}/var/lib/dbus/machine-id"
|
||||
|
||||
echo "uninitialized" > "${ROOTFS_DIR}/etc/machine-id"
|
||||
|
||||
ln -nsf /proc/mounts "${ROOTFS_DIR}/etc/mtab"
|
||||
|
||||
find "${ROOTFS_DIR}/var/log/" -type f -exec cp /dev/null {} \;
|
||||
14
exports/squashfs/03-finalise/files/9999-vesperos-dconf
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
# Runs at live boot only. Sets DCONF_PROFILE=live for the live user
|
||||
# so the live dconf database is used instead of the installed default.
|
||||
|
||||
# Source live-config variables (provides LIVE_USERNAME etc.)
|
||||
. /etc/live/config.conf 2>/dev/null || true
|
||||
LIVE_USER="${LIVE_USERNAME:-vesperos}"
|
||||
LIVE_HOME="/home/${LIVE_USER}"
|
||||
|
||||
if [ -d "${LIVE_HOME}" ]; then
|
||||
mkdir -p "${LIVE_HOME}/.config/environment.d"
|
||||
echo 'DCONF_PROFILE=live' > "${LIVE_HOME}/.config/environment.d/dconf.conf"
|
||||
chown -R "${LIVE_USER}:${LIVE_USER}" "${LIVE_HOME}/.config"
|
||||
fi
|
||||
@@ -0,0 +1,3 @@
|
||||
user-db:user
|
||||
system-db:live
|
||||
system-db:local
|
||||
4
exports/squashfs/03-finalise/files/live-default-settings
Normal file
@@ -0,0 +1,4 @@
|
||||
#[org/gnome/desktop/background]
|
||||
#picture-uri='file:///usr/share/backgrounds/vesperos-live.png'
|
||||
#picture-uri-dark='file:///usr/share/backgrounds/vesperos-live.png'
|
||||
#picture-options='zoom'
|
||||
222
exports/squashfs/04-export/01-run.sh
Executable file
@@ -0,0 +1,222 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
SQUASHFS_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.squashfs"
|
||||
|
||||
unmount "${ROOTFS_DIR}"
|
||||
|
||||
# ── 1. Raw squashfs ────────────────────────────────────────────────────────────
|
||||
mksquashfs "${ROOTFS_DIR}" "${SQUASHFS_FILE}" \
|
||||
-comp xz \
|
||||
-noappend \
|
||||
-e boot/efi
|
||||
|
||||
# Locate kernel and initrd inside the rootfs
|
||||
VMLINUZ=$(find "${ROOTFS_DIR}/boot" -maxdepth 1 -name "vmlinuz-*" | sort | tail -1)
|
||||
INITRD=$(find "${ROOTFS_DIR}/boot" -maxdepth 1 -name "initrd.img-*" | sort | tail -1)
|
||||
|
||||
VMLINUZ_FILE=""
|
||||
INITRD_FILE=""
|
||||
|
||||
if [ -n "${VMLINUZ}" ]; then
|
||||
VMLINUZ_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.vmlinuz"
|
||||
cp "${VMLINUZ}" "${VMLINUZ_FILE}"
|
||||
fi
|
||||
|
||||
if [ -n "${INITRD}" ]; then
|
||||
INITRD_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.initrd"
|
||||
cp "${INITRD}" "${INITRD_FILE}"
|
||||
fi
|
||||
|
||||
mkdir -p "${DEPLOY_DIR}"
|
||||
rm -f "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}."*
|
||||
|
||||
case "${DEPLOY_COMPRESSION}" in
|
||||
zip)
|
||||
pushd "${STAGE_WORK_DIR}" > /dev/null
|
||||
ZIP_MEMBERS="$(basename "${SQUASHFS_FILE}")"
|
||||
[ -n "${VMLINUZ_FILE}" ] && ZIP_MEMBERS="${ZIP_MEMBERS} $(basename "${VMLINUZ_FILE}")"
|
||||
[ -n "${INITRD_FILE}" ] && ZIP_MEMBERS="${ZIP_MEMBERS} $(basename "${INITRD_FILE}")"
|
||||
# shellcheck disable=SC2086
|
||||
zip -"${COMPRESSION_LEVEL}" \
|
||||
"${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.zip" \
|
||||
${ZIP_MEMBERS}
|
||||
popd > /dev/null
|
||||
echo "Archive created at ${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.zip"
|
||||
;;
|
||||
gz)
|
||||
pigz --force -"${COMPRESSION_LEVEL}" "${SQUASHFS_FILE}" --stdout > \
|
||||
"${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.squashfs.gz"
|
||||
[ -n "${VMLINUZ_FILE}" ] && cp "${VMLINUZ_FILE}" "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.vmlinuz"
|
||||
[ -n "${INITRD_FILE}" ] && cp "${INITRD_FILE}" "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.initrd"
|
||||
echo "Squashfs exported at ${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.squashfs.gz"
|
||||
;;
|
||||
xz)
|
||||
xz --compress --force --threads 0 --memlimit-compress=50% -"${COMPRESSION_LEVEL}" \
|
||||
--stdout "${SQUASHFS_FILE}" > "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.squashfs.xz"
|
||||
[ -n "${VMLINUZ_FILE}" ] && cp "${VMLINUZ_FILE}" "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.vmlinuz"
|
||||
[ -n "${INITRD_FILE}" ] && cp "${INITRD_FILE}" "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.initrd"
|
||||
echo "Squashfs exported at ${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.squashfs.xz"
|
||||
;;
|
||||
none | *)
|
||||
cp "${SQUASHFS_FILE}" "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.squashfs"
|
||||
[ -n "${VMLINUZ_FILE}" ] && cp "${VMLINUZ_FILE}" "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.vmlinuz"
|
||||
[ -n "${INITRD_FILE}" ] && cp "${INITRD_FILE}" "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.initrd"
|
||||
echo "Squashfs exported at ${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.squashfs"
|
||||
;;
|
||||
esac
|
||||
|
||||
# ── 2. Liveboot squashfs (only when LIVEBOOT=1 and amd64) ──────────────────────
|
||||
if [ "${LIVEBOOT}" == "1" ]; then
|
||||
if [ "${ARCH}" != "amd64" ]; then
|
||||
echo "squashfs-export: skipping live boot squashfs for non-amd64 arch (${ARCH})"
|
||||
else
|
||||
echo "squashfs-export: applying live boot changes for liveboot squashfs"
|
||||
|
||||
on_chroot << EOF
|
||||
apt-get install -y \
|
||||
live-boot \
|
||||
live-boot-initramfs-tools \
|
||||
live-config \
|
||||
live-config-systemd
|
||||
EOF
|
||||
|
||||
# Write live-config user settings
|
||||
mkdir -p "${ROOTFS_DIR}/etc/live"
|
||||
cat > "${ROOTFS_DIR}/etc/live/config.conf" << EOF
|
||||
LIVE_USERNAME="${LIVE_USERNAME:-vesperos}"
|
||||
LIVE_USER_FULLNAME="${LIVE_USER_FULLNAME:-Live User}"
|
||||
LIVE_USER_DEFAULT_GROUPS="audio cdrom dip floppy video plugdev netdev bluetooth"
|
||||
LIVE_USER_SHELL="/bin/zsh"
|
||||
LIVE_USER_PASSWORD="${LIVE_USER_PASSWORD:-vesperos}"
|
||||
LIVE_LOGIN="true"
|
||||
EOF
|
||||
|
||||
# Rewrite fstab for the live environment.
|
||||
# live-boot manages root via overlayfs — build-time disk entries cause fsck failures at boot.
|
||||
cat > "${ROOTFS_DIR}/etc/fstab" << 'FSTABEOF'
|
||||
# Live system fstab — root is managed by live-boot via overlayfs, not this file.
|
||||
tmpfs /tmp tmpfs defaults,nosuid,nodev 0 0
|
||||
FSTABEOF
|
||||
|
||||
# Remove first-boot trigger so GDM uses autologin in the live session.
|
||||
rm -f "${ROOTFS_DIR}/var/lib/gdm/run-initial-setup"
|
||||
|
||||
# Make GDM wait for live-config
|
||||
mkdir -p "${ROOTFS_DIR}/etc/systemd/system/gdm.service.d"
|
||||
cat > "${ROOTFS_DIR}/etc/systemd/system/gdm.service.d/override.conf" << EOF
|
||||
[Unit]
|
||||
After=live-config.service
|
||||
EOF
|
||||
|
||||
# Enable autoLogin on GDM
|
||||
mkdir -p "${ROOTFS_DIR}/etc/gdm3"
|
||||
cat > "${ROOTFS_DIR}/etc/gdm3/daemon.conf" << EOF
|
||||
[daemon]
|
||||
AutomaticLoginEnable=true
|
||||
AutomaticLogin=${LIVE_USERNAME:-vesperos}
|
||||
EOF
|
||||
|
||||
# Configure initramfs for live boot — squashfs and overlay are required
|
||||
if [ -f "${ROOTFS_DIR}/etc/initramfs-tools/initramfs.conf" ]; then
|
||||
sed -i 's/^MODULES=.*/MODULES=most/' "${ROOTFS_DIR}/etc/initramfs-tools/initramfs.conf"
|
||||
fi
|
||||
|
||||
for mod in squashfs overlay; do
|
||||
grep -qx "${mod}" "${ROOTFS_DIR}/etc/initramfs-tools/modules" 2>/dev/null || \
|
||||
echo "${mod}" >> "${ROOTFS_DIR}/etc/initramfs-tools/modules"
|
||||
done
|
||||
|
||||
# Enable live-config system wide, instead of via grub
|
||||
on_chroot << EOF
|
||||
systemctl enable live-config.service
|
||||
EOF
|
||||
|
||||
# Live-only dconf: separate database + profile so the live wallpaper
|
||||
# is shown in the live session but not on the real installed system.
|
||||
FINALISE_DIR="$(dirname "$0")/../03-finalise"
|
||||
mkdir -p "${ROOTFS_DIR}/etc/dconf/db/live.d"
|
||||
install -m 644 "${FINALISE_DIR}/files/live-default-settings" "${ROOTFS_DIR}/etc/dconf/db/live.d/00-default-settings"
|
||||
install -m 644 "${FINALISE_DIR}/files/dconf-profile-live-user" "${ROOTFS_DIR}/etc/dconf/profile/live"
|
||||
|
||||
# Hook sets DCONF_PROFILE=live for the live user at boot
|
||||
install -m 755 "${FINALISE_DIR}/files/9999-vesperos-dconf" "${ROOTFS_DIR}/lib/live/config/9999-vesperos-dconf"
|
||||
|
||||
on_chroot << EOF
|
||||
dconf update
|
||||
EOF
|
||||
|
||||
# Add calamares installer and related packages to the live image
|
||||
on_chroot << EOF
|
||||
apt-get install -y calamares calamares-settings-vesperos \
|
||||
libcrack2 cracklib-runtime \
|
||||
grub-efi-amd64 grub-pc-bin efibootmgr \
|
||||
parted gdisk dosfstools e2fsprogs
|
||||
EOF
|
||||
|
||||
# Set quiet splash after grub installs its default /etc/default/grub
|
||||
sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"/' \
|
||||
"${ROOTFS_DIR}/etc/default/grub"
|
||||
|
||||
# Keep the graphical framebuffer so Plymouth can render its splash.
|
||||
# Without this, GRUB switches to text mode before handing off to the kernel
|
||||
# and Plymouth falls back to a hidden/text renderer, showing nothing.
|
||||
grep -q 'GRUB_GFXPAYLOAD_LINUX' "${ROOTFS_DIR}/etc/default/grub" || \
|
||||
echo 'GRUB_GFXPAYLOAD_LINUX=keep' >> "${ROOTFS_DIR}/etc/default/grub"
|
||||
|
||||
# Rebuild initramfs with live-boot modules
|
||||
on_chroot << EOF
|
||||
update-initramfs -k all -u
|
||||
EOF
|
||||
|
||||
LIVE_SQUASHFS_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}-live.squashfs"
|
||||
|
||||
unmount "${ROOTFS_DIR}"
|
||||
|
||||
mksquashfs "${ROOTFS_DIR}" "${LIVE_SQUASHFS_FILE}" \
|
||||
-comp xz \
|
||||
-noappend \
|
||||
-e boot/efi
|
||||
|
||||
# Locate updated kernel/initrd for liveboot
|
||||
LIVE_VMLINUZ=$(find "${ROOTFS_DIR}/boot" -maxdepth 1 -name "vmlinuz-*" | sort | tail -1)
|
||||
LIVE_INITRD=$(find "${ROOTFS_DIR}/boot" -maxdepth 1 -name "initrd.img-*" | sort | tail -1)
|
||||
|
||||
case "${DEPLOY_COMPRESSION}" in
|
||||
zip)
|
||||
pushd "${STAGE_WORK_DIR}" > /dev/null
|
||||
LIVE_ZIP_MEMBERS="$(basename "${LIVE_SQUASHFS_FILE}")"
|
||||
# shellcheck disable=SC2086
|
||||
zip -"${COMPRESSION_LEVEL}" \
|
||||
"${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}-live.zip" \
|
||||
${LIVE_ZIP_MEMBERS}
|
||||
popd > /dev/null
|
||||
echo "Live archive created at ${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}-live.zip"
|
||||
;;
|
||||
gz)
|
||||
pigz --force -"${COMPRESSION_LEVEL}" "${LIVE_SQUASHFS_FILE}" --stdout > \
|
||||
"${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}-live.squashfs.gz"
|
||||
echo "Live squashfs exported at ${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}-live.squashfs.gz"
|
||||
;;
|
||||
xz)
|
||||
xz --compress --force --threads 0 --memlimit-compress=50% -"${COMPRESSION_LEVEL}" \
|
||||
--stdout "${LIVE_SQUASHFS_FILE}" > "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}-live.squashfs.xz"
|
||||
echo "Live squashfs exported at ${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}-live.squashfs.xz"
|
||||
;;
|
||||
none | *)
|
||||
cp "${LIVE_SQUASHFS_FILE}" "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}-live.squashfs"
|
||||
echo "Live squashfs exported at ${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}-live.squashfs"
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -n "${LIVE_VMLINUZ}" ] && cp "${LIVE_VMLINUZ}" "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}-live.vmlinuz"
|
||||
[ -n "${LIVE_INITRD}" ] && cp "${LIVE_INITRD}" "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}-live.initrd"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
#rm -f "${SQUASHFS_FILE}"
|
||||
#[ -n "${VMLINUZ_FILE}" ] && rm -f "${VMLINUZ_FILE}"
|
||||
#[ -n "${INITRD_FILE}" ] && rm -f "${INITRD_FILE}"
|
||||
|
||||
# cleanup stage work dir
|
||||
#rm -rf "${STAGE_WORK_DIR}"
|
||||
6
exports/squashfs/prerun.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
rm -rf "${ROOTFS_DIR}"
|
||||
mkdir -p "${ROOTFS_DIR}"
|
||||
|
||||
rsync -aHAXx --exclude /var/cache/apt/archives "${EXPORT_ROOTFS_DIR}/" "${ROOTFS_DIR}/"
|
||||
@@ -17,7 +17,10 @@ bootstrap(){
|
||||
BOOTSTRAP_ARGS+=("$@")
|
||||
printf -v BOOTSTRAP_STR '%q ' "${BOOTSTRAP_ARGS[@]}"
|
||||
|
||||
capsh $CAPSH_ARG -- -c "'${BOOTSTRAP_CMD}' $BOOTSTRAP_STR" || true
|
||||
setarch linux32 capsh $CAPSH_ARG -- -c "'${BOOTSTRAP_CMD}' $BOOTSTRAP_STR" || true
|
||||
|
||||
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1050719
|
||||
rm -f wget-log*
|
||||
|
||||
if [ -d "$2/debootstrap" ] && ! rmdir "$2/debootstrap"; then
|
||||
cp "$2/debootstrap/debootstrap.log" "${STAGE_WORK_DIR}"
|
||||
@@ -131,4 +134,4 @@ ensure_loopdev_partitions() {
|
||||
command -v udevadm >/dev/null 2>&1 || return 0
|
||||
udevadm settle 10
|
||||
}
|
||||
export -f ensure_loopdev_partitions
|
||||
export -f ensure_loopdev_partitions
|
||||
@@ -1,16 +1,26 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# Configure apt sources
|
||||
install -m 644 files/sources.list "${ROOTFS_DIR}/etc/apt/"
|
||||
sed -i "s/RELEASE/${RELEASE}/g" "${ROOTFS_DIR}/etc/apt/sources.list"
|
||||
true > "${ROOTFS_DIR}/etc/apt/sources.list"
|
||||
|
||||
if [[ "${ARCH}" == "arm64" || "${ARCH}" == "armhf" ]]; then
|
||||
install -m 644 files/raspi.list "${ROOTFS_DIR}/etc/apt/sources.list.d/"
|
||||
sed -i "s/RELEASE/${RELEASE}/g" "${ROOTFS_DIR}/etc/apt/sources.list.d/raspi.list"
|
||||
# Add APT Sources
|
||||
if [ "${PLATFORM}" == "rpi" ]; then
|
||||
# On rpi platforms add rpi sources
|
||||
install -m 644 files/raspbian.sources "${ROOTFS_DIR}/etc/apt/sources.list.d/"
|
||||
install -m 644 files/raspi.sources "${ROOTFS_DIR}/etc/apt/sources.list.d/"
|
||||
sed -i "s/RELEASE/${RELEASE}/g" "${ROOTFS_DIR}/etc/apt/sources.list.d/raspbian.sources"
|
||||
sed -i "s/RELEASE/${RELEASE}/g" "${ROOTFS_DIR}/etc/apt/sources.list.d/raspi.sources"
|
||||
install -m 644 files/raspberrypi-archive-keyring.pgp "${ROOTFS_DIR}/usr/share/keyrings/"
|
||||
fi
|
||||
|
||||
install -m 644 files/oxmc.list "${ROOTFS_DIR}/etc/apt/sources.list.d/"
|
||||
sed -i "s/RELEASE/${RELEASE}/g" "${ROOTFS_DIR}/etc/apt/sources.list.d/oxmc.list"
|
||||
# Add default debian sources until oxmc creates a mirror for debian sources
|
||||
install -m 644 files/debian.sources "${ROOTFS_DIR}/etc/apt/sources.list.d/"
|
||||
sed -i "s/RELEASE/${RELEASE}/g" "${ROOTFS_DIR}/etc/apt/sources.list.d/debian.sources"
|
||||
|
||||
# Configure vesperos apt sources
|
||||
install -m 644 files/vesperos.sources "${ROOTFS_DIR}/etc/apt/sources.list.d/"
|
||||
sed -i "s/RELEASE/${RELEASE}/g" "${ROOTFS_DIR}/etc/apt/sources.list.d/vesperos.sources"
|
||||
install -m 644 files/vesperos.gpg "${ROOTFS_DIR}/usr/share/keyrings/"
|
||||
|
||||
# Configure apt proxy
|
||||
if [ -n "$APT_PROXY" ]; then
|
||||
@@ -20,6 +30,7 @@ else
|
||||
rm -f "${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache"
|
||||
fi
|
||||
|
||||
# Add temp repo if provided
|
||||
if [ -n "$TEMP_REPO" ]; then
|
||||
install -m 644 /dev/null "${ROOTFS_DIR}/etc/apt/sources.list.d/00-temp.list"
|
||||
echo "$TEMP_REPO" | sed "s/RELEASE/$RELEASE/g" > "${ROOTFS_DIR}/etc/apt/sources.list.d/00-temp.list"
|
||||
@@ -28,26 +39,30 @@ else
|
||||
fi
|
||||
|
||||
# Configure apt preferences
|
||||
install -m 644 files/apt-chillcraftos-prefs "${ROOTFS_DIR}/etc/apt/preferences.d/"
|
||||
install -m 644 files/apt-vesperos-prefs "${ROOTFS_DIR}/etc/apt/preferences.d/"
|
||||
sed -i "s/RELEASE/${RELEASE}/g" "${ROOTFS_DIR}/etc/apt/preferences.d/apt-vesperos-prefs"
|
||||
|
||||
if [[ "${ARCH}" == "arm64" || "${ARCH}" == "armhf" ]]; then
|
||||
# Add raspberrypi-archive-keyring to apt
|
||||
cat files/raspberrypi.gpg.key | gpg --dearmor > "${STAGE_WORK_DIR}/raspberrypi-archive-stable.gpg"
|
||||
install -m 644 "${STAGE_WORK_DIR}/raspberrypi-archive-stable.gpg" "${ROOTFS_DIR}/etc/apt/trusted.gpg.d/"
|
||||
fi
|
||||
|
||||
# Add oxmc-archive-keyring to apt
|
||||
cat files/oxmc.gpg.key | gpg --dearmor > "${STAGE_WORK_DIR}/oxmc.gpg"
|
||||
install -m 644 "${STAGE_WORK_DIR}/oxmc.gpg" "${ROOTFS_DIR}/etc/apt/trusted.gpg.d/"
|
||||
|
||||
# Add armhf and arm64 architectures, update and upgrade and cache policy
|
||||
# Add additional architectures if needed, update and upgrade and cache policy
|
||||
on_chroot <<- \EOF
|
||||
SYSTEM_ARCH="$(dpkg --print-architecture)"
|
||||
if [ "$SYSTEM_ARCH" = "armhf" ]; then
|
||||
dpkg --add-architecture arm64
|
||||
elif [ "$SYSTEM_ARCH" = "arm64" ]; then
|
||||
dpkg --add-architecture armhf
|
||||
|
||||
# If we're building for rpi, we want to add both armhf and arm64 architectures to allow installing packages from both architectures
|
||||
if [ "${PLATFORM}" == "rpi" ]; then
|
||||
if [ "$SYSTEM_ARCH" = "armhf" ]; then
|
||||
dpkg --add-architecture arm64
|
||||
elif [ "$SYSTEM_ARCH" = "arm64" ]; then
|
||||
dpkg --add-architecture armhf
|
||||
fi
|
||||
fi
|
||||
|
||||
# If we're building for amd64, we want to add i386 architecture to allow installing packages from both architectures
|
||||
if [ "$SYSTEM_ARCH" = "amd64" ]; then
|
||||
dpkg --add-architecture i386
|
||||
elif [ "$SYSTEM_ARCH" = "i386" ]; then
|
||||
dpkg --add-architecture amd64
|
||||
fi
|
||||
|
||||
# Update and upgrade packages and show cache policy
|
||||
apt-get update
|
||||
apt-get dist-upgrade -y
|
||||
apt-cache policy
|
||||
|
||||
@@ -1 +1 @@
|
||||
raspberrypi-archive-keyring
|
||||
tailscale-repo
|
||||
|
||||
1
stage0/00-configure-apt/01-packages-arm-only
Normal file
@@ -0,0 +1 @@
|
||||
raspberrypi-archive-keyring
|
||||
@@ -1,3 +0,0 @@
|
||||
Package: *
|
||||
Pin: release o=apt.oxmc.me, n=bookworm
|
||||
Pin-Priority: 1001
|
||||
3
stage0/00-configure-apt/files/apt-vesperos-prefs
Normal file
@@ -0,0 +1,3 @@
|
||||
Package: *
|
||||
Pin: release o=apt.oxmc.me, n=RELEASE
|
||||
Pin-Priority: 1001
|
||||
11
stage0/00-configure-apt/files/debian.sources
Normal file
@@ -0,0 +1,11 @@
|
||||
Types: deb
|
||||
URIs: https://deb.debian.org/debian
|
||||
Suites: RELEASE RELEASE-updates
|
||||
Components: main contrib non-free non-free-firmware
|
||||
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
|
||||
|
||||
Types: deb
|
||||
URIs: https://security.debian.org/debian-security
|
||||
Suites: RELEASE-security
|
||||
Components: main contrib non-free non-free-firmware
|
||||
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
|
||||
@@ -1,3 +0,0 @@
|
||||
deb https://cdn.oxmc.me/apt RELEASE main
|
||||
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
|
||||
#deb-src https://cdn.oxmc.me/apt RELEASE main
|
||||
BIN
stage0/00-configure-apt/files/raspberrypi-archive-keyring.pgp
Normal file
@@ -1,30 +0,0 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.12 (GNU/Linux)
|
||||
|
||||
mQENBE/d7o8BCACrwqQacGJfn3tnMzGui6mv2lLxYbsOuy/+U4rqMmGEuo3h9m92
|
||||
30E2EtypsoWczkBretzLUCFv+VUOxaA6sV9+puTqYGhhQZFuKUWcG7orf7QbZRuu
|
||||
TxsEUepW5lg7MExmAu1JJzqM0kMQX8fVyWVDkjchZ/is4q3BPOUCJbUJOsE+kK/6
|
||||
8kW6nWdhwSAjfDh06bA5wvoXNjYoDdnSZyVdcYCPEJXEg5jfF/+nmiFKMZBraHwn
|
||||
eQsepr7rBXxNcEvDlSOPal11fg90KXpy7Umre1UcAZYJdQeWcHu7X5uoJx/MG5J8
|
||||
ic6CwYmDaShIFa92f8qmFcna05+lppk76fsnABEBAAG0IFJhc3BiZXJyeSBQaSBB
|
||||
cmNoaXZlIFNpZ25pbmcgS2V5iQE4BBMBAgAiBQJP3e6PAhsDBgsJCAcDAgYVCAIJ
|
||||
CgsEFgIDAQIeAQIXgAAKCRCCsSmSf6MwPk6vB/9pePB3IukU9WC9Bammh3mpQTvL
|
||||
OifbkzHkmAYxzjfK6D2I8pT0xMxy949+ThzJ7uL60p6T/32ED9DR3LHIMXZvKtuc
|
||||
mQnSiNDX03E2p7lIP/htoxW2hDP2n8cdlNdt0M9IjaWBppsbO7IrDppG2B1aRLni
|
||||
uD7v8bHRL2mKTtIDLX42Enl8aLAkJYgNWpZyPkDyOqamjijarIWjGEPCkaURF7g4
|
||||
d44HvYhpbLMOrz1m6N5Bzoa5+nq3lmifeiWKxioFXU+Hy5bhtAM6ljVb59hbD2ra
|
||||
X4+3LXC9oox2flmQnyqwoyfZqVgSQa0B41qEQo8t1bz6Q1Ti7fbMLThmbRHiuQEN
|
||||
BE/d7o8BCADNlVtBZU63fm79SjHh5AEKFs0C3kwa0mOhp9oas/haDggmhiXdzeD3
|
||||
49JWz9ZTx+vlTq0s+I+nIR1a+q+GL+hxYt4HhxoA6vlDMegVfvZKzqTX9Nr2VqQa
|
||||
S4Kz3W5ULv81tw3WowK6i0L7pqDmvDqgm73mMbbxfHD0SyTt8+fk7qX6Ag2pZ4a9
|
||||
ZdJGxvASkh0McGpbYJhk1WYD+eh4fqH3IaeJi6xtNoRdc5YXuzILnp+KaJyPE5CR
|
||||
qUY5JibOD3qR7zDjP0ueP93jLqmoKltCdN5+yYEExtSwz5lXniiYOJp8LWFCgv5h
|
||||
m8aYXkcJS1xVV9Ltno23YvX5edw9QY4hABEBAAGJAR8EGAECAAkFAk/d7o8CGwwA
|
||||
CgkQgrEpkn+jMD5Figf/dIC1qtDMTbu5IsI5uZPX63xydaExQNYf98cq5H2fWF6O
|
||||
yVR7ERzA2w33hI0yZQrqO6pU9SRnHRxCFvGv6y+mXXXMRcmjZG7GiD6tQWeN/3wb
|
||||
EbAn5cg6CJ/Lk/BI4iRRfBX07LbYULCohlGkwBOkRo10T+Ld4vCCnBftCh5x2OtZ
|
||||
TOWRULxP36y2PLGVNF+q9pho98qx+RIxvpofQM/842ZycjPJvzgVQsW4LT91KYAE
|
||||
4TVf6JjwUM6HZDoiNcX6d7zOhNfQihXTsniZZ6rky287htsWVDNkqOi5T3oTxWUo
|
||||
m++/7s3K3L0zWopdhMVcgg6Nt9gcjzqN1c0gy55L/g==
|
||||
=mNSj
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
8
stage0/00-configure-apt/files/raspbian.sources
Normal file
@@ -0,0 +1,8 @@
|
||||
Types: deb
|
||||
URIs: http://raspbian.raspberrypi.com/raspbian/
|
||||
Architectures: armhf
|
||||
Suites: RELEASE
|
||||
Components: main contrib non-free rpi
|
||||
Signed-By: /usr/share/keyrings/raspbian-archive-keyring.pgp
|
||||
# TODO: Remove Trusted once Raspbian reissues their key with SHA256+ (SHA1 rejected by sqv since 2026-02-01)
|
||||
Trusted: yes
|
||||
@@ -1,3 +0,0 @@
|
||||
deb http://archive.raspberrypi.com/debian/ RELEASE main
|
||||
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
|
||||
#deb-src http://archive.raspberrypi.com/debian/ RELEASE main
|
||||
5
stage0/00-configure-apt/files/raspi.sources
Normal file
@@ -0,0 +1,5 @@
|
||||
Types: deb
|
||||
URIs: http://archive.raspberrypi.com/debian/
|
||||
Suites: RELEASE
|
||||
Components: main
|
||||
Signed-By: /usr/share/keyrings/raspberrypi-archive-keyring.pgp
|
||||
@@ -1,7 +0,0 @@
|
||||
deb http://deb.debian.org/debian RELEASE main contrib non-free non-free-firmware
|
||||
deb http://deb.debian.org/debian-security/ RELEASE-security main contrib non-free non-free-firmware
|
||||
deb http://deb.debian.org/debian RELEASE-updates main contrib non-free non-free-firmware
|
||||
# Uncomment deb-src lines below then 'apt-get update' to enable 'apt-get source'
|
||||
#deb-src http://deb.debian.org/debian RELEASE main contrib non-free non-free-firmware
|
||||
#deb-src http://deb.debian.org/debian-security/ RELEASE-security main contrib non-free non-free-firmware
|
||||
#deb-src http://deb.debian.org/debian RELEASE-updates main contrib non-free non-free-firmware
|
||||
5
stage0/00-configure-apt/files/vesperos.sources
Normal file
@@ -0,0 +1,5 @@
|
||||
Types: deb
|
||||
URIs: https://apt.oxmc.me/vesperos
|
||||
Suites: RELEASE
|
||||
Components: main
|
||||
Signed-By: /usr/share/keyrings/vesperos.gpg
|
||||
0
stage0/01-locale/00-run.sh
Normal file → Executable file
@@ -1 +1 @@
|
||||
grub2
|
||||
linux-image-amd64
|
||||
0
stage1/00-boot-files/00-run-arm-only.sh → stage1/00-boot-files/00-run-rpi-only.sh
Executable file → Normal file
@@ -1 +1 @@
|
||||
console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 fsck.repair=yes rootwait
|
||||
console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 fsck.repair=yes rootwait resize
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/rootfs/etc/skel/.bashrc
|
||||
+++ b/rootfs/etc/skel/.bashrc
|
||||
@@ -43,7 +43,7 @@
|
||||
--- stage1.orig/rootfs/etc/skel/.bashrc
|
||||
+++ stage1/rootfs/etc/skel/.bashrc
|
||||
@@ -43,7 +43,7 @@ esac
|
||||
# uncomment for a colored prompt, if the terminal has the capability; turned
|
||||
# off by default to not distract the user: the focus in a terminal window
|
||||
# should be on the output of commands, not on the prompt
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
if [ -n "$force_color_prompt" ]; then
|
||||
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
|
||||
@@ -57,7 +57,7 @@
|
||||
@@ -57,7 +57,7 @@ if [ -n "$force_color_prompt" ]; then
|
||||
fi
|
||||
|
||||
if [ "$color_prompt" = yes ]; then
|
||||
@@ -18,7 +18,7 @@
|
||||
else
|
||||
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
|
||||
fi
|
||||
@@ -79,9 +79,9 @@
|
||||
@@ -79,9 +79,9 @@ if [ -x /usr/bin/dircolors ]; then
|
||||
#alias dir='dir --color=auto'
|
||||
#alias vdir='vdir --color=auto'
|
||||
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
install -v -m 644 files/fstab "${ROOTFS_DIR}/etc/fstab"
|
||||
# SteamOS like readonly root
|
||||
install -m 755 files/system-readonly "${ROOTFS_DIR}/sbin/"
|
||||
|
||||
on_chroot << EOF
|
||||
if ! id -u ${FIRST_USER_NAME} >/dev/null 2>&1; then
|
||||
#adduser --disabled-password --gecos "" ${FIRST_USER_NAME}
|
||||
if [ "${FIRST_USER_ISSYSTEM}" = "true" ]; then
|
||||
useradd -r -M -d / ${FIRST_USER_NAME}
|
||||
else
|
||||
adduser --disabled-password --gecos "" ${FIRST_USER_NAME}
|
||||
fi
|
||||
if [ "${PLATFORM}" == "rpi" ]; then
|
||||
install -m 644 files/fstab-rpi "${ROOTFS_DIR}/etc/fstab"
|
||||
else
|
||||
install -m 644 files/fstab "${ROOTFS_DIR}/etc/fstab"
|
||||
fi
|
||||
|
||||
# Create system user and set root password
|
||||
on_chroot << EOF
|
||||
useradd -r -M -d / system
|
||||
echo "root:root" | chpasswd
|
||||
EOF
|
||||
EOF
|
||||
@@ -1,3 +1,7 @@
|
||||
proc /proc proc defaults 0 0
|
||||
BOOTDEV /boot/firmware vfat defaults 0 2
|
||||
ROOTDEV / ext4 defaults,noatime 0 1
|
||||
proc /proc proc defaults 0 0
|
||||
BOOTDEV /boot vfat defaults 0 2
|
||||
EFIDEV /boot/efi vfat defaults 0 2
|
||||
ROOTDEV / btrfs defaults,noatime,compress=zstd,subvol=@ 0 1
|
||||
ROOTDEV /home btrfs defaults,noatime,compress=zstd,subvol=@home 0 2
|
||||
ROOTDEV /var btrfs defaults,noatime,compress=zstd,subvol=@var 0 2
|
||||
ROOTDEV /.snapshots btrfs defaults,noatime,compress=zstd,subvol=@snapshots 0 2
|
||||
|
||||
6
stage1/01-sys-tweaks/files/fstab-rpi
Normal file
@@ -0,0 +1,6 @@
|
||||
proc /proc proc defaults 0 0
|
||||
BOOTDEV /boot/firmware vfat defaults 0 2
|
||||
ROOTDEV / btrfs defaults,noatime,compress=zstd,subvol=@ 0 1
|
||||
ROOTDEV /home btrfs defaults,noatime,compress=zstd,subvol=@home 0 2
|
||||
ROOTDEV /var btrfs defaults,noatime,compress=zstd,subvol=@var 0 2
|
||||
ROOTDEV /.snapshots btrfs defaults,noatime,compress=zstd,subvol=@snapshots 0 2
|
||||
@@ -1,30 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
FSTAB_FILE="/etc/fstab"
|
||||
set -e
|
||||
|
||||
if [ "$1" == "enable" ]; then
|
||||
echo "Enabling read-only mode..."
|
||||
SUBVOL="/"
|
||||
|
||||
# Modify fstab to set root filesystem as read-only
|
||||
sudo sed -i 's|\(PARTUUID=[^ ]* / .* ext4 \)defaults,noatime|\1ro,noatime|' "$FSTAB_FILE"
|
||||
|
||||
# Remount root as read-only
|
||||
sudo mount -o remount,ro /
|
||||
|
||||
echo "System is now read-only. Reboot for changes to persist."
|
||||
|
||||
elif [ "$1" == "disable" ]; then
|
||||
echo "Disabling read-only mode..."
|
||||
|
||||
# Modify fstab to set root filesystem as writable
|
||||
sudo sed -i 's|\(PARTUUID=[^ ]* / .* ext4 \)ro,noatime|\1defaults,noatime|' "$FSTAB_FILE"
|
||||
|
||||
# Remount root as writable
|
||||
sudo mount -o remount,rw /
|
||||
|
||||
echo "System is now writable. Reboot for changes to persist."
|
||||
|
||||
else
|
||||
echo "Usage: system-readonly enable|disable"
|
||||
usage() {
|
||||
echo "Usage: system-readonly enable|disable|status"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
enable)
|
||||
echo "Enabling read-only mode..."
|
||||
btrfs property set -ts "${SUBVOL}" ro true
|
||||
mount -o remount,ro "${SUBVOL}"
|
||||
echo "Root is read-only. Full effect on next reboot."
|
||||
;;
|
||||
disable)
|
||||
echo "Disabling read-only mode..."
|
||||
btrfs property set -ts "${SUBVOL}" ro false
|
||||
mount -o remount,rw "${SUBVOL}"
|
||||
echo "Root is writable."
|
||||
;;
|
||||
status)
|
||||
RO=$(btrfs property get -ts "${SUBVOL}" ro 2>/dev/null | awk -F= '{print $2}')
|
||||
if [ "${RO}" = "true" ]; then
|
||||
echo "Read-only: enabled"
|
||||
else
|
||||
echo "Read-only: disabled"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
on_chroot << EOF
|
||||
SUDO_USER="${FIRST_USER_NAME}" raspi-config nonint do_net_names 1
|
||||
EOF
|
||||
5
stage1/02-net-tweaks/01-run-rpi-only.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
on_chroot << EOF
|
||||
raspi-config nonint do_net_names 1
|
||||
EOF
|
||||
@@ -1,12 +1,6 @@
|
||||
# Encoding to use on the console:
|
||||
# Choices: ARMSCII-8, CP1251, CP1255, CP1256, GEORGIAN-ACADEMY, GEORGIAN-PS, IBM1133, ISIRI-3342, ISO-8859-1, ISO-8859-10, ISO-8859-11, ISO-8859-13, ISO-8859-14, ISO-8859-15, ISO-8859-16, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, KOI8-R, KOI8-U, TIS-620, UTF-8, VISCII
|
||||
console-setup console-setup/charmap47 select UTF-8
|
||||
# Character set to support:
|
||||
# Choices: . Arabic, # Armenian, # Cyrillic - KOI8-R and KOI8-U, # Cyrillic - non-Slavic languages, # Cyrillic - Slavic languages (also Bosnian and Serbian Latin), . Ethiopic, # Georgian, # Greek, # Hebrew, # Lao, # Latin1 and Latin5 - western Europe and Turkic languages, # Latin2 - central Europe and Romanian, # Latin3 and Latin8 - Chichewa; Esperanto; Irish; Maltese and Welsh, # Latin7 - Lithuanian; Latvian; Maori and Marshallese, . Latin - Vietnamese, # Thai, . Combined - Latin; Slavic Cyrillic; Hebrew; basic Arabic, . Combined - Latin; Slavic Cyrillic; Greek, . Combined - Latin; Slavic and non-Slavic Cyrillic, Guess optimal character set
|
||||
console-setup console-setup/codeset47 select Guess optimal character set
|
||||
# Font for the console:
|
||||
# Choices: Fixed, Goha, GohaClassic, Terminus, TerminusBold, TerminusBoldVGA, VGA, Do not change the boot/kernel font, Let the system select a suitable font
|
||||
console-setup console-setup/fontface47 select Do not change the boot/kernel font
|
||||
# Key to function as AltGr:
|
||||
# Choices: The default for the keyboard layout, No AltGr key, Right Alt (AltGr), Right Control, Right Logo key, Menu key, Left Alt, Left Logo key, Keypad Enter key, Both Logo keys, Both Alt keys
|
||||
keyboard-configuration keyboard-configuration/altgr select The default for the keyboard layout
|
||||
@@ -25,4 +19,4 @@ keyboard-configuration keyboard-configuration/ctrl_alt_bksp boolean true
|
||||
# Choices: English (UK), English (UK) - English (UK\, Colemak), English (UK) - English (UK\, Dvorak with UK punctuation), English (UK) - English (UK\, Dvorak), English (UK) - English (UK\, Macintosh international), English (UK) - English (UK\, Macintosh), English (UK) - English (UK\, extended WinKeys), English (UK) - English (UK\, international with dead keys), Other
|
||||
keyboard-configuration keyboard-configuration/variant select ${KEYBOARD_LAYOUT}
|
||||
# for internal use
|
||||
keyboard-configuration keyboard-configuration/optionscode string PLACEHOLDER
|
||||
keyboard-configuration keyboard-configuration/optionscode string PLACEHOLDER
|
||||
@@ -1,26 +1,24 @@
|
||||
ssh less fbset sudo psmisc strace ed ncdu
|
||||
ssh fbset sudo psmisc strace ed ncdu zsh zsh-common
|
||||
console-setup keyboard-configuration debconf-utils parted
|
||||
build-essential manpages-dev bash-completion gdb pkg-config
|
||||
btrfs-progs
|
||||
snapper
|
||||
python-is-python3
|
||||
v4l-utils
|
||||
python3-spidev
|
||||
python3-smbus2
|
||||
avahi-daemon
|
||||
bluez bluez-firmware
|
||||
lua5.1
|
||||
luajit
|
||||
ca-certificates curl
|
||||
fake-hwclock nfs-common usbutils
|
||||
curl
|
||||
usbutils
|
||||
dosfstools
|
||||
dphys-swapfile
|
||||
apt-listchanges
|
||||
apt-file
|
||||
usb-modeswitch
|
||||
libpam-chksshpwd
|
||||
libmtp-runtime
|
||||
rsync
|
||||
htop
|
||||
man-db
|
||||
policykit-1
|
||||
ssh-import-id
|
||||
ethtool
|
||||
ntfs-3g
|
||||
@@ -28,5 +26,6 @@ pciutils
|
||||
udisks2
|
||||
unzip zip p7zip-full
|
||||
file
|
||||
kms++-utils
|
||||
python3-venv
|
||||
cups
|
||||
command-not-found
|
||||
2
stage2/01-sys-tweaks/00-packages-amd64
Normal file
@@ -0,0 +1,2 @@
|
||||
qemu-guest-agent
|
||||
open-vm-tools
|
||||
@@ -1,2 +1,4 @@
|
||||
cifs-utils
|
||||
mkvtoolnix
|
||||
hyfetch
|
||||
fastfetch
|
||||
2
stage2/01-sys-tweaks/00-packages-rpi-only
Normal file
@@ -0,0 +1,2 @@
|
||||
python3-spidev
|
||||
python3-smbus2
|
||||
10
stage2/01-sys-tweaks/00-patches-amd64/02-inputrc.diff
Normal file
@@ -0,0 +1,10 @@
|
||||
--- stage2.orig/rootfs/etc/inputrc
|
||||
+++ stage2/rootfs/etc/inputrc
|
||||
@@ -59,3 +59,7 @@
|
||||
# "\e[F": end-of-line
|
||||
|
||||
$endif
|
||||
+
|
||||
+# mappings for up and down arrows search history
|
||||
+# "\e[B": history-search-forward
|
||||
+# "\e[A": history-search-backward
|
||||
1
stage2/01-sys-tweaks/00-patches-amd64/series
Normal file
@@ -0,0 +1 @@
|
||||
02-inputrc.diff
|
||||
@@ -1,5 +0,0 @@
|
||||
--- stage2.orig/rootfs/boot/firmware/cmdline.txt
|
||||
+++ stage2/rootfs/boot/firmware/cmdline.txt
|
||||
@@ -1 +1 @@
|
||||
-console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 fsck.repair=yes rootwait
|
||||
+console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 fsck.repair=yes rootwait quiet init=/usr/lib/raspberrypi-sys-mods/firstboot
|
||||
@@ -1 +0,0 @@
|
||||
01-resize-init.diff
|
||||
10
stage2/01-sys-tweaks/00-patches-rpi-only/01-inputrc.diff
Normal file
@@ -0,0 +1,10 @@
|
||||
--- stage2.orig/rootfs/etc/inputrc
|
||||
+++ stage2/rootfs/etc/inputrc
|
||||
@@ -69,3 +69,7 @@ $endif
|
||||
# "\e[F": end-of-line
|
||||
|
||||
$endif
|
||||
+
|
||||
+# mappings for up and down arrows search history
|
||||
+# "\e[B": history-search-forward
|
||||
+# "\e[A": history-search-backward
|
||||
1
stage2/01-sys-tweaks/00-patches-rpi-only/series
Normal file
@@ -0,0 +1 @@
|
||||
01-inputrc.diff
|
||||
4
stage2/01-sys-tweaks/00-patches/01-run.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# Set the default shell to zsh in the adduser configuration, so that new users created with adduser (including the live session user) will have zsh as their default shell.
|
||||
sed -i 's|^DSHELL=.*|DSHELL=/bin/zsh|' "${ROOTFS_DIR}/etc/adduser.conf"
|
||||
@@ -1,13 +1,11 @@
|
||||
Index: jessie-stage2/rootfs/etc/default/useradd
|
||||
===================================================================
|
||||
--- jessie-stage2.orig/rootfs/etc/default/useradd
|
||||
+++ jessie-stage2/rootfs/etc/default/useradd
|
||||
--- stage2.orig/rootfs/etc/default/useradd
|
||||
+++ stage2/rootfs/etc/default/useradd
|
||||
@@ -5,7 +5,7 @@
|
||||
# Similar to DHSELL in adduser. However, we use "sh" here because
|
||||
# Similar to DSHELL in adduser. However, we use "sh" here because
|
||||
# useradd is a low level utility and should be as general
|
||||
# as possible
|
||||
-SHELL=/bin/sh
|
||||
+SHELL=/bin/bash
|
||||
+SHELL=/bin/zsh
|
||||
#
|
||||
# The default group for users
|
||||
# 100=users on Debian systems
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
Index: jessie-stage2/rootfs/etc/dphys-swapfile
|
||||
===================================================================
|
||||
--- jessie-stage2.orig/rootfs/etc/dphys-swapfile
|
||||
+++ jessie-stage2/rootfs/etc/dphys-swapfile
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
# set size to absolute value, leaving empty (default) then uses computed value
|
||||
# you most likely don't want this, unless you have an special disk situation
|
||||
-#CONF_SWAPSIZE=
|
||||
+CONF_SWAPSIZE=512
|
||||
|
||||
# set size to computed value, this times RAM size, dynamically adapts,
|
||||
# guarantees that there is enough swap without wasting disk space on excess
|
||||
@@ -1,12 +0,0 @@
|
||||
Index: jessie-stage2/rootfs/etc/inputrc
|
||||
===================================================================
|
||||
--- jessie-stage2.orig/rootfs/etc/inputrc
|
||||
+++ jessie-stage2/rootfs/etc/inputrc
|
||||
@@ -65,3 +65,7 @@ $endif
|
||||
# "\e[F": end-of-line
|
||||
|
||||
$endif
|
||||
+
|
||||
+# mappings for up and down arrows search history
|
||||
+# "\e[B": history-search-forward
|
||||
+# "\e[A": history-search-backward
|
||||
21
stage2/01-sys-tweaks/00-patches/03-path.diff
Normal file
@@ -0,0 +1,21 @@
|
||||
--- stage2.orig/rootfs/etc/login.defs
|
||||
+++ stage2/rootfs/etc/login.defs
|
||||
@@ -60,7 +60,7 @@ HUSHLOGIN_FILE .hushlogin
|
||||
#
|
||||
# (they are minimal, add the rest in the shell startup files)
|
||||
ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
-ENV_PATH PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
|
||||
+ENV_PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
|
||||
|
||||
#
|
||||
# Terminal permissions for terminals after login(1).
|
||||
--- stage2.orig/rootfs/etc/profile
|
||||
+++ stage2/rootfs/etc/profile
|
||||
@@ -4,7 +4,7 @@
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
else
|
||||
- PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
|
||||
+ PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games"
|
||||
fi
|
||||
export PATH
|
||||
@@ -1,26 +0,0 @@
|
||||
Index: jessie-stage2/rootfs/etc/login.defs
|
||||
===================================================================
|
||||
--- jessie-stage2.orig/rootfs/etc/login.defs
|
||||
+++ jessie-stage2/rootfs/etc/login.defs
|
||||
@@ -100,7 +100,7 @@ HUSHLOGIN_FILE .hushlogin
|
||||
#
|
||||
# (they are minimal, add the rest in the shell startup files)
|
||||
ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
-ENV_PATH PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
|
||||
+ENV_PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
|
||||
|
||||
#
|
||||
# Terminal permissions
|
||||
Index: jessie-stage2/rootfs/etc/profile
|
||||
===================================================================
|
||||
--- jessie-stage2.orig/rootfs/etc/profile
|
||||
+++ jessie-stage2/rootfs/etc/profile
|
||||
@@ -4,7 +4,7 @@
|
||||
if [ "`id -u`" -eq 0 ]; then
|
||||
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
else
|
||||
- PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
|
||||
+ PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games"
|
||||
fi
|
||||
export PATH
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
01-useradd.diff
|
||||
02-swap.diff
|
||||
03-inputrc.diff
|
||||
04-path.diff
|
||||
03-path.diff
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
raspberrypi-sys-mods
|
||||
pi-bluetooth
|
||||
rpi-update
|
||||
rpi-eeprom
|
||||
raspi-utils
|
||||
12
stage2/01-sys-tweaks/01-packages-rpi-only
Normal file
@@ -0,0 +1,12 @@
|
||||
raspberrypi-sys-mods
|
||||
rpi-update
|
||||
rpi-eeprom
|
||||
raspi-utils
|
||||
rpi-swap rpi-loop-utils
|
||||
gpiod python3-libgpiod
|
||||
python3-gpiozero
|
||||
python3-rpi-lgpio
|
||||
rpi-keyboard-config
|
||||
rpi-keyboard-fw-update
|
||||
rpi-usb-gadget
|
||||
kms++-utils
|
||||