Package workstation tools, reuse emulator sessions, and derive build versions
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
source "$(dirname -- "${BASH_SOURCE[0]}")/lib.sh"
|
||||
[[ $# == 0 ]] || die 'Usage: tools/build-base-packages'
|
||||
cd "$FDS_ROOT"
|
||||
fds_version=$(tools/version)
|
||||
use_xbps
|
||||
check_void_pin
|
||||
mkdir -p out/logs out/packages out/manifests
|
||||
@@ -12,7 +13,7 @@ flock -n 8 || die 'Another base package build is already running'
|
||||
tools/build-fds-package
|
||||
tools/build-kernel
|
||||
tools/build-dasungd
|
||||
input="$FDS_VOID/hostdir/sources/fds-init-0.1.0"
|
||||
input="$FDS_VOID/hostdir/sources/fds-init-${fds_version}"
|
||||
if [[ -d $input ]]; then
|
||||
previous=$(mktemp -d "$FDS_ROOT/out/init-source.XXXXXX")
|
||||
mv "$input" "$previous/"
|
||||
@@ -35,7 +36,9 @@ for package in fds-dhcpcd fds-eink fds-base-files fds-init fds-base; do
|
||||
xbps_src -a aarch64 clean "$package"
|
||||
xbps_src -f -a aarch64 pkg "$package"
|
||||
) 2>&1 | tee "out/logs/xbps-$package.log"
|
||||
cp "$FDS_VOID/hostdir/binpkgs/$package-"*.aarch64.xbps out/packages/
|
||||
package_version=$fds_version
|
||||
[[ $package != fds-dhcpcd ]] || package_version=10.3.2
|
||||
tools/export-package "$FDS_VOID/hostdir/binpkgs/${package}-${package_version}_1.aarch64.xbps"
|
||||
done
|
||||
XBPS_ARCH=aarch64 xbps-rindex -fa out/packages/fds-*.aarch64.xbps
|
||||
printf 'PASS: all FDS base packages exported to out/packages/\n'
|
||||
|
||||
+6
-6
@@ -2,12 +2,13 @@
|
||||
source "$(dirname -- "${BASH_SOURCE[0]}")/lib.sh"
|
||||
[[ $# == 0 ]] || die 'Usage: tools/build-dasungd'
|
||||
cd "$FDS_ROOT"
|
||||
fds_version=$(tools/version)
|
||||
use_xbps
|
||||
check_void_pin
|
||||
mkdir -p out/logs out/manifests out/packages
|
||||
# These are build-container tools; no Arch packages or host services are changed.
|
||||
missing=()
|
||||
for package in cross-aarch64-linux-musl pkg-config s6-rc; do
|
||||
for package in cross-aarch64-linux-musl pkg-config s6-rc python3 git; do
|
||||
if ! XBPS_ARCH=x86_64 xbps-query -r "$FDS_VOID/masterdir-x86_64" "$package" >/dev/null 2>&1; then
|
||||
missing+=("$package")
|
||||
fi
|
||||
@@ -26,7 +27,7 @@ tools/in-void env LIBUSB_NO_PKG_CONFIG=1 LIBUDEV_NO_PKG_CONFIG=1 \
|
||||
binary=target/aarch64-unknown-linux-musl/release/dasungd
|
||||
tools/verify-elf "$binary" aarch64 static
|
||||
cp -- "$binary" out/dasungd
|
||||
input="$FDS_VOID/hostdir/sources/fds-dasungd-0.1.0"
|
||||
input="$FDS_VOID/hostdir/sources/fds-dasungd-${fds_version}"
|
||||
mkdir -p "$input"
|
||||
cp -- "$binary" "$input/dasungd"
|
||||
cp rust/dasungd/LICENSE rust/dasungd/profiles/paperlike13k-37hz.edid "$input/"
|
||||
@@ -62,10 +63,9 @@ tools/prepare-void
|
||||
cd "$FDS_VOID"
|
||||
xbps_src -f -a aarch64 pkg fds-dasungd
|
||||
) 2>&1 | tee out/logs/xbps-fds-dasungd.log
|
||||
package=fds-dasungd-0.1.0_1.aarch64.xbps
|
||||
cp "$FDS_VOID/hostdir/binpkgs/$package" out/packages/
|
||||
XBPS_ARCH=aarch64 xbps-rindex -fa "out/packages/$package"
|
||||
package="fds-dasungd-${fds_version}_1.aarch64.xbps"
|
||||
tools/export-package "$FDS_VOID/hostdir/binpkgs/$package"
|
||||
sha256sum out/dasungd "out/packages/$package" >out/manifests/dasung-artifacts.sha256
|
||||
XBPS_ARCH=x86_64 xbps-query -r "$FDS_VOID/masterdir-x86_64" -l >out/manifests/dasung-build-packages.txt
|
||||
sha256sum Cargo.toml Cargo.lock rust-toolchain.toml .cargo/config.toml tools/cargo-build tools/lib.sh tools/build-dasungd >out/manifests/dasung-rust-inputs.sha256
|
||||
sha256sum tools/version tools/fds_version.py tools/version-build.rs Cargo.toml Cargo.lock rust-toolchain.toml .cargo/config.toml tools/cargo-build tools/lib.sh tools/build-dasungd >out/manifests/dasung-rust-inputs.sha256
|
||||
printf 'PASS: Dasung static ARM executable, base package, and s6 database built\n'
|
||||
|
||||
+1
-1
@@ -15,5 +15,5 @@ cp out/fds out/fds-power
|
||||
sha256sum out/fds-control out/fds-program out/fds-release out/fds-burn out/fds-inspect out/fds-eject out/fds-power out/fds out/fds-stage0 out/fds-boottrace out/fds-cartridged out/fds-profile >out/manifests/fds-tools.sha256
|
||||
find rust/fds-control rust/fds-software rust/fds-common rust/fds-cli rust/fds-stage0 rust/fds-boottrace rust/fds-cartridged rust/fds-burn rust/fds-release -type f -print0 | sort -z | \
|
||||
xargs -0 sha256sum >out/manifests/fds-tools-inputs.sha256
|
||||
sha256sum Cargo.toml Cargo.lock rust-toolchain.toml .cargo/config.toml tools/cargo-build tools/lib.sh tools/build-fds >>out/manifests/fds-tools-inputs.sha256
|
||||
sha256sum tools/version tools/fds_version.py tools/version-build.rs Cargo.toml Cargo.lock rust-toolchain.toml .cargo/config.toml tools/cargo-build tools/lib.sh tools/build-fds >>out/manifests/fds-tools-inputs.sha256
|
||||
printf 'PASS: static ARM FDS CLI and stage0 tools built\n'
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
source "$(dirname -- "${BASH_SOURCE[0]}")/lib.sh"
|
||||
[[ $# == 0 ]] || die 'Usage: tools/build-fds-package'
|
||||
cd "$FDS_ROOT"
|
||||
fds_version=$(tools/version)
|
||||
use_xbps
|
||||
tools/build-fds
|
||||
tools/prepare-void
|
||||
input="$FDS_VOID/hostdir/sources/fds-cli-0.1.0"
|
||||
input="$FDS_VOID/hostdir/sources/fds-cli-${fds_version}"
|
||||
mkdir -p "$input" out/packages
|
||||
cp out/fds out/fds-control out/fds-program out/fds-boottrace out/fds-burn out/fds-inspect out/fds-eject out/fds-power out/fds-release LICENSE "$input/"
|
||||
notices=$(mktemp -d "$FDS_ROOT/out/rust-notices.XXXXXX")
|
||||
@@ -17,9 +18,8 @@ cp "$notices/RUST-NOTICES.txt" "$input/"
|
||||
xbps_src -a aarch64 clean fds-cli
|
||||
xbps_src -f -a aarch64 pkg fds-cli
|
||||
) 2>&1 | tee out/logs/xbps-fds-cli.log
|
||||
cp "$FDS_VOID/hostdir/binpkgs/fds-cli-0.1.0_1.aarch64.xbps" out/packages/
|
||||
XBPS_ARCH=aarch64 xbps-rindex -fa out/packages/fds-cli-0.1.0_1.aarch64.xbps
|
||||
input="$FDS_VOID/hostdir/sources/fds-cartridged-0.1.0"
|
||||
tools/export-package "$FDS_VOID/hostdir/binpkgs/fds-cli-${fds_version}_1.aarch64.xbps"
|
||||
input="$FDS_VOID/hostdir/sources/fds-cartridged-${fds_version}"
|
||||
if [[ -d $input ]]; then
|
||||
previous=$(mktemp -d "$FDS_ROOT/out/cartridged-source.XXXXXX")
|
||||
mv "$input" "$previous/"
|
||||
@@ -37,6 +37,5 @@ cp s6/source/boot/contents.d/cartridged "$input/s6-source/boot/contents.d/"
|
||||
xbps_src -a aarch64 clean fds-cartridged
|
||||
xbps_src -f -a aarch64 pkg fds-cartridged
|
||||
) 2>&1 | tee out/logs/xbps-fds-cartridged.log
|
||||
cp "$FDS_VOID/hostdir/binpkgs/fds-cartridged-0.1.0_1.aarch64.xbps" out/packages/
|
||||
XBPS_ARCH=aarch64 xbps-rindex -fa out/packages/fds-cartridged-0.1.0_1.aarch64.xbps
|
||||
tools/export-package "$FDS_VOID/hostdir/binpkgs/fds-cartridged-${fds_version}_1.aarch64.xbps"
|
||||
printf 'PASS: FDS CLI package built without a dynamic libc dependency\n'
|
||||
|
||||
@@ -69,6 +69,7 @@ if [[ ${FDS_OFFLINE:-0} == 1 ]]; then
|
||||
fi
|
||||
python3 tools/rootfs-archive "$root" "$work" "${archive_inputs[@]}"
|
||||
{
|
||||
printf 'version=%s\n' "$(tools/version)"
|
||||
printf 'profile=%s\nvoid_commit=%s\n' "$profile" "$(cat VOID_PACKAGES_COMMIT)"
|
||||
printf 'emulation=private-user-namespace-binfmt\n'
|
||||
tools/in-void xbps-query -p pkgver qemu-user-aarch64
|
||||
|
||||
+18
-10
@@ -1,15 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
# Native Linux host binaries; independent of the Pi and Void build container.
|
||||
# Build an installable Arch package without installing host packages implicitly.
|
||||
set -euo pipefail
|
||||
[[ $# == 0 ]] || { printf 'Usage: tools/build-workstation\n' >&2; exit 2; }
|
||||
[[ $(uname -s) == Linux ]] || { printf 'A Linux workstation is required\n' >&2; exit 2; }
|
||||
(( EUID != 0 )) || { printf 'Build as an ordinary user\n' >&2; exit 2; }
|
||||
cd "$(dirname -- "${BASH_SOURCE[0]}")/.."
|
||||
command -v cargo >/dev/null || { printf 'Install Rust with Cargo before building workstation tools\n' >&2; exit 2; }
|
||||
fds_host_target=$(rustc -vV | sed -n 's/^host: //p')
|
||||
[[ $fds_host_target == *-linux-* ]] || { printf 'Rust must target the native Linux host\n' >&2; exit 2; }
|
||||
cargo build --locked --release --target "$fds_host_target" -p fds-workstation
|
||||
mkdir -p out/workstation
|
||||
install -m755 "target/$fds_host_target/release/fds-cartridge" out/workstation/fds-cartridge
|
||||
install -m755 "target/$fds_host_target/release/fds-emulator" out/workstation/fds-emulator
|
||||
printf 'Built native Linux tools in out/workstation/\n'
|
||||
for tool in makepkg pacman cargo rustc python3 git; do
|
||||
command -v "$tool" >/dev/null || { printf 'Missing %s; see docs/workstation.md\n' "$tool" >&2; exit 1; }
|
||||
done
|
||||
export FDS_SOURCE_DIR="$PWD"
|
||||
mkdir -p out/workstation out/workstation-package
|
||||
exec 9>out/.workstation-package.lock
|
||||
flock -n 9 || { printf 'Another workstation package build is running\n' >&2; exit 1; }
|
||||
cp packaging/arch/PKGBUILD out/workstation-package/PKGBUILD
|
||||
export PKGDEST="$PWD/out/workstation"
|
||||
cd out/workstation-package
|
||||
# Dependencies are checked by their actual build commands. Runtime features
|
||||
# are optional, and package installation is a separate explicit Make target.
|
||||
makepkg --nodeps --force
|
||||
mapfile -t packages < <(makepkg --packagelist)
|
||||
(( ${#packages[@]} == 1 )) && [[ -s ${packages[0]} ]] || { printf 'Expected one fds-tools package\n' >&2; exit 1; }
|
||||
printf '%s\n' "${packages[0]}" >../workstation/package-path.txt
|
||||
printf 'Built Arch package: %s\nInstall with make workstation-install\n' "${packages[0]}"
|
||||
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
# Native Linux host binaries; independent of the Pi and Void build container.
|
||||
set -euo pipefail
|
||||
[[ $# == 0 ]] || { printf 'Usage: tools/build-workstation-binaries\n' >&2; exit 2; }
|
||||
[[ $(uname -s) == Linux ]] || { printf 'A Linux workstation is required\n' >&2; exit 2; }
|
||||
(( EUID != 0 )) || { printf 'Build as an ordinary user\n' >&2; exit 2; }
|
||||
cd "$(dirname -- "${BASH_SOURCE[0]}")/.."
|
||||
command -v cargo >/dev/null || { printf 'Install Rust with Cargo before building workstation tools\n' >&2; exit 2; }
|
||||
fds_host_target=$(rustc -vV | sed -n 's/^host: //p')
|
||||
[[ $fds_host_target == *-linux-* ]] || { printf 'Rust must target the native Linux host\n' >&2; exit 2; }
|
||||
cargo build --locked --release --target "$fds_host_target" -p fds-workstation
|
||||
mkdir -p out/workstation
|
||||
install -m755 "target/$fds_host_target/release/fds-cartridge" out/workstation/fds-cartridge
|
||||
install -m755 "target/$fds_host_target/release/fds-emulator" out/workstation/fds-emulator
|
||||
printf 'Built native Linux tools in out/workstation/\n'
|
||||
+4
-2
@@ -24,15 +24,17 @@ PREFIXES = (
|
||||
'm9-images', 'm9-vm', 'm9-system', 'm10-vm', 'm11-vm', 'm11-faults',
|
||||
'm12-clock', 'm12-development', 'm12-eeprom', 'm12-internal',
|
||||
'm12-recovery', 'm12-release-contracts', 'm12-signing',
|
||||
'rust-profiles', 'workstation-images', 'emu-test',
|
||||
'rust-profiles', 'workstation-images', 'emu-test', 'arch-package-test', 'version-image-test',
|
||||
)
|
||||
GENERATED = re.compile(r'(?:' + '|'.join(PREFIXES) + r')\.[A-Za-z0-9_-]{6,8}')
|
||||
POINTERS = (
|
||||
'out/arch-package-current.txt',
|
||||
'out/version-image-current.txt',
|
||||
'out/workstation-images-current.txt',
|
||||
'out/workstation-emulator-current.txt',
|
||||
'out/manifests/dasung-s6-database.txt',
|
||||
)
|
||||
LOCKS = ('.clean.lock', '.rootfs.lock', '.base-packages.lock', '.image-tools.lock')
|
||||
LOCKS = ('.clean.lock', '.rootfs.lock', '.base-packages.lock', '.image-tools.lock', '.workstation-package.lock')
|
||||
|
||||
|
||||
def within(path, parent):
|
||||
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Export one FDS XBPS package, retaining superseded builds outside the active index."""
|
||||
import argparse
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
project = Path(__file__).resolve().parents[1]
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('package', type=Path)
|
||||
args = parser.parse_args()
|
||||
source = args.package.resolve(strict=True)
|
||||
name, release = source.name.rsplit('-', 1)
|
||||
if not name.startswith('fds-') or not release.endswith('.aarch64.xbps'):
|
||||
parser.error('Expected an FDS AArch64 package')
|
||||
out = project / 'out/packages'
|
||||
out.mkdir(exist_ok=True)
|
||||
old = [p for p in out.glob(f'{name}-*.aarch64.xbps') if p.name.rsplit('-', 1)[0] == name]
|
||||
if old:
|
||||
history = project / 'out/package-history'
|
||||
history.mkdir(exist_ok=True)
|
||||
saved = Path(tempfile.mkdtemp(prefix=f'{name}.', dir=history))
|
||||
for path in old:
|
||||
path.rename(saved / path.name)
|
||||
# Prune entries for archived versions before indexing the selected package.
|
||||
env = dict(os.environ, XBPS_ARCH='aarch64')
|
||||
index = project / '.host/xbps/usr/bin/xbps-rindex'
|
||||
subprocess.run([str(index), '-c', str(out)], env=env, check=True)
|
||||
shutil.copy2(source, out / source.name)
|
||||
subprocess.run([str(index), '-fa', str(out / source.name)], env=env, check=True)
|
||||
print(f'Exported {source.name}; previous builds retained under out/package-history')
|
||||
@@ -0,0 +1,59 @@
|
||||
"""Canonical FDS build version, shared by Cargo, images and package builders."""
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
RELEASE = re.compile(r'v?([0-9]+(?:\.[0-9]+){1,2})\Z')
|
||||
VALID = re.compile(r'[0-9][A-Za-z0-9.]{0,31}\Z')
|
||||
|
||||
|
||||
def validate(value):
|
||||
if not isinstance(value, str) or not VALID.fullmatch(value):
|
||||
raise ValueError(f'Invalid FDS version: {value!r}')
|
||||
return value
|
||||
|
||||
|
||||
def git(root, *args):
|
||||
return subprocess.check_output(['git', '-C', str(root), *args], text=True, stderr=subprocess.DEVNULL).strip()
|
||||
|
||||
|
||||
def version(root=ROOT):
|
||||
root = Path(root).resolve()
|
||||
# Source exports carry the value resolved when the export was created.
|
||||
# Never accidentally describe a containing repository during offline builds.
|
||||
if not (root / '.git').exists():
|
||||
return validate((root / 'FDS_VERSION').read_text().strip())
|
||||
revision = git(root, 'rev-parse', '--short=12', 'HEAD')
|
||||
tags = [tag for tag in git(root, 'tag', '--merged', 'HEAD').splitlines() if RELEASE.fullmatch(tag)]
|
||||
if tags:
|
||||
description = git(root, 'describe', '--tags', '--long', '--abbrev=12', *[f'--match={tag}' for tag in tags], 'HEAD')
|
||||
tag, distance, commit = description.rsplit('-', 2)
|
||||
value = RELEASE.fullmatch(tag)[1]
|
||||
if int(distance):
|
||||
value += f'.r{distance}.{commit}'
|
||||
else:
|
||||
value = f'0.dev.g{revision}'
|
||||
if git(root, 'status', '--porcelain', '--untracked-files=no'):
|
||||
value += '.dirty'
|
||||
return validate(value)
|
||||
|
||||
|
||||
def cargo(root=ROOT):
|
||||
print(f'cargo:rustc-env=FDS_BUILD_VERSION={version(root)}')
|
||||
for path in [root / 'tools/fds_version.py', root / 'tools/version', root / 'tools/version-build.rs']:
|
||||
print(f'cargo:rerun-if-changed={path}')
|
||||
if not (root / '.git').exists():
|
||||
print(f'cargo:rerun-if-changed={root / "FDS_VERSION"}')
|
||||
return
|
||||
# Tag creation, ref changes, staging and edits must invalidate cached binaries.
|
||||
for name in ['HEAD', 'index', 'packed-refs', 'refs']:
|
||||
path = git(root, 'rev-parse', '--path-format=absolute', '--git-path', name)
|
||||
print(f'cargo:rerun-if-changed={path}')
|
||||
head = subprocess.run(['git', '-C', str(root), 'symbolic-ref', '-q', 'HEAD'], capture_output=True, text=True)
|
||||
if head.returncode == 0:
|
||||
print('cargo:rerun-if-changed=' + git(root, 'rev-parse', '--path-format=absolute', '--git-path', head.stdout.strip()))
|
||||
paths = git(root, 'ls-files', '--cached', '--others', '--exclude-standard').splitlines()
|
||||
for name in paths:
|
||||
if name != 'vendor/void-packages':
|
||||
print(f'cargo:rerun-if-changed={root / name}')
|
||||
+5
-3
@@ -12,11 +12,12 @@ import stat
|
||||
import subprocess
|
||||
import sys
|
||||
import tomllib
|
||||
from fds_version import version, validate
|
||||
|
||||
project = Path(__file__).resolve().parents[1]
|
||||
OWNED = ('.cargo', '.gitignore', '.gitmodules', 'AGENTS.md', 'Cargo.lock',
|
||||
'Cargo.toml', 'LICENSE', 'Makefile', 'README.md', 'VOID_PACKAGES_COMMIT',
|
||||
'config', 'docs', 'image', 'packages', 'profiles', 'rust-toolchain.toml',
|
||||
'config', 'docs', 'examples', 'image', 'packaging', 'packages', 'profiles', 'rust-toolchain.toml',
|
||||
'rust', 's6', 'tests', 'tools')
|
||||
|
||||
|
||||
@@ -119,6 +120,7 @@ def create(destination):
|
||||
new_directory(destination)
|
||||
for name in OWNED:
|
||||
copy(project / name, destination / 'project' / name)
|
||||
(destination / 'project/FDS_VERSION').write_text(version(project) + '\n')
|
||||
run('git', '-C', void, 'bundle', 'create', destination / 'void.bundle', 'HEAD')
|
||||
# Bundles carry commit objects, but do not retain a shallow checkout's
|
||||
# boundary file. Without it, history-aware commands follow missing parents.
|
||||
@@ -205,7 +207,7 @@ def create(destination):
|
||||
('tar', ['tar', '--version']), ('rustup', ['rustup', '--version'])]:
|
||||
host[name] = subprocess.check_output(command, text=True, stderr=subprocess.DEVNULL).splitlines()[0]
|
||||
files = inventory(destination)
|
||||
lock = {'format': 1, 'version': '0.1.0', 'void_commit': pin, 'source_epoch': epoch,
|
||||
lock = {'format': 1, 'version': version(project), 'void_commit': pin, 'source_epoch': epoch,
|
||||
'source_sha256': source_digest(files), 'rust_toolchain': toolchain_version,
|
||||
'host_prerequisites': host, 'files': files}
|
||||
(destination / 'lock.json').write_text(json.dumps(lock, indent=2) + '\n')
|
||||
@@ -219,7 +221,7 @@ def verify(directory):
|
||||
if lockfile.is_symlink() or not lockfile.is_file() or lockfile.stat().st_size > 64 * 1024 * 1024:
|
||||
raise ValueError('Missing or invalid frozen input lock')
|
||||
lock = json.loads(lockfile.read_text())
|
||||
if lock.get('format') != 1 or lock.get('version') != '0.1.0':
|
||||
if lock.get('format') != 1 or not validate(lock.get('version')):
|
||||
raise ValueError('Unsupported frozen input format')
|
||||
if (set(lock) != {'format', 'version', 'void_commit', 'source_epoch', 'source_sha256',
|
||||
'rust_toolchain', 'host_prerequisites', 'files'}
|
||||
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
# Only this explicit target changes the host package database.
|
||||
set -euo pipefail
|
||||
[[ $# == 0 ]] || { printf 'Usage: tools/install-workstation\n' >&2; exit 2; }
|
||||
cd "$(dirname -- "${BASH_SOURCE[0]}")/.."
|
||||
package=$(cat out/workstation/package-path.txt)
|
||||
[[ -f $package ]] || { printf 'Build fds-tools with make workstation first\n' >&2; exit 1; }
|
||||
if (( EUID == 0 )); then
|
||||
exec pacman -U -- "$package"
|
||||
else
|
||||
exec sudo pacman -U -- "$package"
|
||||
fi
|
||||
@@ -3,6 +3,8 @@ source "$(dirname -- "${BASH_SOURCE[0]}")/lib.sh"
|
||||
[[ $# == 0 ]] || die 'Usage: tools/prepare-void'
|
||||
"$FDS_ROOT/tools/prepare-void-workspace"
|
||||
check_void_pin
|
||||
"$FDS_ROOT/tools/version" >"$FDS_VOID/fds-version.next"
|
||||
mv "$FDS_VOID/fds-version.next" "$FDS_VOID/fds-version"
|
||||
# xbps-src reads this ignored local configuration instead of user-global settings.
|
||||
if [[ -f $FDS_VOID/etc/conf ]] && ! cmp -s "$FDS_ROOT/config/xbps-src.conf" "$FDS_VOID/etc/conf"; then
|
||||
die '.host/void-packages/etc/conf differs from config/xbps-src.conf; reconcile it explicitly'
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
from fds_version import validate
|
||||
|
||||
|
||||
def digest(path):
|
||||
@@ -42,7 +43,7 @@ def artifacts(project):
|
||||
def read_lock(project):
|
||||
path = Path(project) / '.host/frozen/lock.json'
|
||||
lock = json.loads(path.read_text())
|
||||
if lock.get('format') != 1 or lock.get('version') != '0.1.0':
|
||||
if lock.get('format') != 1 or not validate(lock.get('version')):
|
||||
raise ValueError('Build does not identify a supported frozen input snapshot')
|
||||
return lock, digest(path)
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import pathlib
|
||||
import stat
|
||||
import struct
|
||||
import sys
|
||||
import shlex
|
||||
from fds_version import validate
|
||||
|
||||
from rootfs_lib import package_db, rooted
|
||||
|
||||
@@ -29,6 +31,12 @@ def audit(root, configured=True):
|
||||
assert path.is_dir() and not path.is_symlink(), f"Missing directory: {name}"
|
||||
assert stat.S_IMODE(path.stat().st_mode) == int(mode, 8), f"Wrong directory mode: {name}"
|
||||
assert 'ID=fds\n' in (root / "usr/lib/os-release").read_text(), "Wrong OS identity"
|
||||
identity = dict(line.split('=', 1) for line in shlex.split((root / 'usr/lib/os-release').read_text(), comments=True))
|
||||
version = validate(identity['VERSION_ID'])
|
||||
assert identity['VERSION'] == version and identity['PRETTY_NAME'] == f'FDS/OS {version}', 'Inconsistent OS version'
|
||||
assert (root / 'etc/issue').read_text() == f'FDS/OS {version}\n', 'Inconsistent login version'
|
||||
for package in ('fds-base', 'fds-base-files', 'fds-init', 'fds-cli', 'fds-cartridged', 'fds-dasungd', 'fds-eink'):
|
||||
assert db[package]['pkgver'] == f'{package}-{version}_1', f'OS/package version mismatch: {package}'
|
||||
release = (root / "usr/share/fds/kernel-release").read_text().strip()
|
||||
assert (root / "usr/lib/modules" / release / "modules.dep").is_file(), "Missing matching kernel module index"
|
||||
assert (root / "etc/shadow").stat().st_mode & 0o777 == 0o600, "Shadow file is exposed"
|
||||
|
||||
@@ -26,7 +26,10 @@ trap 'rm -f "$log"' EXIT
|
||||
dasungd --config /etc/dasungd.toml check
|
||||
fds --json info | grep -q aarch64
|
||||
fds-cartridged --help | grep -q SYSFS_ROOT
|
||||
fds-release --version | grep -qx "fds-release 0.1.0"
|
||||
. /etc/os-release
|
||||
fds-release --version | grep -Fx "fds-release $VERSION_ID"
|
||||
fds --version | grep -Fx "fds $VERSION_ID"
|
||||
dasungd --version | grep -Fx "dasungd $VERSION_ID"
|
||||
s6-rc-db -c /etc/s6-rc/compiled list all | grep -qx cartridged
|
||||
s6-rc-db -c /etc/s6-rc/compiled list all | grep -qx dasungd
|
||||
s6-rc-db -c /etc/s6-rc/compiled list all | grep -qx test-echo
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Print the FDS version derived from release tags or a Git source export."""
|
||||
import argparse
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from fds_version import ROOT, cargo, version
|
||||
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--root', type=Path, default=ROOT)
|
||||
parser.add_argument('--cargo', action='store_true', help='emit Cargo build metadata and change tracking')
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
if args.cargo:
|
||||
cargo(args.root.resolve())
|
||||
else:
|
||||
print(version(args.root))
|
||||
except (OSError, ValueError, subprocess.CalledProcessError) as error:
|
||||
parser.exit(1, f'Cannot determine FDS version: {error}\n')
|
||||
@@ -0,0 +1,20 @@
|
||||
// Every workspace crate uses the same resolver, including direct Cargo builds.
|
||||
use std::{env, path::PathBuf, process::Command};
|
||||
fn main() {
|
||||
let manifest = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
|
||||
let root = manifest.parent().unwrap().parent().unwrap();
|
||||
let output = Command::new("python3")
|
||||
.arg(root.join("tools/version"))
|
||||
.arg("--cargo")
|
||||
.output()
|
||||
.expect("Python 3 is required to resolve the FDS build version");
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"FDS version discovery failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
print!(
|
||||
"{}",
|
||||
String::from_utf8(output.stdout).expect("Version metadata must be UTF-8")
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user