Capture mesh-catalog at feat/r4g (2246ccc4) with the templates its manifests name and its predefined.json, and lay the copy out as a repository's root
The catalogue's manifests moved their content into template files and fall back to predefined keys, so a copy of module.json alone no longer passes the catalogue's own check; the bus's Dockerfile is gone from the catalogue.
This commit is contained in:
+13
@@ -0,0 +1,13 @@
|
||||
# Module kernel, novox/hq ADR 0508 §9, issue 1841. After a kernel image is installed, upgraded or removed, the
|
||||
# fallback kernel's boot entry (or the GRUB menu) is placed again. Written by the mesh; change the module.
|
||||
[Trigger]
|
||||
Operation = Install
|
||||
Operation = Upgrade
|
||||
Operation = Remove
|
||||
Type = Path
|
||||
Target = usr/lib/modules/*/vmlinuz
|
||||
|
||||
[Action]
|
||||
Description = Placing the fallback kernel on the boot menu
|
||||
When = PostTransaction
|
||||
Exec = ${dir:state}/boot-entries run
|
||||
@@ -0,0 +1,133 @@
|
||||
#!/bin/sh
|
||||
# The fallback kernel's place on this machine's boot menu (module kernel, novox/hq ADR 0508 §9 and §10,
|
||||
# issue 1841). Written by the mesh and run as root by mesh-kernel-boot-entries.service at boot and when the
|
||||
# module is applied, and by the pacman hook 90-mesh-kernel-boot-entries.hook after a kernel is installed,
|
||||
# upgraded or removed. Replaced on every push; change the module, never this file.
|
||||
#
|
||||
# boot-entries run [<root> [<this module's state> [<room needed in /boot, KiB>]]]
|
||||
#
|
||||
# The three are arguments only so the module's tests can run this against a stand-in tree.
|
||||
#
|
||||
# It reads from the machine which loader booted it, never from a setting:
|
||||
# systemd-boot the EFI variable LoaderEntrySelected is present: the entry mesh-linux-lts.conf is written
|
||||
# from the command line the machine booted with.
|
||||
# GRUB /boot/grub/grub.cfg exists and that variable does not: the menu is generated again, only
|
||||
# when the set of kernels in /boot differs from the menu's.
|
||||
# neither it fails loudly. The default entry is never touched.
|
||||
# And a pacman hook of someone else's that copies kernel images to one fixed name in /boot is moved into this
|
||||
# module's state first (ADR 0508 §10): it would put the fallback kernel in the default kernel's place.
|
||||
set -eu
|
||||
|
||||
root=/
|
||||
state='${dir:state}'
|
||||
[ $# -ge 2 ] && root=$(printf '%s' "$2" | sed 's|/$||')
|
||||
[ $# -ge 3 ] && state=$3
|
||||
boot=$root/boot
|
||||
hooks=$root/etc/pacman.d/hooks
|
||||
efivar=$root/sys/firmware/efi/efivars/LoaderEntrySelected-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
|
||||
ours=90-mesh-kernel-boot-entries.hook
|
||||
# The fallback kernel and its initramfs are about 72 MB in /boot (issue 1836): less room fails the unit
|
||||
# before a package writes half of them.
|
||||
need_kib=98304
|
||||
[ $# -ge 4 ] && need_kib=$4
|
||||
|
||||
[ $# -ge 1 ] && [ "$1" = run ] || {
|
||||
echo "usage: boot-entries run [<root> [<state directory> [<KiB needed>]]]" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
# A hook that is not ours, triggered by kernel images, whose action copies to one fixed name in /boot.
|
||||
copies_kernels() {
|
||||
grep -Eqi '^[[:space:]]*Target[[:space:]]*=.*(vmlinuz|usr/lib/modules)' "$1" &&
|
||||
grep -Eq '^[[:space:]]*Exec[[:space:]]*=.*(cp|install|ln|rsync)[[:space:]].*/boot/[A-Za-z0-9._+-]+([^A-Za-z0-9._+/%$*-]|$)' "$1"
|
||||
}
|
||||
|
||||
if [ -d "$hooks" ]; then
|
||||
for hook in "$hooks"/*.hook; do
|
||||
[ -f "$hook" ] || continue
|
||||
[ "$(basename "$hook")" = "$ours" ] && continue
|
||||
copies_kernels "$hook" || continue
|
||||
mkdir -p "$state/taken-over"
|
||||
mv -f "$hook" "$state/taken-over/$(basename "$hook")"
|
||||
echo "taken over: the pacman hook $(basename "$hook") copied kernel images to one fixed name in /boot; moved to $state/taken-over/ so each kernel keeps its own package's name"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -e "$efivar" ]; then
|
||||
loader=systemd-boot
|
||||
elif [ -f "$boot/grub/grub.cfg" ]; then
|
||||
loader=grub
|
||||
else
|
||||
echo "no boot loader found: the machine was not booted by systemd-boot (no LoaderEntrySelected variable) and there is no $boot/grub/grub.cfg; the fallback kernel has no menu to be placed on" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Room first, only while the fallback kernel is not in /boot yet.
|
||||
if [ ! -e "$boot/vmlinuz-linux-lts" ]; then
|
||||
free=$(df -Pk "$boot" | awk 'NR==2 {print $4}')
|
||||
[ -n "$free" ] || free=0
|
||||
if [ "$free" -lt "$need_kib" ]; then
|
||||
echo "$boot has $free KiB free and the fallback kernel needs $need_kib KiB: free room there before the kernel is installed" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$loader" in
|
||||
systemd-boot)
|
||||
entries=$boot/loader/entries
|
||||
cmdline=$(sed -e 's/BOOT_IMAGE=[^ ]*//g' -e 's/initrd=[^ ]*//g' "$root/proc/cmdline" | tr -s ' \n' ' ' | sed -e 's/^ //' -e 's/ $//')
|
||||
[ -n "$cmdline" ] || {
|
||||
echo "$root/proc/cmdline holds no command line to boot the fallback kernel with" >&2
|
||||
exit 1
|
||||
}
|
||||
want=$(
|
||||
echo "title Arch Linux (linux-lts, fallback)"
|
||||
echo "linux /vmlinuz-linux-lts"
|
||||
for ucode in intel-ucode.img amd-ucode.img; do
|
||||
[ -e "$boot/$ucode" ] && echo "initrd /$ucode"
|
||||
done
|
||||
echo "initrd /initramfs-linux-lts.img"
|
||||
echo "options $cmdline"
|
||||
)
|
||||
mkdir -p "$entries"
|
||||
if [ "$(cat "$entries/mesh-linux-lts.conf" 2>/dev/null || true)" = "$want" ]; then
|
||||
echo "systemd-boot: mesh-linux-lts.conf, as it was"
|
||||
else
|
||||
printf '%s\n' "$want" >"$entries/mesh-linux-lts.conf"
|
||||
echo "systemd-boot: wrote $entries/mesh-linux-lts.conf from the command line the machine booted with; the default entry is as it was"
|
||||
fi
|
||||
;;
|
||||
grub)
|
||||
cfg=$boot/grub/grub.cfg
|
||||
menu=$(sed -n 's|^[[:space:]]*linux[[:space:]]*\(/boot\)\{0,1\}/\(vmlinuz-[^[:space:]]*\).*|\2|p' "$cfg" | sort -u)
|
||||
have=$(cd "$boot" && ls -d vmlinuz-* 2>/dev/null | sort -u || true)
|
||||
if [ "$menu" = "$have" ]; then
|
||||
echo "grub: the menu lists the kernels in /boot, left as it is"
|
||||
else
|
||||
# GRUB lists kernels in reverse version order, so the fallback kernel would come first and become the
|
||||
# default entry: the kernel the machine booted is put first (GRUB_TOP_LEVEL; /etc/default/grub still
|
||||
# overrides it when it sets one), the fallback kernel never.
|
||||
top=$(tr ' ' '\n' <"$root/proc/cmdline" | sed -n 's|^BOOT_IMAGE=\(.*\)$|\1|p' | head -n 1)
|
||||
top=$(printf '%s' "$top" | sed 's|.*/||')
|
||||
case "$top" in
|
||||
vmlinuz-linux-lts | "") top= ;;
|
||||
esac
|
||||
[ -n "$top" ] && [ -e "$boot/$top" ] || top=
|
||||
if [ -z "$top" ]; then
|
||||
if [ -e "$boot/vmlinuz-linux" ]; then
|
||||
top=vmlinuz-linux
|
||||
else
|
||||
top=$(printf '%s\n' $have | grep -v '^vmlinuz-linux-lts$' | head -n 1 || true)
|
||||
fi
|
||||
fi
|
||||
if [ -n "$top" ]; then
|
||||
GRUB_TOP_LEVEL=/boot/$top grub-mkconfig -o "$cfg"
|
||||
else
|
||||
grub-mkconfig -o "$cfg"
|
||||
fi
|
||||
first=$top
|
||||
[ -n "$first" ] || first="the menu's own order"
|
||||
echo "grub: the kernels in /boot changed ($(echo $have | tr '\n' ' ')); the menu is generated again with $first first; the default entry is as it was"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,84 @@
|
||||
#!/bin/sh
|
||||
# Transparent huge pages as the mesh sets them on this machine (module kernel, novox/hq issue 746).
|
||||
# Written by the mesh from this machine's setting transparent-huge-pages and run by
|
||||
# mesh-kernel-huge-pages.service: `apply` at boot and whenever the setting changes, `restore` when the
|
||||
# unit stops (the module unassigned, or the machine shutting down). Replaced on every push; change the
|
||||
# setting, never this file. A change of the setting reloads the unit, which runs `apply` again: the mode
|
||||
# moves straight to the new value and never passes back through the one the machine was found with.
|
||||
#
|
||||
# huge-pages apply|restore [<the kernel's transparent_hugepage directory> [<this module's state>]]
|
||||
#
|
||||
# The two directories are arguments only so the module's tests can run this against a stand-in tree.
|
||||
set -eu
|
||||
|
||||
want='${config:transparent-huge-pages}'
|
||||
sys=/sys/kernel/mm/transparent_hugepage
|
||||
state='${dir:state}'
|
||||
[ $# -ge 2 ] && sys=$2
|
||||
[ $# -ge 3 ] && state=$3
|
||||
|
||||
case "$want" in
|
||||
always | madvise | never) ;;
|
||||
*)
|
||||
echo "the setting transparent-huge-pages is '$want'; the kernel takes always, madvise or never" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
[ -f "$sys/enabled" ] || {
|
||||
echo "this kernel has no $sys/enabled: it was built without transparent huge pages, so there is nothing to set" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# The mode in force is the word the kernel brackets: "always [madvise] never". A file holding one bare
|
||||
# word (the stand-in tree of the tests) is read as that word.
|
||||
mode() { sed -n -e 's/.*\[\([a-z]*\)\].*/\1/p' -e t -e 's/^ *\([a-z]*\) *$/\1/p' "$sys/enabled"; }
|
||||
|
||||
[ $# -ge 1 ] || set -- usage
|
||||
case "$1" in
|
||||
apply)
|
||||
now=$(mode)
|
||||
# What the machine had before the mesh first set it, kept once, so `restore` gives it back.
|
||||
[ -s "$state/found" ] || printf '%s\n' "$now" >"$state/found"
|
||||
if [ "$now" = "$want" ]; then
|
||||
echo "transparent huge pages: $want, as set"
|
||||
exit 0
|
||||
fi
|
||||
printf '%s\n' "$want" >"$sys/enabled"
|
||||
got=$(mode)
|
||||
[ "$got" = "$want" ] || {
|
||||
echo "wrote $want to $sys/enabled and the kernel says $got" >&2
|
||||
exit 1
|
||||
}
|
||||
echo "transparent huge pages: $now -> $want"
|
||||
# A file folio already in the page cache keeps its size: the active journal files, mapped by journald
|
||||
# and by every reader, stay in 2 MiB folios until they are archived (issue 746). Rotating starts new
|
||||
# files that are mapped under the new mode. A failed rotation is said and does not fail the setting.
|
||||
# At boot nothing is in huge folios yet, and the persistent journal opens only after this unit: no rotation
|
||||
# while the service manager is still bringing the machine up.
|
||||
booting=$(systemctl is-system-running 2>/dev/null || true)
|
||||
case "$booting" in
|
||||
initializing | starting) echo "the machine is still starting: nothing to rotate yet" ;;
|
||||
*)
|
||||
if [ "$want" != always ] && command -v journalctl >/dev/null 2>&1; then
|
||||
journalctl --rotate || echo "the journal could not be rotated: its active files keep their huge pages until they are archived" >&2
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
restore)
|
||||
found=$(cat "$state/found" 2>/dev/null || true)
|
||||
case "$found" in
|
||||
always | madvise | never)
|
||||
printf '%s\n' "$found" >"$sys/enabled"
|
||||
echo "transparent huge pages: back to $found, as the machine had them"
|
||||
;;
|
||||
*) echo "transparent huge pages: nothing recorded as found, left at $(mode)" ;;
|
||||
esac
|
||||
# Unassigned or shut down: nothing of the module is kept; the next start records what it finds again.
|
||||
rm -f "$state/found"
|
||||
;;
|
||||
*)
|
||||
echo "usage: huge-pages apply|restore [<transparent_hugepage directory> [<state directory>]]" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
[Unit]
|
||||
Description=The fallback kernel's place on this machine's boot menu
|
||||
# Module kernel, novox/hq ADR 0508 §9, issue 1841. Starting this unit reads which loader booted the machine and
|
||||
# places the fallback kernel's boot entry (systemd-boot) or generates the menu again (GRUB); it fails, and says
|
||||
# why, when there is no loader or the boot partition has no room. The kernel packages are declared after this
|
||||
# unit, so the entry is in place before they are installed.
|
||||
After=local-fs.target
|
||||
Wants=local-fs.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=${dir:state}/boot-entries run
|
||||
# It writes the boot partition, the pacman hook directory and its own state, and nothing else.
|
||||
ProtectSystem=strict
|
||||
ReadWritePaths=/boot ${dir:state} /etc/pacman.d/hooks
|
||||
ProtectHome=yes
|
||||
PrivateNetwork=yes
|
||||
NoNewPrivileges=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
[Unit]
|
||||
Description=Transparent huge pages as the mesh sets them on this machine
|
||||
# Module kernel, novox/hq issue 746. Starting this unit sets the mode from the setting
|
||||
# transparent-huge-pages; reloading it (the setting changed) sets the new mode; stopping it gives back the
|
||||
# mode the machine had before. It runs early in boot, before the services that fill the page cache.
|
||||
DefaultDependencies=no
|
||||
After=local-fs.target
|
||||
Before=sysinit.target shutdown.target
|
||||
Conflicts=shutdown.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=${dir:state}/huge-pages apply
|
||||
ExecReload=${dir:state}/huge-pages apply
|
||||
ExecStop=${dir:state}/huge-pages restore
|
||||
# It writes one file under /sys and its own state, and asks the journal daemon to rotate over its socket.
|
||||
ProtectSystem=strict
|
||||
ReadWritePaths=${dir:state}
|
||||
ProtectHome=yes
|
||||
PrivateNetwork=yes
|
||||
NoNewPrivileges=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=sysinit.target
|
||||
@@ -0,0 +1,125 @@
|
||||
{
|
||||
"module": "kernel",
|
||||
"version": "1",
|
||||
"capabilities": [
|
||||
"service-manager"
|
||||
],
|
||||
"config": {
|
||||
"transparent-huge-pages": {
|
||||
"type": "string",
|
||||
"description": "madvise is the value the mesh chose for every node (novox/hq ADR 0381), not the always the distribution's kernel boots with; a machine that needs another value is given it as its own setting; madvise gives huge pages only to programs that ask for them, which stops a small write to a mapped file (the journal) dirtying and writing back a whole 2 MiB page on a machine whose disks are slow (novox/hq issue 746)",
|
||||
"trusted": true,
|
||||
"default": "madvise"
|
||||
}
|
||||
},
|
||||
"tools": [
|
||||
"kernel_huge_pages",
|
||||
"kernel_boot"
|
||||
],
|
||||
"resources": [
|
||||
{
|
||||
"id": "state",
|
||||
"type": "directory",
|
||||
"mode": "0700",
|
||||
"place": ".",
|
||||
"unknown": "program"
|
||||
},
|
||||
{
|
||||
"id": "huge-pages",
|
||||
"type": "file",
|
||||
"path": "${dir:state}/huge-pages",
|
||||
"mode": "0755",
|
||||
"trusted": true,
|
||||
"template": "files/huge-pages.sh"
|
||||
},
|
||||
{
|
||||
"id": "unit",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/mesh-kernel-huge-pages.service",
|
||||
"mode": "0644",
|
||||
"template": "files/mesh-kernel-huge-pages.service"
|
||||
},
|
||||
{
|
||||
"id": "apply",
|
||||
"type": "service",
|
||||
"unit": "mesh-kernel-huge-pages.service",
|
||||
"state": "running",
|
||||
"boot": "enabled",
|
||||
"restart-on": [
|
||||
"unit"
|
||||
],
|
||||
"reload-on": [
|
||||
"huge-pages"
|
||||
],
|
||||
"health": {
|
||||
"kind": "unit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "boot-entries",
|
||||
"type": "file",
|
||||
"path": "${dir:state}/boot-entries",
|
||||
"mode": "0755",
|
||||
"trusted": true,
|
||||
"template": "files/boot-entries.sh"
|
||||
},
|
||||
{
|
||||
"id": "boot-unit",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/mesh-kernel-boot-entries.service",
|
||||
"mode": "0644",
|
||||
"template": "files/mesh-kernel-boot-entries.service"
|
||||
},
|
||||
{
|
||||
"id": "boot-hook",
|
||||
"type": "file",
|
||||
"path": "/etc/pacman.d/hooks/90-mesh-kernel-boot-entries.hook",
|
||||
"mode": "0644",
|
||||
"template": "files/90-mesh-kernel-boot-entries.hook"
|
||||
},
|
||||
{
|
||||
"id": "boot-apply",
|
||||
"type": "service",
|
||||
"unit": "mesh-kernel-boot-entries.service",
|
||||
"state": "running",
|
||||
"boot": "enabled",
|
||||
"restart-on": [
|
||||
"boot-unit",
|
||||
"boot-entries"
|
||||
],
|
||||
"health": {
|
||||
"kind": "unit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "linux-lts",
|
||||
"type": "package",
|
||||
"package": "linux-lts"
|
||||
},
|
||||
{
|
||||
"id": "linux-lts-headers",
|
||||
"type": "package",
|
||||
"package": "linux-lts-headers"
|
||||
}
|
||||
],
|
||||
"build": {
|
||||
"artifacts": [
|
||||
{
|
||||
"name": "tools",
|
||||
"kind": "bundle",
|
||||
"language": "go",
|
||||
"system": "arch",
|
||||
"from": "cmd/kernel-tools",
|
||||
"binary": "kernel-tools",
|
||||
"loads": [
|
||||
"kernel-tools"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "files",
|
||||
"kind": "archive",
|
||||
"from": "files"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user