mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-23 17:33:01 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea315bdb10 | ||
|
|
3f23aa92be | ||
|
|
4984d5ac7f | ||
|
|
d945bb703b | ||
|
|
b047bd2a52 | ||
|
|
efc97f6566 | ||
|
|
39f9c1e166 | ||
|
|
f81de1d3ec | ||
|
|
e7fabfc37d | ||
|
|
956e604dcb | ||
|
|
9d3669b647 | ||
|
|
17a3ca58a0 | ||
|
|
7e2d0cf2f8 |
@@ -167,8 +167,8 @@ APIs.
|
||||
[0]: https://www.kernel.org
|
||||
[1]: https://buildroot.org/ "Buildroot Homepage"
|
||||
[2]: https://www.sysrepo.org/ "Sysrepo Homepage"
|
||||
[3]: https://www.kernelkit.org/infix/latest/cli/introduction/
|
||||
[4]: https://www.kernelkit.org/infix/
|
||||
[3]: https://kernelkit.org/infix/latest/cli/introduction/
|
||||
[4]: https://kernelkit.org/infix/
|
||||
[5]: https://github.com/kernelkit/infix/releases
|
||||
[Latest Build]: https://github.com/kernelkit/infix/releases/tag/latest "Latest build"
|
||||
[License]: https://en.wikipedia.org/wiki/GPL_license
|
||||
|
||||
@@ -262,8 +262,8 @@ make aarch64
|
||||
./utils/mkimage.sh -odt emmc bananapi-bpi-r3
|
||||
```
|
||||
|
||||
[0]: https://www.kernelkit.org/posts/flashing-sdcard/
|
||||
[1]: https://www.kernelkit.org/infix/latest/
|
||||
[0]: https://kernelkit.org/posts/flashing-sdcard/
|
||||
[1]: https://kernelkit.org/infix/latest/
|
||||
[2]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-bpi-r3-sdcard.img
|
||||
[3]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-bpi-r3-emmc.img
|
||||
[4]: https://github.com/kernelkit/infix/releases/download/latest-boot/bpi-r3-emmc-boot-2025.01-latest.tar.gz
|
||||
|
||||
@@ -312,13 +312,13 @@ While capable of basic routing tasks, be aware of limitations:
|
||||
For applications requiring multiple ports or high performance, consider
|
||||
dedicated networking hardware like the [Banana Pi R3][12].
|
||||
|
||||
[0]: https://www.kernelkit.org/posts/flashing-sdcard/
|
||||
[1]: https://www.kernelkit.org/infix/latest/
|
||||
[0]: https://kernelkit.org/posts/flashing-sdcard/
|
||||
[1]: https://kernelkit.org/infix/latest/
|
||||
[2]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-rpi64-sdcard.img
|
||||
[3]: https://www.kernelkit.org/infix/latest/container/#content-mounts
|
||||
[4]: https://www.kernelkit.org/infix/latest/scripting-restconf/
|
||||
[3]: https://kernelkit.org/infix/latest/container/#content-mounts
|
||||
[4]: https://kernelkit.org/infix/latest/scripting-restconf/
|
||||
[8]: https://github.com/kernelkit/infix/releases/tag/latest-boot
|
||||
[9]: https://www.kernelkit.org/infix/latest/networking/#wifi
|
||||
[9]: https://kernelkit.org/infix/latest/networking/#wifi
|
||||
[10]: https://www.raspberrypi.com/products/raspberry-pi-touch-display/
|
||||
[11]: https://www.raspberrypi.com/documentation/
|
||||
[12]: https://www.kernelkit.org/infix/latest/hardware/#banana-pi-bpi-r3
|
||||
[12]: https://kernelkit.org/infix/latest/hardware/#banana-pi-bpi-r3
|
||||
|
||||
@@ -112,5 +112,5 @@ Connect a USB-to-serial adapter to the board's debug UART header.
|
||||
> [!WARNING]
|
||||
> Use only 3.3V serial adapters.
|
||||
|
||||
[0]: https://www.kernelkit.org/posts/flashing-sdcard/
|
||||
[0]: https://kernelkit.org/posts/flashing-sdcard/
|
||||
[1]: https://www.microchip.com/en-us/development-tool/EV21H18A
|
||||
|
||||
@@ -91,5 +91,5 @@ Serial settings: 115200 8N1
|
||||
> [!WARNING]
|
||||
> Use only 3.3V serial adapters. 5V adapters will damage your Raspberry Pi!
|
||||
|
||||
[0]: https://www.kernelkit.org/posts/flashing-sdcard/
|
||||
[0]: https://kernelkit.org/posts/flashing-sdcard/
|
||||
[1]: https://www.raspberrypi.com/products/raspberry-pi-2-model-b/
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
|
||||
menu "Images"
|
||||
|
||||
comment "DDI Based"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-ddi/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-ddi-disk/Config.in"
|
||||
|
||||
comment "ITB Based"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-rootfs/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-aux/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-qcow/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-gns3a/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-rauc/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-dl-release/Config.in"
|
||||
|
||||
comment "General"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-barebox-esp/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-lvm-stub/Config.in"
|
||||
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-readme/Config.in"
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
#Simple dracut config for a system without systemd
|
||||
|
||||
#Dracut configuration
|
||||
|
||||
show_modules=yes
|
||||
i18n_install_all=no
|
||||
lvmconf=no
|
||||
mdadmconf=no
|
||||
early_microcode=no
|
||||
hostonly=no
|
||||
hostonly_cmdline=no
|
||||
use_fstab=no
|
||||
kernel_cmdline="rd.break=initqueue"
|
||||
do_strip=no
|
||||
|
||||
# Dracut modules needed
|
||||
add_dracutmodules+=" \
|
||||
busybox \
|
||||
"
|
||||
|
||||
# Modules to ignore
|
||||
omit_dracutmodules+=" \
|
||||
base \
|
||||
bash \
|
||||
biosdevname \
|
||||
btrfs \
|
||||
bluetooth \
|
||||
caps \
|
||||
cifs \
|
||||
connman \
|
||||
crypt \
|
||||
crypt-gpg \
|
||||
dash \
|
||||
dbus-broker \
|
||||
dbus-daemon \
|
||||
dm \
|
||||
dmraid \
|
||||
dmsquash-live-ntfs \
|
||||
dracut-systemd \
|
||||
fcoe \
|
||||
fcoe-uefi \
|
||||
fs-lib \
|
||||
iscsi \
|
||||
i18n \
|
||||
kernel-modules \
|
||||
kernel-modules-extra \
|
||||
lvmmerge \
|
||||
lvm \
|
||||
lunmask \
|
||||
mdraid \
|
||||
memstrack \
|
||||
mksh \
|
||||
modsign \
|
||||
mount-root \
|
||||
multipath \
|
||||
nbd \
|
||||
network-legacy \
|
||||
network-wicked \
|
||||
nfs \
|
||||
nvdimm \
|
||||
nvmf \
|
||||
parse-lunmask \
|
||||
pcsc \
|
||||
qemu \
|
||||
qemu-net \
|
||||
resume \
|
||||
rootfs-block \
|
||||
rngd \
|
||||
shutdown \
|
||||
systemd \
|
||||
systemd-udevd \
|
||||
systemd-coredump \
|
||||
systemd-ask-password \
|
||||
systemd-timedated \
|
||||
systemd-rfkill \
|
||||
systemd-resolved \
|
||||
systemd-hostnamed \
|
||||
systemd-initrd \
|
||||
systemd-integritysetup \
|
||||
systemd-journald \
|
||||
systemd-ldconfig \
|
||||
systemd-networkd \
|
||||
systemd-timesyncd \
|
||||
systemd-veritysetup \
|
||||
systemd-modules-load \
|
||||
systemd-pcrphase \
|
||||
systemd-portabled \
|
||||
systemd-pstore \
|
||||
systemd-sysctl \
|
||||
systemd-repart \
|
||||
systemd-sysext \
|
||||
systemd-sysusers \
|
||||
systemd-tmpfiles \
|
||||
squash \
|
||||
ssh-client \
|
||||
stratis \
|
||||
tpm2-tss \
|
||||
udev-rules \
|
||||
url-lib \
|
||||
usrmount \
|
||||
virtiofs \
|
||||
"
|
||||
@@ -0,0 +1,6 @@
|
||||
config IMAGE_BAREBOX_ESP
|
||||
bool "Barebox EFI System Partition"
|
||||
depends on BR2_TARGET_BAREBOX
|
||||
default y if IMAGE_DDI
|
||||
help
|
||||
An EFI System Partition (ESP) with Barebox installed.
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
case "$BR2_ARCH" in
|
||||
x86_64)
|
||||
BOOT_EFI=BOOTX64.EFI
|
||||
;;
|
||||
*)
|
||||
echo "Unknown EFI boot path for $BR2_ARCH" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
mkdir -p "${WORKDIR}"/root
|
||||
rm -rf "${WORKDIR}"/tmp
|
||||
mkdir -p "${WORKDIR}"/tmp
|
||||
|
||||
cat <<EOF >"${WORKDIR}"/genimage.cfg
|
||||
image barebox-esp.vfat {
|
||||
size = "16M"
|
||||
vfat {
|
||||
file EFI/BOOT/$BOOT_EFI {
|
||||
image = $BINARIES_DIR/barebox.efi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Silence genimage warnings
|
||||
config {}
|
||||
EOF
|
||||
|
||||
genimage \
|
||||
--tmppath "${WORKDIR}"/tmp \
|
||||
--rootpath "${WORKDIR}"/root \
|
||||
--inputpath "${WORKDIR}" \
|
||||
--outputpath "${BINARIES_DIR}" \
|
||||
--config "${WORKDIR}"/genimage.cfg
|
||||
@@ -0,0 +1,7 @@
|
||||
################################################################################
|
||||
#
|
||||
# image-barebox-esp
|
||||
#
|
||||
################################################################################
|
||||
|
||||
$(eval $(ix-image))
|
||||
@@ -0,0 +1,8 @@
|
||||
menuconfig IMAGE_DDI_DISK
|
||||
bool "LVM2 based provisioning disk (DDI)"
|
||||
depends on IMAGE_BAREBOX_ESP
|
||||
depends on IMAGE_DDI
|
||||
help
|
||||
Compose a full disk image consisting of an EFI System
|
||||
Partition (ESP) containing Barebox, and an LVM PV in which
|
||||
Infix is installed as an LV.
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
|
||||
mkdir -p "${WORKDIR}"/root
|
||||
rm -rf "${WORKDIR}"/tmp
|
||||
mkdir -p "${WORKDIR}"/tmp
|
||||
|
||||
"${BR2_EXTERNAL_INFIX_PATH}"/utils/lvm-mkinternal \
|
||||
"${BINARIES_DIR}"/"${ARTIFACT}".raw >"${WORKDIR}"/internal.lvm
|
||||
|
||||
cat <<EOF >"${WORKDIR}"/genimage.cfg
|
||||
|
||||
image ${ARTIFACT}.disk {
|
||||
hdimage {
|
||||
partition-table-type = "gpt"
|
||||
}
|
||||
|
||||
partition esp {
|
||||
partition-type-uuid = "esp"
|
||||
image = "$BINARIES_DIR/barebox-esp.vfat"
|
||||
}
|
||||
|
||||
partition esp-backup {
|
||||
partition-type-uuid = "esp"
|
||||
image = "$BINARIES_DIR/barebox-esp.vfat"
|
||||
}
|
||||
|
||||
partition internal {
|
||||
growfs = "true"
|
||||
partition-type-uuid = "lvm"
|
||||
image = "internal.lvm"
|
||||
}
|
||||
}
|
||||
|
||||
# Silence genimage warnings
|
||||
config {}
|
||||
EOF
|
||||
|
||||
genimage \
|
||||
--tmppath "${WORKDIR}"/tmp \
|
||||
--rootpath "${WORKDIR}"/root \
|
||||
--inputpath "${WORKDIR}" \
|
||||
--outputpath "${BINARIES_DIR}" \
|
||||
--config "${WORKDIR}"/genimage.cfg
|
||||
@@ -0,0 +1,9 @@
|
||||
################################################################################
|
||||
#
|
||||
# image-ddi-disk
|
||||
#
|
||||
################################################################################
|
||||
|
||||
IMAGE_DDI_DISK_DEPENDENCIES := image-barebox-esp image-ddi
|
||||
|
||||
$(eval $(ix-image))
|
||||
@@ -0,0 +1,33 @@
|
||||
menuconfig IMAGE_DDI
|
||||
bool "Discoverable Disk Image (DDI)"
|
||||
select BR2_TARGET_ROOTFS_SQUASHFS
|
||||
select BR2_PACKAGE_HOST_GENIMAGE
|
||||
help
|
||||
Create a Discoverable Disk Image containing:
|
||||
- SquashFS of the root filesystem
|
||||
- dm-verity hash tree of the root filesystem
|
||||
- DDI compliant JSON signature object of the hash tree
|
||||
|
||||
https://uapi-group.org/specifications/specs/discoverable_disk_image/
|
||||
|
||||
config IMAGE_DDI_KEY
|
||||
string "signing key"
|
||||
depends on IMAGE_DDI
|
||||
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.key"
|
||||
help
|
||||
Path to the private RSA key, in PKCS#8 format, used to sign
|
||||
the dm-verity hash tree.
|
||||
|
||||
config IMAGE_DDI_CERT
|
||||
string "signing cert"
|
||||
depends on IMAGE_DDI
|
||||
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.crt"
|
||||
help
|
||||
Path to the X509 certificate whose associated public key can
|
||||
validate the authenticity of the generated signature.
|
||||
|
||||
The SHA256 fingerprint of this certificate is recorded
|
||||
alongside the standard PKCS#7 signature in the JSON object,
|
||||
which can be useful to locate corresponding key on systems
|
||||
that lack full X509 parsing capabilities.
|
||||
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Generate the DDI in two phases. First we create the verity hash tree
|
||||
# and signature, then we collect them together with the rootfs in the
|
||||
# ddi. The reason for this is that genimage (at least up to v19) can
|
||||
# not infer the size of a partition if the image to be placed in it is
|
||||
# created by the same genimage instance. With the two-phase approach,
|
||||
# we work around that problem and can create a DDI without any wasted
|
||||
# space.
|
||||
|
||||
set -e
|
||||
|
||||
rm -rf "${WORKDIR}"/tmp
|
||||
mkdir -p "${WORKDIR}"/tmp "${WORKDIR}"/verity
|
||||
|
||||
cat <<EOF >"${WORKDIR}"/genimage-verity.cfg
|
||||
image rootfs.verity {
|
||||
verity {
|
||||
image = "rootfs.squashfs"
|
||||
}
|
||||
}
|
||||
|
||||
image rootfs.verity-sig {
|
||||
verity-sig {
|
||||
image = "rootfs.verity"
|
||||
cert = "${CERT}"
|
||||
key = "${KEY}"
|
||||
}
|
||||
}
|
||||
|
||||
config {}
|
||||
EOF
|
||||
|
||||
genimage \
|
||||
--loglevel 1 \
|
||||
--tmppath "${WORKDIR}"/tmp \
|
||||
--rootpath "${WORKDIR}" \
|
||||
--inputpath "${BINARIES_DIR}" \
|
||||
--outputpath "${WORKDIR}"/verity \
|
||||
--config "${WORKDIR}"/genimage-verity.cfg
|
||||
|
||||
case "${BR2_ARCH}" in
|
||||
"x86_64")
|
||||
arch=x86-64
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: missing mapping from ${BR2_ARCH} to genimage arch" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
cat <<EOF >"${WORKDIR}"/genimage-ddi.cfg
|
||||
image ${ARTIFACT}.raw {
|
||||
hdimage {
|
||||
partition-table-type = "gpt"
|
||||
}
|
||||
|
||||
partition root {
|
||||
partition-type-uuid = "root-${arch}"
|
||||
image = "rootfs.squashfs"
|
||||
}
|
||||
partition root-verity {
|
||||
partition-type-uuid = "root-${arch}-verity"
|
||||
image = "${WORKDIR}/verity/rootfs.verity"
|
||||
}
|
||||
partition root-verity-sig {
|
||||
partition-type-uuid = "root-${arch}-verity-sig"
|
||||
image = "${WORKDIR}/verity/rootfs.verity-sig"
|
||||
}
|
||||
}
|
||||
|
||||
config {}
|
||||
EOF
|
||||
|
||||
genimage \
|
||||
--loglevel 1 \
|
||||
--tmppath "${WORKDIR}"/tmp \
|
||||
--rootpath "${WORKDIR}" \
|
||||
--inputpath "${BINARIES_DIR}" \
|
||||
--outputpath "${BINARIES_DIR}" \
|
||||
--config "${WORKDIR}"/genimage-ddi.cfg
|
||||
@@ -0,0 +1,32 @@
|
||||
image rootfs.verity {
|
||||
verity {
|
||||
image = "rootfs.squashfs"
|
||||
}
|
||||
}
|
||||
|
||||
image rootfs.verity-sig {
|
||||
verity-sig {
|
||||
image = "rootfs.verity"
|
||||
cert = "@CERT@"
|
||||
key = "@KEY@"
|
||||
}
|
||||
}
|
||||
|
||||
image @ARTIFACT@.raw {
|
||||
hdimage {
|
||||
partition-table-type = "gpt"
|
||||
}
|
||||
|
||||
partition root {
|
||||
partition-type-uuid = "root-@ARCH@"
|
||||
image = "rootfs.squashfs"
|
||||
}
|
||||
partition root-verity {
|
||||
partition-type-uuid = "root-@ARCH@-verity"
|
||||
image = "rootfs.verity"
|
||||
}
|
||||
partition root-verity-sig {
|
||||
partition-type-uuid = "root-@ARCH@-verity-sig"
|
||||
image = "rootfs.verity-sig"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
################################################################################
|
||||
#
|
||||
# image-ddi
|
||||
#
|
||||
################################################################################
|
||||
|
||||
IMAGE_DDI_DEPENDENCIES := host-genimage rootfs-squashfs
|
||||
IMAGE_DDI_CONFIG_VARS := KEY CERT
|
||||
|
||||
$(eval $(ix-image))
|
||||
@@ -0,0 +1,15 @@
|
||||
tmpfs /tmp tmpfs mode=0755,nosuid,nodev 0 0
|
||||
tmpfs /run tmpfs mode=0755,nosuid,nodev 0 0
|
||||
tmpfs /media tmpfs mode=1755,nosuid,nodev 0 0
|
||||
tmpfs /mnt/tmp tmpfs defaults 0 0
|
||||
|
||||
# Locate and mount /cfg, /home, /root and /var from the internal
|
||||
# volume, wherever that is located - or, as a last resort, setup tmpfs
|
||||
# mounts at these points. Setup an ephemeral writable overlay on /etc.
|
||||
/usr/libexec/infix/mnt# /mnt/rw helper none 0 0
|
||||
|
||||
# Optional, nice-to-have mounts
|
||||
debugfs /sys/kernel/debug debugfs nofail 0 0
|
||||
tracefs /sys/kernel/tracing tracefs nofail 0 0
|
||||
cfgfs /config configfs nofail,noauto 0 0
|
||||
host /mnt/host 9p nofail,noauto,cache=none,msize=16384 0 0
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
#!/bin/sh
|
||||
# Called from /etc/fstab to ensure we have something writable mounted
|
||||
# at /cfg, /home, /root, and /var.
|
||||
#
|
||||
# In the normal case, the "rw" LV from the "internal" LVM VG is used
|
||||
# to back all persistant storage. In the event that "internal" is
|
||||
# present, but the "rw" LV is missing, one will be provisioned, along
|
||||
# with the required BTRFS subvolumes.
|
||||
#
|
||||
# In all other scenarios where the subvolumes are not available, the
|
||||
# system will fall back to temporary storage for all mount points.
|
||||
#
|
||||
# For /etc, a writable, tmpfs backed, layer is always overlayed on top
|
||||
# of the read-only contents from the OS image.
|
||||
|
||||
set -e
|
||||
|
||||
nm=$(basename "$0")
|
||||
need_restore=
|
||||
code=0
|
||||
|
||||
logmsg()
|
||||
{
|
||||
logger -k -t "$nm" -p user.crit "$@"
|
||||
}
|
||||
|
||||
status()
|
||||
{
|
||||
GREEN="$(printf '\033[1;32m')"
|
||||
RED="$(printf '\033[1;31m')"
|
||||
YELLOW="$(printf '\033[1;33m')"
|
||||
BOLD="$(printf '\033[1m')"
|
||||
RESET="$(printf '\033[0m')"
|
||||
|
||||
case $1 in
|
||||
0) color=$GREEN; text=' OK ' ;;
|
||||
1) color=$RED; text='FAIL' ;;
|
||||
2) color=$YELLOW;text='WARN' ;;
|
||||
*) color=$YELLOW;text=' ⋯ ' ;;
|
||||
esac
|
||||
|
||||
printf '%s[%s%s%s%s]%s ' "$BOLD" "$color" "$text" "$RESET" "$BOLD" "$RESET"
|
||||
}
|
||||
|
||||
print_start()
|
||||
{
|
||||
printf '\r\033[K%s%s' "$(status 3)" "$*" > /dev/console
|
||||
need_restore=YES
|
||||
}
|
||||
|
||||
print_end()
|
||||
{
|
||||
rc=$1; shift
|
||||
if [ $# -gt 0 ]; then
|
||||
printf '\r\033[K%s%s\n' "$(status "$rc")" "$*" > /dev/console
|
||||
else
|
||||
printf '\r%s\n' "$(status "$rc")" > /dev/console
|
||||
fi
|
||||
}
|
||||
|
||||
# Restore Finit's original progress message so its [ OK ] appears correctly
|
||||
print_restore()
|
||||
{
|
||||
[ "$need_restore" ] || return 0
|
||||
print_start "Mounting filesystems from /etc/fstab"
|
||||
}
|
||||
|
||||
# # External button or bootloader changed kernel command line
|
||||
# check_factory()
|
||||
# {
|
||||
# if [ -f /mnt/cfg/infix/.reset ]; then
|
||||
# return 0;
|
||||
# fi
|
||||
|
||||
# if grep -q 'finit.cond=factory-reset' /proc/cmdline; then
|
||||
# return 0;
|
||||
# fi
|
||||
|
||||
# # Add to your br2-external to extend factory-reset check
|
||||
# if [ ! -x /usr/libexec/infix/check-factory ]; then
|
||||
# return 1;
|
||||
# fi
|
||||
|
||||
# /usr/libexec/infix/check-factory
|
||||
# }
|
||||
|
||||
# factory_reset()
|
||||
# {
|
||||
# find /sys/class/leds/ -type l -exec sh -c 'echo 100 > $0/brightness' {} \;
|
||||
# print_start "Resetting to factory defaults."
|
||||
# logger $opt -p user.notice -t "$nm" "Resetting to factory defaults."
|
||||
|
||||
# rm -rf /mnt/cfg/* /mnt/var/*
|
||||
# sync
|
||||
|
||||
# logger $opt -p user.notice -t "$nm" "Factory reset complete."
|
||||
# print_end 0 "Factory reset complete."
|
||||
# print_restore
|
||||
# }
|
||||
|
||||
subvols="cfg var root home"
|
||||
|
||||
internal_rw_provision()
|
||||
{
|
||||
print_start "Provisioning persistent storage on internal volume"
|
||||
|
||||
lvm lvcreate --name rw --extents 50%FREE internal || {
|
||||
logmsg "No rw LV available, nor could it be created"
|
||||
print_end 1
|
||||
return 1
|
||||
}
|
||||
|
||||
mkfs.btrfs -L rw /dev/internal/rw || {
|
||||
logmsg "Could not create BTRFS on rw LV"
|
||||
print_end 1
|
||||
return 1
|
||||
}
|
||||
|
||||
mount -t btrfs /dev/internal/rw /mnt/rw || {
|
||||
logmsg "Failed to mount rw"
|
||||
print_end 1
|
||||
return 1
|
||||
}
|
||||
|
||||
for subvol in $subvols; do
|
||||
btrfs subvolume create /mnt/rw/@"$subvol" || {
|
||||
logmsg "Failed to create @$subvol on rw"
|
||||
print_end 1
|
||||
return 1
|
||||
}
|
||||
done
|
||||
|
||||
umount /mnt/rw || {
|
||||
logmsg "Failed to unmount rw"
|
||||
print_end 1
|
||||
return 1
|
||||
}
|
||||
|
||||
print_end 0
|
||||
}
|
||||
|
||||
internal_rw_activate()
|
||||
{
|
||||
lvm vgs internal || {
|
||||
logmsg "No internal volume available"
|
||||
return 1
|
||||
}
|
||||
|
||||
lvm vgchange -ay internal || {
|
||||
logmsg "Unable to bring internal volume online"
|
||||
return 1
|
||||
}
|
||||
|
||||
# The only condition under which we do BTRFS provisioning is when
|
||||
# the LV is absent. In all other failure scenarios: fall back to
|
||||
# tmpfs and let the user sort it out. This way we do not risk any
|
||||
# loss of data.
|
||||
[ -b /dev/internal/rw ] && return 0
|
||||
|
||||
internal_rw_provision
|
||||
}
|
||||
|
||||
internal_rw_mount()
|
||||
{
|
||||
internal_rw_activate || return 1
|
||||
|
||||
for subvol in $subvols; do
|
||||
mount -t btrfs /dev/internal/rw /"$subvol" -o subvol=@"$subvol" || {
|
||||
logmsg "Failed to mount /$subvol"
|
||||
return 1
|
||||
}
|
||||
done
|
||||
}
|
||||
|
||||
tmpfs_rw_mount()
|
||||
{
|
||||
for subvol in $subvols; do
|
||||
mkdir -p -m 0755 /mnt/tmp/"$subvol"
|
||||
mount /mnt/tmp/"$subvol" /"$subvol" -o bind || {
|
||||
logmsg "Failed to mount temporary /$subvol"
|
||||
return 1
|
||||
}
|
||||
done
|
||||
}
|
||||
|
||||
tmpfs_etc_mount()
|
||||
{
|
||||
mkdir -p -m 0755 /mnt/tmp/etc/
|
||||
tar c -C /etc . | tar x -C /mnt/tmp/etc
|
||||
mount /mnt/tmp/etc /etc -o bind
|
||||
}
|
||||
|
||||
exec >/mnt/tmp/mnt.log 2>&1
|
||||
|
||||
tmpfs_etc_mount || {
|
||||
code=1
|
||||
logmsg "Failed to make /etc writable"
|
||||
}
|
||||
|
||||
if ! internal_rw_mount; then
|
||||
code=1
|
||||
print_end 1 "Mounting persistent storage from internal volume"
|
||||
logmsg "Internal volume not found, falling back to tmpfs"
|
||||
|
||||
print_start "Falling back to ephemeral tmpfs storage!"
|
||||
tmpfs_rw_mount
|
||||
print_end $?
|
||||
fi
|
||||
|
||||
print_restore
|
||||
exit $code
|
||||
@@ -12,7 +12,7 @@ cat <<EOF >"${gns3a}"
|
||||
"category": "router",
|
||||
"description": "${ARTIFACT} development appliance",
|
||||
"vendor_name": "Kernelkit",
|
||||
"vendor_url": "https://www.kernelkit.org",
|
||||
"vendor_url": "https://kernelkit.org",
|
||||
"product_name": "${ARTIFACT} devel",
|
||||
"registry_version": 6,
|
||||
"status": "experimental",
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
config IMAGE_LVM_STUB
|
||||
bool "LVM2 stub image"
|
||||
default y if IMAGE_DDI
|
||||
help
|
||||
An empty LVM2 physical volume attached to the internal
|
||||
volume group. This is useful as a base image for persistent
|
||||
storage in QEMU emulation scenarios where the OS is supplied
|
||||
in a separate image.
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
|
||||
mkdir -p "${WORKDIR}"/root
|
||||
rm -rf "${WORKDIR}"/tmp
|
||||
mkdir -p "${WORKDIR}"/tmp
|
||||
|
||||
"${BR2_EXTERNAL_INFIX_PATH}"/utils/lvm-mkinternal >"${WORKDIR}"/stub.lvm
|
||||
|
||||
cat <<EOF >"${WORKDIR}"/genimage.cfg
|
||||
image lvm-stub.disk {
|
||||
hdimage {
|
||||
partition-table-type = "gpt"
|
||||
}
|
||||
|
||||
partition internal {
|
||||
growfs = "true"
|
||||
image = "stub.lvm"
|
||||
partition-type-uuid = "lvm"
|
||||
}
|
||||
}
|
||||
|
||||
# Silence genimage warnings
|
||||
config {}
|
||||
EOF
|
||||
|
||||
genimage \
|
||||
--tmppath "${WORKDIR}"/tmp \
|
||||
--rootpath "${WORKDIR}"/root \
|
||||
--inputpath "${WORKDIR}" \
|
||||
--outputpath "${BINARIES_DIR}" \
|
||||
--config "${WORKDIR}"/genimage.cfg
|
||||
@@ -0,0 +1,7 @@
|
||||
################################################################################
|
||||
#
|
||||
# image-lvm-stub
|
||||
#
|
||||
################################################################################
|
||||
|
||||
$(eval $(ix-image))
|
||||
@@ -50,7 +50,7 @@ The default credentials for the demo builds is
|
||||
Password:
|
||||
.-------.
|
||||
| . . | Infix OS — Immutable.Friendly.Secure
|
||||
|-. v .-| https://www.kernelkit.org
|
||||
|-. v .-| https://kernelkit.org
|
||||
'-'---'-'
|
||||
|
||||
Run the command 'cli' for interactive OAM
|
||||
|
||||
@@ -10,6 +10,7 @@ $(1): $$($(2)_DEPENDENCIES)
|
||||
PKGDIR=$$($(2)_DIR) \
|
||||
WORKDIR=$$(BUILD_DIR)/$(1) \
|
||||
BINARIES_DIR=$$(BINARIES_DIR) \
|
||||
BR2_ARCH=$$(BR2_ARCH) \
|
||||
BR2_EXTERNAL_INFIX_PATH=$$(BR2_EXTERNAL_INFIX_PATH) \
|
||||
ARTIFACT=$$(INFIX_ARTIFACT) \
|
||||
COMPATIBLE=$$(INFIX_COMPATIBLE) \
|
||||
@@ -19,6 +20,7 @@ $(1): $$($(2)_DEPENDENCIES)
|
||||
|
||||
ifeq ($$($(2)),y)
|
||||
TARGETS_ROOTFS += $(1)
|
||||
BR2_ROOTFS_OVERLAY := "$$(realpath $$(pkgdir)/rootfs) $$(call qstrip,$$(BR2_ROOTFS_OVERLAY))"
|
||||
endif
|
||||
|
||||
endef
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
check() {
|
||||
return 0
|
||||
}
|
||||
|
||||
depends() {
|
||||
return 0
|
||||
}
|
||||
|
||||
install() {
|
||||
# Not sure if this should be handled by buildroot's merged-usr
|
||||
# module. Fix it here for now.
|
||||
ln -s "lib" "${initdir?}/lib64"
|
||||
}
|
||||
Executable
+279
@@ -0,0 +1,279 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo -ne "\e[31m●\e[0m \e[33m●\e[0m \e[32m●\e[0m Infix Initramfs — " >/dev/console
|
||||
source /etc/os-release >/dev/console
|
||||
echo "$VERSION"
|
||||
|
||||
set -e
|
||||
|
||||
getkopt()
|
||||
{
|
||||
grep -q -E "(^| )$1( |$)" /proc/cmdline
|
||||
}
|
||||
|
||||
getkparam()
|
||||
{
|
||||
sed -n "s/.*\<$1=\([^ ]*\).*/\1/p" /proc/cmdline
|
||||
}
|
||||
|
||||
debug_shell()
|
||||
{
|
||||
[ "$(getkparam rd.shell)" = "$1" ] || return 0
|
||||
|
||||
exec </dev/console &>/dev/console
|
||||
echo "Starting debug shell at $1"
|
||||
exec sh -i
|
||||
}
|
||||
|
||||
die()
|
||||
{
|
||||
step="${*:-$step}"
|
||||
|
||||
echo -e "\r\e[0K[\e[31mFAIL\e[0m] $step" >/dev/console
|
||||
echo "<0>ix-initramfs: ERROR: $step" >/dev/kmsg
|
||||
debug_shell error
|
||||
exit 1
|
||||
}
|
||||
|
||||
warn()
|
||||
{
|
||||
step="${*:-$step}"
|
||||
|
||||
echo -e "\r\e[0K[\e[33mWARN\e[0m] $step" >/dev/console
|
||||
echo "<5>ix-initramfs: WARNING: $step" >/dev/kmsg
|
||||
debug_shell warning
|
||||
}
|
||||
|
||||
ok()
|
||||
{
|
||||
step="${*:-$step}"
|
||||
|
||||
echo -e "\r\e[0K[\e[32m OK \e[0m] $step" >/dev/console
|
||||
echo "<5>ix-initramfs: $step" >/dev/kmsg
|
||||
}
|
||||
|
||||
begin()
|
||||
{
|
||||
step="$*"
|
||||
echo -ne "[\e[33m ⋯ \e[0m] $step" >/dev/console
|
||||
}
|
||||
|
||||
debug()
|
||||
{
|
||||
echo "<7>ix-initramfs: $*" >/dev/kmsg
|
||||
}
|
||||
|
||||
mountcore()
|
||||
{
|
||||
mount -t proc proc /proc
|
||||
mount -t sysfs sys /sys
|
||||
mount -t devtmpfs dev /dev
|
||||
}
|
||||
|
||||
mountroot()
|
||||
{
|
||||
mkdir /newroot
|
||||
mount "$1" /newroot || \
|
||||
die "Unable to mount rootfs on $1"
|
||||
|
||||
ok "Mounting root filesystem on $(basename $1)"
|
||||
}
|
||||
|
||||
switchroot()
|
||||
{
|
||||
local innerinit=$(getkparam init)
|
||||
|
||||
ok "Switching to root filesystem"
|
||||
exec switch_root /newroot ${innerinit:-/sbin/init}
|
||||
}
|
||||
|
||||
internal_get_part()
|
||||
{
|
||||
local _i _pv
|
||||
|
||||
for _i in $(seq 50); do
|
||||
_pv=$(lvm pvs --reportformat json \
|
||||
| jq -r '.report[].pv[] | select(.vg_name == "internal") | .pv_name')
|
||||
if [ "$_pv" ]; then
|
||||
[ $_i -gt 5 ] && ok
|
||||
echo "$_pv"
|
||||
return 0
|
||||
fi
|
||||
|
||||
[ $_i -eq 5 ] && begin "Waiting for the internal volume to come online"
|
||||
sleep .2
|
||||
done
|
||||
|
||||
warn "Proceeding without the internal volume"
|
||||
return 0
|
||||
}
|
||||
|
||||
internal_inflate()
|
||||
{
|
||||
local _dev _growfs _index _part
|
||||
|
||||
getkopt rd.nointernal && return 0
|
||||
|
||||
GPT_PART_GROWFS_BIT=59
|
||||
|
||||
_part=$(internal_get_part)
|
||||
[ "$_part" ] || return 0
|
||||
|
||||
_index=$(cat /sys/class/block/$(basename "$_part")/partition)
|
||||
[ "$_index" ] || return 1
|
||||
|
||||
_dev=/dev/$(basename $(realpath /sys/class/block/$(basename "$_part")/../))
|
||||
[ -b "$_dev" ] || return 1
|
||||
|
||||
sgdisk "$_dev" -A "$_index":get:$GPT_PART_GROWFS_BIT \
|
||||
| grep -q "$_index:$GPT_PART_GROWFS_BIT:1" \
|
||||
|| return 0
|
||||
|
||||
begin "Inflating internal VG in $_part"
|
||||
|
||||
# First, expand the GPT to cover the entire disk and expand the
|
||||
# LVM partition as much as possible.
|
||||
if ! sgdisk "$_dev" \
|
||||
--disk-guid=random \
|
||||
--set-alignment=1 \
|
||||
--move-second-header \
|
||||
--delete="$_index" \
|
||||
--largest-new="$_index" --typecode="$_index":8e00 \
|
||||
>/tmp/internal-inflate.log 2>&1; then
|
||||
warn "Failed to inflate GPT on $_dev"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! lvm pvresize "$_part" >>/tmp/internal-inflate.log 2>&1; then
|
||||
warn "Failed to resize PV $_part"
|
||||
return 0
|
||||
fi
|
||||
|
||||
ok "Inflated internal VG in $_part"
|
||||
}
|
||||
|
||||
addparts()
|
||||
{
|
||||
local _disk="$1"
|
||||
local _partscan="/sys/class/block/"$(basename "$_disk")/partscan
|
||||
|
||||
[ -f "$_partscan" ] && [ $(cat "$_partscan") -eq 1 ] && return
|
||||
|
||||
kpartx -a "$_disk" 2>/dev/null || die "addparts: Unable to add partitions from $_disk"
|
||||
}
|
||||
|
||||
gptuuid_probe()
|
||||
{
|
||||
local _uuid=$(echo "$1" | sed -e 's/^GPTUUID=//' | tr ABCDEF abcdef)
|
||||
local _cand _disk _initrd
|
||||
|
||||
[ -f /initrd.image ] && _initrd=/initrd.image
|
||||
|
||||
for _disk in $_initrd $(find /dev/ -type b); do
|
||||
_cand=$(ddi "$_disk" inspect uuid | tr ABCDEF abcdef)
|
||||
[ $? -eq 0 ] || continue
|
||||
|
||||
if [ "$_cand" = "$_uuid" ]; then
|
||||
ok "Located $_uuid in $_disk"
|
||||
echo "$_disk"
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
die "gptuuid_probe: Unable to find disk $_uuid"
|
||||
}
|
||||
|
||||
ddi_probe()
|
||||
{
|
||||
local _disk="$1"
|
||||
local _dm="$(basename $_disk).root"
|
||||
local _hash=$(getkparam rd.ddi.roothash)
|
||||
local _v _trust
|
||||
|
||||
if [ -n "$_hash" ]; then
|
||||
ok "Trusting pre-authenticated root hash"
|
||||
_v="-V $_hash"
|
||||
else
|
||||
_v="-v"
|
||||
fi
|
||||
|
||||
_trust=$(ddi "$_disk" part root open $_v "$_dm" 2>&1 \
|
||||
|| die "ddi_probe: veritysetup of $_disk failed")
|
||||
|
||||
ok "$_trust"
|
||||
ok "Opened verity protected root from $(basename $_disk)"
|
||||
echo /dev/mapper/"$_dm"
|
||||
}
|
||||
|
||||
lvm_probe()
|
||||
{
|
||||
local _vg=$(dirname "$1") _lv=$(basename "$1")
|
||||
|
||||
lvm vgchange -ay "$_vg" &>/dev/null || \
|
||||
die "lvm_probe: Failed to activate the $_vg VG"
|
||||
|
||||
[ -b /dev/"$1" ] || die "lvm_probe: Unable to locate the $_lv LV in $_vg"
|
||||
|
||||
echo /dev/"$1"
|
||||
}
|
||||
|
||||
lo_probe()
|
||||
{
|
||||
local _lo=$(losetup -f || die "probe_lo: found no free loop device for $1")
|
||||
losetup -P "$_lo" "$1" || die "probe_lo: losetup of $1 to $_lo failed"
|
||||
|
||||
debug "lo_probe: setup $_lo backed by $1"
|
||||
echo "$_lo"
|
||||
}
|
||||
|
||||
probe()
|
||||
{
|
||||
local _real _kind
|
||||
|
||||
case "$1" in
|
||||
/*)
|
||||
_real=$(realpath "$1")
|
||||
_kind=$(stat -c %F "$_real" 2>/dev/null || true)
|
||||
case "$_kind" in
|
||||
"block special file")
|
||||
addparts "$_real"
|
||||
echo "$_real"
|
||||
;;
|
||||
"regular file")
|
||||
lo_probe "$_real"
|
||||
;;
|
||||
"")
|
||||
die "Unknown root \"$1\""
|
||||
;;
|
||||
*)
|
||||
die "Unsupported root \"$1\": $_kind"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
lvm)
|
||||
shift
|
||||
probe $(lvm_probe "$@")
|
||||
;;
|
||||
ddi)
|
||||
shift
|
||||
ddi_probe $(probe "$@")
|
||||
;;
|
||||
GPTUUID=*)
|
||||
gptuuid_probe "$@"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
mountcore
|
||||
|
||||
debug_shell internal
|
||||
internal_inflate
|
||||
|
||||
debug_shell probe
|
||||
rootdev=$(probe $(getkparam root | sed -e 's/:/ /g'))
|
||||
|
||||
debug_shell mount
|
||||
mountroot "$rootdev"
|
||||
|
||||
debug_shell switchroot
|
||||
switchroot
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
progs="blkid ddi dmsetup kpartx jq lvm openssl sgdisk veritysetup"
|
||||
|
||||
check() {
|
||||
require_binaries $progs || return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
depends() {
|
||||
return 0
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_multiple $progs
|
||||
inst '/etc/os-release'
|
||||
inst '/etc/rauc/keys/*'
|
||||
|
||||
cp "$moddir/init" "${initdir?}/init"
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
mainmenu "QEMU @ARCH@ Virtualization"
|
||||
|
||||
config QEMU_@ARCH@
|
||||
bool
|
||||
default y
|
||||
|
||||
config QEMU_ARCH
|
||||
string
|
||||
default "@ARCH@"
|
||||
|
||||
config QEMU_VIRTIO_BUS
|
||||
string
|
||||
default "device" if QEMU_arm
|
||||
default "pci"
|
||||
|
||||
config QEMU_BIN_DDI
|
||||
string
|
||||
default "@IMAGE@"
|
||||
|
||||
config QEMU_BIN_DISK
|
||||
string
|
||||
default "@DISK@"
|
||||
|
||||
config QEMU_BIN_ESP
|
||||
string
|
||||
default "@ESP@"
|
||||
|
||||
config QEMU_BIN_KERNEL
|
||||
string
|
||||
depends on QEMU_LOADER_QEMU
|
||||
default "../zImage" if QEMU_arm
|
||||
default "../Image" if QEMU_aarch64
|
||||
default "../bzImage" if QEMU_x86_64
|
||||
|
||||
config QEMU_BIN_LVM_STUB
|
||||
string
|
||||
default "../lvm-stub.disk"
|
||||
|
||||
|
||||
choice
|
||||
prompt "Loader"
|
||||
default QEMU_LOADER_QEMU
|
||||
|
||||
config QEMU_LOADER_QEMU
|
||||
bool "QEMU"
|
||||
|
||||
config QEMU_LOADER_OVMF
|
||||
bool "OVMF (UEFI)"
|
||||
|
||||
endchoice
|
||||
|
||||
config QEMU_BIN_BIOS
|
||||
string
|
||||
depends on !QEMU_LOADER_KERNEL
|
||||
default "OVMF.fd" if QEMU_LOADER_OVMF
|
||||
|
||||
menu "Machine"
|
||||
|
||||
config QEMU_MACHINE
|
||||
string "Machine"
|
||||
default "pc" if QEMU_x86_64
|
||||
default "virt"
|
||||
|
||||
config QEMU_CPU
|
||||
string "CPU"
|
||||
default "host" if QEMU_x86_64
|
||||
default "cortex-a53" if QEMU_aarch64
|
||||
default "max"
|
||||
|
||||
config QEMU_RAM
|
||||
string "RAM size (k/M/G)"
|
||||
default "384M"
|
||||
|
||||
choice
|
||||
prompt "Console"
|
||||
default QEMU_CONSOLE_VIRTIO
|
||||
|
||||
config QEMU_CONSOLE_VIRTIO
|
||||
bool "Virtio (hvc0)"
|
||||
|
||||
config QEMU_CONSOLE_SERIAL
|
||||
bool "Serial (ttyS0/ttyAMA0)"
|
||||
|
||||
endchoice
|
||||
|
||||
config QEMU_CONSOLE
|
||||
string
|
||||
default "hvc0" if QEMU_CONSOLE_VIRTIO
|
||||
default "ttyAMA0" if QEMU_arm
|
||||
default "ttyAMA0" if QEMU_aarch64
|
||||
default "ttyS0"
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Disks & Filesystems"
|
||||
|
||||
config QEMU_DISK_INITRD
|
||||
bool "Use the DDI as initrd"
|
||||
depends on QEMU_LOADER_QEMU
|
||||
help
|
||||
Pass, and boot from, the DDI as the initial RAM disk.
|
||||
|
||||
This is useful to test netbooting scenarios, e.g., in
|
||||
combination with an empty system disk to simulate an initial
|
||||
deployment.
|
||||
|
||||
comment "System disk"
|
||||
|
||||
choice
|
||||
prompt "Interface"
|
||||
default QEMU_DISK_SYS_IF_VIRTIO
|
||||
|
||||
config QEMU_DISK_SYS_IF_VIRTIO
|
||||
bool "virtio"
|
||||
help
|
||||
Attach system disks using virtio block devices.
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Contents"
|
||||
default QEMU_DISK_SYS_SPLIT
|
||||
|
||||
config QEMU_DISK_SYS_EMPTY
|
||||
bool "Empty disk"
|
||||
help
|
||||
Attach an empty disk.
|
||||
|
||||
This is useful for testing things like installing Infix from a
|
||||
USB mass storage device (see "USB Mass Storage" below).
|
||||
|
||||
config QEMU_DISK_SYS_FULL
|
||||
bool "Full system disk"
|
||||
help
|
||||
Use the full system disk containing:
|
||||
- EFI partition (and backup) with Barebox
|
||||
- LVM PV with Infix installed
|
||||
|
||||
This is useful when testing system upgrades, fallback
|
||||
mechanisms related to corrupt disks etc.
|
||||
|
||||
WARNING: Usage of this option is fraught with peril as
|
||||
incremental builds of Infix are likely to cause corruption in
|
||||
the QCoW2 layer. If you do not understand the meaning of this
|
||||
you most likely to NOT want to make use of this feature.
|
||||
|
||||
config QEMU_DISK_SYS_NONE
|
||||
bool "None"
|
||||
help
|
||||
Do not attach any system disk.
|
||||
|
||||
This is useful for testing how Infix behaves when no persistent
|
||||
storage is available - a common scenario during bringup of a
|
||||
new board.
|
||||
|
||||
config QEMU_DISK_SYS_SPLIT
|
||||
bool "Split ESP/DDI/LVM"
|
||||
help
|
||||
Attach the EFI System partition, containing Barebox; the raw
|
||||
DDI image; and an (initially empty) LVM stub for persistent
|
||||
storage - each as a separate disk.
|
||||
|
||||
This is the simplest way of testing out incremental builds of
|
||||
Infix. Since the DDI is attached as a raw read-only disk, there
|
||||
is no risk of CoW corruption like with a full system disk.
|
||||
|
||||
NOTE: In this setup, the size below refers to the size of the
|
||||
LVM stub.
|
||||
|
||||
endchoice
|
||||
|
||||
config QEMU_DISK_SYS_SIZE
|
||||
string "Size (k/M/G)"
|
||||
default "8G"
|
||||
|
||||
comment "USB mass storage"
|
||||
|
||||
choice
|
||||
prompt "Contents"
|
||||
default QEMU_DISK_USB_NONE
|
||||
|
||||
config QEMU_DISK_USB_DISK
|
||||
bool "Full system disk"
|
||||
help
|
||||
Attach the full system disk containing:
|
||||
- EFI partition (and backup) with Barebox
|
||||
- LVM PV with Infix installed
|
||||
|
||||
config QEMU_DISK_USB_NONE
|
||||
bool "None"
|
||||
help
|
||||
Do not attach any disk over USB.
|
||||
|
||||
endchoice
|
||||
|
||||
config QEMU_DISK_USB_SIZE
|
||||
string "Size (k/M/G)"
|
||||
depends on !QEMU_DISK_USB_NONE
|
||||
default "4G"
|
||||
|
||||
comment "Host filesystem passthrough (9P)"
|
||||
|
||||
config QEMU_DISK_HOST
|
||||
string "Path"
|
||||
default "/tmp"
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Networking"
|
||||
|
||||
choice
|
||||
prompt "Mode"
|
||||
default QEMU_NET_USER
|
||||
|
||||
config QEMU_NET_BRIDGE
|
||||
bool "Bridged"
|
||||
|
||||
config QEMU_NET_NONE
|
||||
bool "None"
|
||||
|
||||
config QEMU_NET_ROCKER
|
||||
bool "Rocker"
|
||||
|
||||
config QEMU_NET_TAP
|
||||
bool "TAP"
|
||||
|
||||
config QEMU_NET_USER
|
||||
bool "User"
|
||||
|
||||
endchoice
|
||||
|
||||
config QEMU_NET_MODE
|
||||
string
|
||||
default "bridge" if QEMU_NET_BRIDGE
|
||||
default "none" if QEMU_NET_NONE
|
||||
default "rocker" if QEMU_NET_ROCKER
|
||||
default "tap" if QEMU_NET_TAP
|
||||
default "user" if QEMU_NET_USER
|
||||
|
||||
config QEMU_NET_MODEL
|
||||
string "Interface model"
|
||||
default "virtio-net-device" if QEMU_arm
|
||||
default "virtio-net-pci"
|
||||
help
|
||||
The default virtio NIC works for most use-cases, but if you
|
||||
want to play with low-level stuff like ethtool, you might
|
||||
want to test the Intel 82545EM driver, e1000.
|
||||
|
||||
Note: ARM 32-bit uses virtio-net-device (MMIO) by default.
|
||||
|
||||
config QEMU_NET_BRIDGE_DEV
|
||||
string "Bridge device"
|
||||
depends on QEMU_NET_BRIDGE
|
||||
default "virbr0"
|
||||
|
||||
config QEMU_NET_USER_OPTS
|
||||
string "User mode options"
|
||||
depends on QEMU_NET_USER
|
||||
help
|
||||
Extra -nic user,<OPTIONS>
|
||||
|
||||
config QEMU_NET_TAP_N
|
||||
int "Number of TAPs"
|
||||
depends on QEMU_NET_TAP
|
||||
default 1
|
||||
|
||||
config QEMU_NET_PORTS
|
||||
int "Number of Rocker switch ports"
|
||||
depends on QEMU_NET_ROCKER
|
||||
default 10
|
||||
|
||||
endmenu
|
||||
|
||||
config QEMU_EXTRA
|
||||
string "Extra QEMU options"
|
||||
|
||||
config QEMU_APPEND
|
||||
string "Extra kernel options"
|
||||
depends on QEMU_LOADER_QEMU
|
||||
Executable
+480
@@ -0,0 +1,480 @@
|
||||
#!/bin/sh
|
||||
# This script can be used to start an Infix OS image in Qemu. It reads
|
||||
# either a .config, generated from Config.in, or qemu.cfg from a release
|
||||
# tarball, for the required configuration data.
|
||||
#
|
||||
# Debian/Ubuntu users can change the configuration post-release, install
|
||||
# the kconfig-frontends package:
|
||||
#
|
||||
# sudo apt install kconfig-frontends
|
||||
#
|
||||
# and then call this script with:
|
||||
#
|
||||
# ./run.sh -c
|
||||
#
|
||||
# To bring up a menuconfig dialog. Select `Exit` and save the changes.
|
||||
# For more help, see:_
|
||||
#
|
||||
# ./run.sh -h
|
||||
#
|
||||
# shellcheck disable=SC3037
|
||||
|
||||
# Add /sbin to PATH for mkfs.ext4 and such (not default in debian)
|
||||
export PATH="/sbin:/usr/sbin:$PATH"
|
||||
|
||||
qdir=$(dirname "$(readlink -f "$0")")
|
||||
imgdir=$(readlink -f "${qdir}/..")
|
||||
prognm=$(basename "$0")
|
||||
|
||||
usage()
|
||||
{
|
||||
cat <<EOF
|
||||
usage: $prognm [OPTIONS] [-- KERNEL-ARGS]
|
||||
|
||||
Start Infix in a VM.
|
||||
|
||||
Any arguments after -- are passed to the kernel, provided that QEMU's
|
||||
native loader is being used (i.e., not UEFI, for example). This
|
||||
includes a second --, which the kernel uses to delimit between kernel
|
||||
arguments and those passed to the init process.
|
||||
|
||||
Options:
|
||||
-0
|
||||
Clear any copy-on-write layers, resetting all disks to their
|
||||
initial states, and exit.
|
||||
|
||||
-c
|
||||
Run menuconfig to change Qemu settings. This requires the
|
||||
'kconfig-frontends' package (Debian/Ubuntu).
|
||||
|
||||
-G
|
||||
Skip config generation. This is useful if you are testing out new
|
||||
QEMU features by manually modifying qemu.cfg.
|
||||
|
||||
-h
|
||||
Show this help message
|
||||
|
||||
Example:
|
||||
|
||||
$prognm -- loglevel=4 -- finit.debug
|
||||
|
||||
Will set the kernel's loglevel to 4, and pass finit.debug as an
|
||||
argument to PID 1.
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
die()
|
||||
{
|
||||
echo "$prognm: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
binpath()
|
||||
{
|
||||
case "$1" in
|
||||
./*|../*)
|
||||
# Relative paths are relative to the location of .config
|
||||
printf "$qdir/$1"
|
||||
;;
|
||||
*)
|
||||
printf "$1"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
q()
|
||||
{
|
||||
local _cmd="$1"
|
||||
shift
|
||||
|
||||
case "$_cmd" in
|
||||
sect)
|
||||
printf ' \\\n\t' >>"$qdir"/qemu.sh
|
||||
|
||||
case $# in
|
||||
1)
|
||||
printf -- "-$1" >>"$qdir"/qemu.sh
|
||||
_delim=" "
|
||||
;;
|
||||
2)
|
||||
printf -- "-$1 $2" >>"$qdir"/qemu.sh
|
||||
_delim=","
|
||||
;;
|
||||
*)
|
||||
die "q sect: Invalid arguments"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
param)
|
||||
[ $# -eq 2 ] || die "q param: Takes exactly two arguments"
|
||||
printf -- "$_delim$1=$2" >>"$qdir"/qemu.sh
|
||||
_delim=","
|
||||
;;
|
||||
option)
|
||||
[ $# -eq 1 ] || die "q option: Takes exactly one argument"
|
||||
printf -- "$_delim$1" >>"$qdir"/qemu.sh
|
||||
_delim=","
|
||||
;;
|
||||
*)
|
||||
die "q: Unknown command: $_cmd"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
q_sect_device_virtio()
|
||||
{
|
||||
q sect device virtio-$1-$QEMU_VIRTIO_BUS
|
||||
}
|
||||
|
||||
q_add_disk()
|
||||
{
|
||||
if [ "$QEMU_DISK_SYS_IF_VIRTIO" ]; then
|
||||
q_sect_device_virtio blk
|
||||
q param drive "$1"
|
||||
else
|
||||
die "Unknown system disk interface"
|
||||
fi
|
||||
}
|
||||
|
||||
q_sect_device_usb()
|
||||
{
|
||||
if [ -z "$usb_bus_added" ]; then
|
||||
q sect usb
|
||||
q sect device usb-ehci
|
||||
q param id ehci
|
||||
usb_bus_added=YES
|
||||
fi
|
||||
|
||||
q sect device "$1"
|
||||
q param bus ehci.0
|
||||
}
|
||||
|
||||
qcowed()
|
||||
{
|
||||
local _qcow="$qdir"/"$1".qcow2
|
||||
local _base _size
|
||||
|
||||
if [ -f "$_qcow" ] && qemu-img check -q "$_qcow"; then
|
||||
echo "$_qcow"
|
||||
return
|
||||
fi
|
||||
|
||||
rm -f "$_qcow"
|
||||
|
||||
case $# in
|
||||
2)
|
||||
_size="$2"
|
||||
|
||||
qemu-img create -q -f qcow2 "$_qcow" "$_size" \
|
||||
|| die "Unable to create $1"
|
||||
;;
|
||||
3)
|
||||
|
||||
_base="$2"
|
||||
_size="$3"
|
||||
|
||||
[ "$_size" = "auto" ] && _size=
|
||||
|
||||
qemu-img create -q -f qcow2 -F raw \
|
||||
-o backing_file="$_base" "$_qcow" $_size \
|
||||
|| die "Unable to create CoW layer for $_base"
|
||||
;;
|
||||
*)
|
||||
die "qcowed: usage: qcowed <name> [<backing-file>] <size>"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$_qcow"
|
||||
}
|
||||
|
||||
append()
|
||||
{
|
||||
echo -n " $*" >>"$qdir"/append
|
||||
}
|
||||
|
||||
gen_machine()
|
||||
{
|
||||
q sect machine
|
||||
q param type "$QEMU_MACHINE"
|
||||
q param accel kvm:tcg
|
||||
|
||||
q sect cpu "$QEMU_CPU"
|
||||
|
||||
q sect m
|
||||
q param size "$QEMU_RAM"
|
||||
}
|
||||
|
||||
gen_loader()
|
||||
{
|
||||
if [ "$QEMU_LOADER_QEMU" ]; then
|
||||
q sect kernel $(binpath "$QEMU_BIN_KERNEL")
|
||||
elif [ "$QEMU_LOADER_OVMF" ]; then
|
||||
q sect bios $(binpath "$QEMU_BIN_BIOS")
|
||||
fi
|
||||
}
|
||||
|
||||
gen_serial()
|
||||
{
|
||||
q sect display none
|
||||
|
||||
q_sect_device_virtio serial
|
||||
|
||||
q sect chardev stdio
|
||||
q param id console0
|
||||
q param mux on
|
||||
|
||||
q sect mon
|
||||
q param chardev console0
|
||||
|
||||
case "$QEMU_CONSOLE" in
|
||||
hvc0)
|
||||
q sect device virtconsole
|
||||
q param nr 0
|
||||
q param name console
|
||||
q param chardev console0
|
||||
;;
|
||||
ttyS0|ttyAMA0)
|
||||
q sect serial chardev:console0
|
||||
;;
|
||||
*)
|
||||
die "Unsupported console: $QEMU_CONSOLE"
|
||||
;;
|
||||
esac
|
||||
|
||||
append console="$QEMU_CONSOLE"
|
||||
|
||||
[ "$V" ] && append debug || append loglevel=4
|
||||
}
|
||||
|
||||
gpt_uuid()
|
||||
{
|
||||
sgdisk "$1" -p | awk '
|
||||
BEGIN { err = 1; } END { exit(err); }
|
||||
/^Creating new GPT/ { exit; }
|
||||
|
||||
/^Disk identifier \(GUID\): / {
|
||||
print($4); err = 0; exit;
|
||||
}' || die "Unable to determine GPT UUID of $1"
|
||||
}
|
||||
|
||||
gen_disk_sys_empty()
|
||||
{
|
||||
q sect drive
|
||||
q param id disk-sys
|
||||
q param format qcow2
|
||||
q param if none
|
||||
q param file $(qcowed disk-sys "$QEMU_DISK_SYS_SIZE")
|
||||
|
||||
q_add_disk disk-sys
|
||||
}
|
||||
|
||||
gen_disk_sys_full()
|
||||
{
|
||||
q sect drive
|
||||
q param id disk-sys
|
||||
q param format qcow2
|
||||
q param if none
|
||||
q param file $(qcowed disk-sys $(binpath "$QEMU_BIN_DISK") \
|
||||
"$QEMU_DISK_SYS_SIZE")
|
||||
|
||||
q_add_disk disk-sys
|
||||
|
||||
append root=ddi:lvm:internal/$(basename "$QEMU_BIN_DDI")
|
||||
}
|
||||
|
||||
gen_disk_sys_split()
|
||||
{
|
||||
# EFI System Partition
|
||||
q sect drive
|
||||
q param id disk-esp
|
||||
q param format qcow2
|
||||
q param if none
|
||||
q param file $(qcowed disk-esp $(binpath "$QEMU_BIN_ESP") auto)
|
||||
|
||||
q_add_disk disk-esp
|
||||
|
||||
# LVM stub
|
||||
q sect drive
|
||||
q param id disk-sys
|
||||
q param format qcow2
|
||||
q param if none
|
||||
q param file $(qcowed disk-sys $(binpath "$QEMU_BIN_LVM_STUB") \
|
||||
"$QEMU_DISK_SYS_SIZE")
|
||||
|
||||
q_add_disk disk-sys
|
||||
|
||||
# DDI (ro)
|
||||
q sect drive
|
||||
q param id disk-ddi
|
||||
q param format raw
|
||||
q param file $(binpath "$QEMU_BIN_DDI")
|
||||
q param if none
|
||||
q param read-only on
|
||||
|
||||
q_add_disk disk-ddi
|
||||
|
||||
append root=ddi:GPTUUID=$(gpt_uuid $(binpath "$QEMU_BIN_DDI"))
|
||||
}
|
||||
|
||||
gen_disk_sys()
|
||||
{
|
||||
[ "$QEMU_DISK_SYS_NONE" ] && return
|
||||
|
||||
if [ "$QEMU_DISK_SYS_EMPTY" ]; then
|
||||
gen_disk_sys_empty
|
||||
elif [ "$QEMU_DISK_SYS_FULL" ]; then
|
||||
gen_disk_sys_full
|
||||
elif [ "$QEMU_DISK_SYS_SPLIT" ]; then
|
||||
gen_disk_sys_split
|
||||
else
|
||||
die "Unknown system disk mode"
|
||||
fi
|
||||
}
|
||||
|
||||
gen_disk_usb()
|
||||
{
|
||||
[ "$QEMU_DISK_USB_NONE" ] && return
|
||||
|
||||
if [ "$QEMU_DISK_USB_DISK" ]; then
|
||||
q sect drive
|
||||
q param id disk-usb
|
||||
q param format qcow2
|
||||
q param file $(qcowed disk-usb \
|
||||
$(binpath "$QEMU_BIN_DISK") \
|
||||
"$QEMU_DISK_USB_SIZE")
|
||||
q param if none
|
||||
|
||||
q_sect_device_usb usb-storage
|
||||
q param drive disk-usb
|
||||
else
|
||||
die "Unknown USB attachment"
|
||||
fi
|
||||
}
|
||||
|
||||
gen_disk_initrd()
|
||||
{
|
||||
[ "$QEMU_DISK_INITRD" ] || return
|
||||
|
||||
q sect initrd $(binpath "$QEMU_BIN_DDI")
|
||||
append root=ddi:/initrd.image
|
||||
}
|
||||
|
||||
internal_is_available()
|
||||
{
|
||||
[ "$QEMU_DISK_SYS_FULL" ] || [ "$QEMU_DISK_SYS_SPLIT" ] \
|
||||
|| [ "$QEMU_DISK_USB_DISK" ]
|
||||
}
|
||||
|
||||
gen_disks()
|
||||
{
|
||||
gen_disk_sys
|
||||
gen_disk_usb
|
||||
|
||||
gen_disk_initrd
|
||||
|
||||
internal_is_available || append rd.nointernal
|
||||
}
|
||||
|
||||
gen_gdb()
|
||||
{
|
||||
# Create a UNIX socket on the host that is connected to a virtio
|
||||
# console in the guest, which gdbserver can attach to for
|
||||
# userspace debugging.
|
||||
q sect chardev socket
|
||||
q param id gdbserver
|
||||
q param path "$qdir"/gdbserver.sock
|
||||
q param server on
|
||||
q param wait off
|
||||
|
||||
q sect device virtconsole
|
||||
q param nr 1
|
||||
q param name gdbserver
|
||||
q param chardev gdbserver
|
||||
|
||||
# Create a UNIX socket on the host that is connected to QEMU's GDB
|
||||
# stub, for bootloader/kernel debugging.
|
||||
q sect chardev socket
|
||||
q param id gdbqemu
|
||||
q param path "$qdir"/gdbqemu.sock
|
||||
q param server on
|
||||
q param wait off
|
||||
|
||||
q sect gdb chardev:gdbqemu
|
||||
}
|
||||
|
||||
gen_all()
|
||||
{
|
||||
local _append
|
||||
|
||||
: >"$qdir"/append
|
||||
cat <<EOF >"$qdir"/qemu.sh
|
||||
#!/bin/sh
|
||||
|
||||
echo "Starting Qemu :: Ctrl-a x -- exit | Ctrl-a c -- toggle console/monitor"
|
||||
|
||||
line=\$(stty -g)
|
||||
stty raw
|
||||
trap 'stty "\$line"' EXIT INT TERM
|
||||
|
||||
qemu-system-$QEMU_ARCH -nodefaults \\
|
||||
EOF
|
||||
chmod +x "$qdir"/qemu.sh
|
||||
|
||||
gen_machine
|
||||
gen_loader
|
||||
gen_serial
|
||||
gen_disks
|
||||
gen_gdb
|
||||
|
||||
if [ "$QEMU_LOADER_QEMU" ]; then
|
||||
_append=$(cat "$qdir"/append)
|
||||
q sect append "\"$_append $QEMU_APPEND $*\""
|
||||
fi
|
||||
|
||||
echo >>"$qdir"/qemu.sh
|
||||
}
|
||||
|
||||
menuconfig()
|
||||
{
|
||||
command -v kconfig-mconf >/dev/null \
|
||||
|| die "cannot find kconfig-mconf for menuconfig"
|
||||
|
||||
CONFIG_= KCONFIG_CONFIG="$qdir"/.config \
|
||||
kconfig-mconf "$qdir"/Config.in
|
||||
}
|
||||
|
||||
_generate=YES
|
||||
|
||||
while getopts "0cGh-" opt; do
|
||||
case ${opt} in
|
||||
0)
|
||||
echo "Clearing all copy-on-write layers" >&2
|
||||
rm -f "$qdir"/*.qcow2
|
||||
exit 0
|
||||
;;
|
||||
c)
|
||||
menuconfig
|
||||
;;
|
||||
G)
|
||||
_generate=
|
||||
;;
|
||||
h)
|
||||
usage && exit 0
|
||||
;;
|
||||
-)
|
||||
break
|
||||
;;
|
||||
*)
|
||||
usage && exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
# shellcheck disable=SC1090
|
||||
. "$qdir"/.config
|
||||
|
||||
[ "$_generate" ] && gen_all "$*"
|
||||
|
||||
exec "$qdir"/qemu.sh
|
||||
@@ -149,7 +149,7 @@ config QEMU_HOST
|
||||
|
||||
config QEMU_APPEND
|
||||
string "Extra kernel options"
|
||||
depends on !QEMU_ROOTFS_MMC
|
||||
depends on QEMU_LOADER_KERNEL
|
||||
|
||||
config QEMU_EXTRA
|
||||
string "Extra QEMU options"
|
||||
@@ -4,9 +4,15 @@
|
||||
#
|
||||
################################################################################
|
||||
|
||||
QEMU_SCRIPTS_DIR := $(pkgdir)
|
||||
qemu-scripts-dir := $(pkgdir)/$(if $(IMAGE_DDI),ddi,itb)
|
||||
qemu-image := ../$(INFIX_ARTIFACT).$(if $(IMAGE_DDI),raw,qcow2)
|
||||
qemu-disk := $(if $(IMAGE_DDI_DISK),../$(INFIX_ARTIFACT).disk)
|
||||
qemu-esp := $(if $(IMAGE_BAREBOX_ESP),../barebox-esp.vfat)
|
||||
|
||||
qemu-kconfig-prefix := $(if $(IMAGE_DDI),,CONFIG_)
|
||||
|
||||
qemu-kconfig = \
|
||||
CONFIG_="CONFIG_" \
|
||||
CONFIG_="$(qemu-kconfig-prefix)" \
|
||||
BR2_CONFIG="$(BINARIES_DIR)/qemu/.config" \
|
||||
$(BUILD_DIR)/buildroot-config/$(1) $(2) "$(BINARIES_DIR)/qemu/Config.in"
|
||||
|
||||
@@ -25,17 +31,19 @@ qemu-scripts: \
|
||||
$(BINARIES_DIR)/qemu/Config.in \
|
||||
$(BINARIES_DIR)/qemu/.config
|
||||
|
||||
$(BINARIES_DIR)/qemu/run.sh: $(QEMU_SCRIPTS_DIR)/run.sh
|
||||
$(BINARIES_DIR)/qemu/run.sh: $(qemu-scripts-dir)/run.sh
|
||||
@$(call IXMSG,"Installing QEMU scripts")
|
||||
@mkdir -p $(dir $@)
|
||||
@cp $< $@
|
||||
|
||||
$(BINARIES_DIR)/qemu/Config.in: $(QEMU_SCRIPTS_DIR)/Config.in.in
|
||||
$(BINARIES_DIR)/qemu/Config.in: $(qemu-scripts-dir)/Config.in.in
|
||||
@mkdir -p $(dir $@)
|
||||
@sed \
|
||||
-e "s:@ARCH@:QEMU_$(BR2_ARCH):" \
|
||||
-e "s:@DISK_IMG@:../$(INFIX_ARTIFACT).qcow2:" \
|
||||
< $< >$@
|
||||
-e "s:@ARCH@:$(BR2_ARCH):g" \
|
||||
-e "s:@IMAGE@:$(qemu-image):g" \
|
||||
-e "s:@DISK@:$(qemu-disk):g" \
|
||||
-e "s:@ESP@:$(qemu-esp):g" \
|
||||
<$< >$@
|
||||
|
||||
$(BINARIES_DIR)/qemu/.config: $(BINARIES_DIR)/qemu/Config.in
|
||||
@$(call qemu-kconfig,conf,--olddefconfig)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.-------.
|
||||
| . . | Infix OS — Immutable.Friendly.Secure
|
||||
|-. v .-| https://www.kernelkit.org
|
||||
|-. v .-| https://kernelkit.org
|
||||
'-'---'-'
|
||||
|
||||
Executable
+343
@@ -0,0 +1,343 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
capath=/etc/rauc/keys
|
||||
|
||||
usage()
|
||||
{
|
||||
local _ddi="$(basename $0)"
|
||||
|
||||
cat <<EOF
|
||||
usage: $_ddi [<options>] <image> <command> [<args>]
|
||||
|
||||
Discoverable Disk Image manipulation
|
||||
|
||||
Options:
|
||||
|
||||
-A <arch>
|
||||
Override the system architecture.
|
||||
|
||||
-C <path>
|
||||
Source trusted signing keys from the supplied directory.
|
||||
Default: $capath
|
||||
|
||||
-h
|
||||
Show this message and exit.
|
||||
|
||||
Commands:
|
||||
|
||||
inspect <property>
|
||||
|
||||
uuid
|
||||
Print GPT disk identifier
|
||||
|
||||
part <partition> <command> [<args]
|
||||
Where <partition> is one of:
|
||||
root The first root partition
|
||||
|
||||
open [<options>] <name>
|
||||
|
||||
Create a device mapping for the specified partition, called
|
||||
<name>.
|
||||
|
||||
Options:
|
||||
|
||||
-v
|
||||
Use the associated dm-verity hash tree, whose root hash is
|
||||
available in the associated signature partition.
|
||||
|
||||
-V <root-hash>
|
||||
Use the associated dm-verity hash tree, along with an
|
||||
externally validated root hash.
|
||||
|
||||
verify [<options>]
|
||||
|
||||
Verify that the specified partition exists and, optionally,
|
||||
is accompanied by a trusted dm-verity hash tree.
|
||||
|
||||
Options:
|
||||
|
||||
-v
|
||||
Require the presence of an associated dm-verity hash tree,
|
||||
whose root hash is available in the associated signature
|
||||
partition.
|
||||
|
||||
-V <root-hash>
|
||||
Require the presence of an associated dm-verity hash tree
|
||||
whose root hash matches the provided one.
|
||||
|
||||
Examples:
|
||||
|
||||
Map and mount the verity protected SquashFS root partition from an
|
||||
image:
|
||||
$_ddi infix-x86_64.raw part root open -v infix
|
||||
mount -t squashfs /dev/mapper/infix /opt
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
X86_64_CODE_ROOT=0x8304
|
||||
X86_64_CODE_ROOT_VERITY=0x830c
|
||||
X86_64_CODE_ROOT_VERITY_SIG=0x8370
|
||||
|
||||
die()
|
||||
{
|
||||
echo "ERROR: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
ok()
|
||||
{
|
||||
echo "$*" >&2
|
||||
}
|
||||
|
||||
setup_arch()
|
||||
{
|
||||
case "$1" in
|
||||
x86_64)
|
||||
CODE_ROOT=$X86_64_CODE_ROOT
|
||||
CODE_ROOT_VERITY=$X86_64_CODE_ROOT_VERITY
|
||||
CODE_ROOT_VERITY_SIG=$X86_64_CODE_ROOT_VERITY_SIG
|
||||
;;
|
||||
*)
|
||||
die "Unsupported architecture"
|
||||
esac
|
||||
}
|
||||
|
||||
setup_work()
|
||||
{
|
||||
local _umask
|
||||
|
||||
_umask=$(umask)
|
||||
umask 077
|
||||
workdir=$(mktemp -d)
|
||||
umask $_umask
|
||||
|
||||
trap 'rm -rf "$workdir"' EXIT INT TERM
|
||||
}
|
||||
|
||||
ddi_to_block()
|
||||
{
|
||||
local _kind _lo
|
||||
|
||||
_kind=$(stat -Lc %F "$1")
|
||||
case "$_kind" in
|
||||
"block special file")
|
||||
echo "$1"
|
||||
return
|
||||
;;
|
||||
"regular file")
|
||||
_lo=$(losetup -f || die "Found no free loop device for $1")
|
||||
losetup -P "$_lo" "$1" || die "Failed to setup loop device of $1"
|
||||
echo "$_lo"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
die "$1 is a $_kind, only regular and block devices are supported"
|
||||
}
|
||||
|
||||
ddi_get_part_info()
|
||||
{
|
||||
local _code _item
|
||||
|
||||
case "$2" in
|
||||
root) _code="$CODE_ROOT";;
|
||||
root-verity) _code="$CODE_ROOT_VERITY";;
|
||||
root-verity-sig) _code="$CODE_ROOT_VERITY_SIG";;
|
||||
*) die "Unknown partition type \"$1\"" ;;
|
||||
esac
|
||||
_code=$(printf "%04X" "$_code")
|
||||
_item=${3:-exists}
|
||||
|
||||
sgdisk "$1" -p | awk -v code="$_code" -v item="$_item" '
|
||||
/^[ ]*[0-9]+/ {
|
||||
if ($6 != code)
|
||||
next;
|
||||
|
||||
if (item == "exists") exit(0);
|
||||
if (item == "index") { print($1); exit(0); }
|
||||
|
||||
exit(1);
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
ddi_get_part_dev()
|
||||
{
|
||||
local _dev _index _lvuuid _subsys
|
||||
|
||||
_index=$(ddi_get_part_info "$1" "$2" index \
|
||||
|| die "No $2 partition found on $1")
|
||||
|
||||
_subsys=$(dmsetup info -c --noheadings -o subsystem "$1" 2>/dev/null || true)
|
||||
if [ "$_subsys" = "LVM" ]; then
|
||||
_lvuuid=$(dmsetup info -c --noheadings -o uuid "$1")
|
||||
_dev=/dev/mapper/$(dmsetup info -c --noheadings -o name -u "part${_index}-$_lvuuid")
|
||||
else
|
||||
_dev=$(basename "$1")
|
||||
_dev=$(find /sys/block/"$_dev"/ -mindepth 1 -maxdepth 1 -type d \
|
||||
-name "${_dev}$_index" -o -name "${_dev}p$_index")
|
||||
_dev=/dev/$(basename "$_dev")
|
||||
fi
|
||||
|
||||
[ -b "$_dev" ] || die "Failed to locate $2 partition in $1"
|
||||
|
||||
echo "$_dev"
|
||||
}
|
||||
|
||||
ddi_get_root_hash()
|
||||
{
|
||||
local _subj
|
||||
|
||||
command -v openssl >/dev/null || die "Missing dependency: openssl"
|
||||
command -v jq >/dev/null || die "Missing dependency: jq"
|
||||
|
||||
jq -r .rootHash "$1" | tr -d '\n' >"$workdir"/hash \
|
||||
|| die "Invalid signature: rootHash is missing"
|
||||
|
||||
jq -r .signature "$1" | base64 -d >"$workdir"/sig \
|
||||
|| die "Invalid signature: signature data is missing"
|
||||
|
||||
openssl cms -verify -verify_retcode -CApath "$capath" \
|
||||
-content "$workdir"/hash \
|
||||
-in "$workdir"/sig -inform DER \
|
||||
-certsout "$workdir"/certs >/dev/null 2>&1 \
|
||||
|| die "Signature verification failed"
|
||||
|
||||
_subj=$(openssl x509 -noout -subject <"$workdir"/certs | sed -e 's/^subject=//')
|
||||
ok "Trusting root hash signature from $_subj"
|
||||
|
||||
cat "$workdir"/hash
|
||||
}
|
||||
|
||||
ddipart_get_verity()
|
||||
{
|
||||
local _hash
|
||||
|
||||
while getopts "vV:" opt; do
|
||||
case "$opt" in
|
||||
V)
|
||||
vkind="${kind}-verity"
|
||||
vhash="$OPTARG"
|
||||
;;
|
||||
v)
|
||||
vkind="${kind}-verity"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ "$vkind" ] || return
|
||||
|
||||
vpart=$(ddi_get_part_dev "$img" "$vkind")
|
||||
|
||||
[ "$vhash" ] && return
|
||||
|
||||
vskind="${vkind}-sig"
|
||||
vspart=$(ddi_get_part_dev "$img" "$vskind")
|
||||
vhash=$(ddi_get_root_hash "$vspart")
|
||||
}
|
||||
|
||||
ddipart_open()
|
||||
{
|
||||
[ "$vpart" ] || die "$kind partition is already accessible at $part"
|
||||
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
veritysetup open "$part" "$1" "$vpart" "$vhash"
|
||||
}
|
||||
|
||||
ddipart_verify()
|
||||
{
|
||||
[ "$vpart" ] || return
|
||||
|
||||
veritysetup verify "$part" "$vpart" "$vhash"
|
||||
ok "Image in $img has $kind partition with valid dm-verity hash tree"
|
||||
}
|
||||
|
||||
ddipart()
|
||||
{
|
||||
local _cmd
|
||||
|
||||
kind="$1"
|
||||
shift
|
||||
|
||||
ddi_get_part_info "$img" "$kind" \
|
||||
|| die "No $kind partition found on $img"
|
||||
|
||||
_cmd="$1"
|
||||
shift
|
||||
|
||||
case "$_cmd" in
|
||||
open|verify)
|
||||
img=$(ddi_to_block $img)
|
||||
part=$(ddi_get_part_dev "$img" "$kind")
|
||||
ddipart_get_verity "$@"
|
||||
|
||||
ddipart_$_cmd "$@"
|
||||
;;
|
||||
*)
|
||||
die "Unknown partition command \"$_cmd\""
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
ddiinspect()
|
||||
{
|
||||
case "$1" in
|
||||
uuid)
|
||||
sgdisk "$img" -p | awk '
|
||||
BEGIN { err = 1; } END { exit(err); }
|
||||
/^Creating new GPT/ { exit; }
|
||||
|
||||
/^Disk identifier \(GUID\): / {
|
||||
print($4); err = 0; exit;
|
||||
}'
|
||||
;;
|
||||
*)
|
||||
die "Unknown property: $1"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_arch=$(uname -m)
|
||||
|
||||
while getopts "A:C:h" opt; do
|
||||
case ${opt} in
|
||||
A)
|
||||
_arch="$OPTARG"
|
||||
;;
|
||||
C)
|
||||
capath="$OPTARG"
|
||||
;;
|
||||
h)
|
||||
usage && exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
usage && exit 1
|
||||
fi
|
||||
|
||||
img="$1"
|
||||
cmd="$2"
|
||||
shift 2
|
||||
|
||||
setup_arch "$_arch"
|
||||
setup_work
|
||||
|
||||
case "$cmd" in
|
||||
inspect)
|
||||
ddiinspect "$@"
|
||||
;;
|
||||
part)
|
||||
ddipart "$@"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown command \"$cmd\"" >2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -23,8 +23,7 @@ dir=""
|
||||
all=""
|
||||
env=""
|
||||
port=""
|
||||
force=${force:-}
|
||||
reset_volumes=
|
||||
force=
|
||||
|
||||
# Variable shared across subshells
|
||||
export meta_sha=""
|
||||
@@ -228,7 +227,7 @@ fetch()
|
||||
|
||||
if out=$(eval "$cmd" 2>&1); then
|
||||
log "$file downloaded successfully."
|
||||
if [ -n "$force" ] || check "$file"; then
|
||||
if check "$file"; then
|
||||
echo "$dst"
|
||||
return 0
|
||||
fi
|
||||
@@ -898,9 +897,6 @@ while [ "$1" != "" ]; do
|
||||
shift
|
||||
restart=$1
|
||||
;;
|
||||
-R | --reset-volumes)
|
||||
reset_volumes=true
|
||||
;;
|
||||
-s | --simple)
|
||||
simple=true
|
||||
;;
|
||||
@@ -1112,8 +1108,7 @@ case $cmd in
|
||||
# Remove the old image if it's not used by any other containers
|
||||
if [ -n "$old_image_id" ]; then
|
||||
# Check if the old image is still in use by any containers
|
||||
old_image_id=${old_image_id:0:12}
|
||||
if ! podman ps -a --format '{{.ImageID}}' | grep -q "^${old_image_id}"; then
|
||||
if ! podman ps -a --format '{{.ImageID}}' | grep -q "^${old_image_id}$"; then
|
||||
log "Removing old image $old_image_id"
|
||||
podman rmi "$old_image_id" 2>/dev/null || true
|
||||
else
|
||||
@@ -1255,22 +1250,8 @@ case $cmd in
|
||||
container stop "$name"
|
||||
echo "done"
|
||||
|
||||
# If --reset-volumes requested, delete named volumes so they re-initialize from new image
|
||||
if [ -n "$reset_volumes" ]; then
|
||||
printf ">> Resetting named volumes (all configuration will be lost): "
|
||||
grep -oE -- '-v [^ ]+' "$script" | awk '{print $2}' | cut -d: -f1 | \
|
||||
while read -r vol_name; do
|
||||
if podman volume exists "$vol_name" 2>/dev/null; then
|
||||
printf "%s " "$vol_name"
|
||||
log "Removing volume $vol_name"
|
||||
podman volume rm -f "$vol_name" >/dev/null || true
|
||||
fi
|
||||
done
|
||||
echo "done"
|
||||
fi
|
||||
|
||||
# Set force flag to ensure fresh pull/fetch of image
|
||||
export force="-f"
|
||||
force="-f"
|
||||
|
||||
# For remote images, force re-pull
|
||||
case "$img" in
|
||||
@@ -1292,17 +1273,14 @@ case $cmd in
|
||||
# Recreate container by running the script
|
||||
echo ">> Recreating container ..."
|
||||
if ! "$script"; then
|
||||
force=
|
||||
echo ">> Failed recreating container $name"
|
||||
exit 1
|
||||
fi
|
||||
force=
|
||||
|
||||
# Remove the old image if it's not used by any other containers
|
||||
if [ -n "$old_image_id" ]; then
|
||||
# Check if the old image is still in use by any containers
|
||||
old_image_id=${old_image_id:0:12}
|
||||
if ! podman ps -a --format '{{.ImageID}}' | grep -q "^${old_image_id}"; then
|
||||
if ! podman ps -a --format '{{.ImageID}}' | grep -q "^${old_image_id}$"; then
|
||||
log "Removing old image $old_image_id"
|
||||
podman rmi "$old_image_id" 2>/dev/null || true
|
||||
else
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
CODE_ROOT=0x8304
|
||||
CODE_ROOT_VERITY=0x830c
|
||||
CODE_ROOT_VERITY_SIG=0x8370
|
||||
+1
-1
Submodule buildroot updated: 66450a898a...cde6f777f9
@@ -27,7 +27,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
|
||||
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.15"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.14"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
@@ -143,10 +143,10 @@ BR2_PACKAGE_MARVELL_CN9130_CRB=y
|
||||
BR2_PACKAGE_MARVELL_ESPRESSOBIN=y
|
||||
BR2_PACKAGE_RASPBERRYPI_RPI64=y
|
||||
BR2_PACKAGE_STYX_DCP_SC_28P=y
|
||||
INFIX_VENDOR_HOME="https://www.kernelkit.org"
|
||||
INFIX_VENDOR_HOME="https://kernelkit.org"
|
||||
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
|
||||
INFIX_HOME="https://github.com/kernelkit/infix/"
|
||||
INFIX_DOC="https://www.kernelkit.org/infix/"
|
||||
INFIX_DOC="https://kernelkit.org/infix/"
|
||||
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
||||
BR2_PACKAGE_FEATURE_GPS=y
|
||||
BR2_PACKAGE_FEATURE_WIFI_MEDIATEK=y
|
||||
|
||||
@@ -27,7 +27,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
|
||||
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.15"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.14"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
@@ -121,10 +121,10 @@ BR2_PACKAGE_MARVELL_CN9130_CRB=y
|
||||
BR2_PACKAGE_MARVELL_ESPRESSOBIN=y
|
||||
BR2_PACKAGE_RASPBERRYPI_RPI64=y
|
||||
BR2_PACKAGE_STYX_DCP_SC_28P=y
|
||||
INFIX_VENDOR_HOME="https://www.kernelkit.org"
|
||||
INFIX_VENDOR_HOME="https://kernelkit.org"
|
||||
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
|
||||
INFIX_HOME="https://github.com/kernelkit/infix/"
|
||||
INFIX_DOC="https://www.kernelkit.org/infix/"
|
||||
INFIX_DOC="https://kernelkit.org/infix/"
|
||||
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
||||
BR2_PACKAGE_FEATURE_GPS=y
|
||||
BR2_PACKAGE_CONFD=y
|
||||
|
||||
@@ -28,7 +28,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
|
||||
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.15"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.14"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/arm/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
@@ -139,10 +139,10 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
|
||||
BR2_PACKAGE_MICROCHIP_SAMA7G54_EK=y
|
||||
BR2_PACKAGE_RASPBERRYPI_RPI2=y
|
||||
INFIX_VENDOR_HOME="https://www.kernelkit.org"
|
||||
INFIX_VENDOR_HOME="https://kernelkit.org"
|
||||
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
|
||||
INFIX_HOME="https://github.com/kernelkit/infix/"
|
||||
INFIX_DOC="https://www.kernelkit.org/infix/"
|
||||
INFIX_DOC="https://kernelkit.org/infix/"
|
||||
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
||||
BR2_PACKAGE_FEATURE_GPS=y
|
||||
BR2_PACKAGE_FEATURE_WIFI_MEDIATEK=y
|
||||
|
||||
@@ -28,7 +28,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
|
||||
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.15"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.14"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/arm/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
@@ -121,10 +121,10 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
|
||||
BR2_PACKAGE_MICROCHIP_SAMA7G54_EK=y
|
||||
BR2_PACKAGE_RASPBERRYPI_RPI2=y
|
||||
INFIX_VENDOR_HOME="https://www.kernelkit.org"
|
||||
INFIX_VENDOR_HOME="https://kernelkit.org"
|
||||
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
|
||||
INFIX_HOME="https://github.com/kernelkit/infix/"
|
||||
INFIX_DOC="https://www.kernelkit.org/infix/"
|
||||
INFIX_DOC="https://kernelkit.org/infix/"
|
||||
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
||||
BR2_PACKAGE_FEATURE_GPS=y
|
||||
BR2_PACKAGE_CONFD=y
|
||||
|
||||
@@ -170,10 +170,10 @@ BR2_PACKAGE_HOST_BMAP_TOOLS=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
|
||||
INFIX_VENDOR_HOME="https://www.kernelkit.org"
|
||||
INFIX_VENDOR_HOME="https://kernelkit.org"
|
||||
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
|
||||
INFIX_HOME="https://github.com/kernelkit/infix/"
|
||||
INFIX_DOC="https://www.kernelkit.org/infix/"
|
||||
INFIX_DOC="https://kernelkit.org/infix/"
|
||||
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
||||
BR2_PACKAGE_FEATURE_GPS=y
|
||||
BR2_PACKAGE_FEATURE_WIFI=y
|
||||
|
||||
@@ -26,7 +26,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
|
||||
BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.15"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.14"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
@@ -142,10 +142,10 @@ BR2_PACKAGE_HOST_MTOOLS=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
|
||||
INFIX_VENDOR_HOME="https://www.kernelkit.org"
|
||||
INFIX_VENDOR_HOME="https://kernelkit.org"
|
||||
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
|
||||
INFIX_HOME="https://github.com/kernelkit/infix/"
|
||||
INFIX_DOC="https://www.kernelkit.org/infix/"
|
||||
INFIX_DOC="https://kernelkit.org/infix/"
|
||||
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
||||
BR2_PACKAGE_FEATURE_GPS=y
|
||||
BR2_PACKAGE_FEATURE_WIFI=y
|
||||
|
||||
@@ -26,7 +26,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
|
||||
BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.15"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.14"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
@@ -37,6 +37,7 @@ BR2_PACKAGE_STRESS_NG=y
|
||||
BR2_PACKAGE_JQ=y
|
||||
BR2_PACKAGE_E2FSPROGS=y
|
||||
BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y
|
||||
BR2_PACKAGE_CRYPTSETUP=y
|
||||
BR2_PACKAGE_DBUS_CXX=y
|
||||
BR2_PACKAGE_DBUS_GLIB=y
|
||||
BR2_PACKAGE_EUDEV_RULES_GEN=y
|
||||
@@ -87,6 +88,7 @@ BR2_PACKAGE_BASH_COMPLETION=y
|
||||
BR2_PACKAGE_SUDO=y
|
||||
BR2_PACKAGE_GETENT=y
|
||||
BR2_PACKAGE_KMOD_TOOLS=y
|
||||
BR2_PACKAGE_MULTIPATH_TOOLS=y
|
||||
BR2_PACKAGE_PWGEN=y
|
||||
BR2_PACKAGE_RAUC=y
|
||||
BR2_PACKAGE_RAUC_DBUS=y
|
||||
@@ -95,6 +97,7 @@ BR2_PACKAGE_RAUC_NETWORK=y
|
||||
BR2_PACKAGE_RAUC_JSON=y
|
||||
BR2_PACKAGE_SYSKLOGD=y
|
||||
BR2_PACKAGE_SYSKLOGD_LOGGER=y
|
||||
BR2_PACKAGE_UTIL_LINUX_PARTX=y
|
||||
BR2_PACKAGE_WATCHDOGD=y
|
||||
BR2_PACKAGE_WATCHDOGD_GENERIC=y
|
||||
BR2_PACKAGE_WATCHDOGD_LOADAVG=y
|
||||
@@ -105,13 +108,16 @@ BR2_PACKAGE_WATCHDOGD_TEMPMON=y
|
||||
BR2_PACKAGE_LESS=y
|
||||
BR2_PACKAGE_MG=y
|
||||
BR2_PACKAGE_NANO=y
|
||||
BR2_TARGET_ROOTFS_CPIO_DRACUT=y
|
||||
BR2_TARGET_ROOTFS_CPIO_DRACUT_MODULES="${BR2_EXTERNAL_INFIX_PATH}/board/common/initramfs"
|
||||
BR2_TARGET_ROOTFS_CPIO_DRACUT_CONF_FILES="${BR2_EXTERNAL_INFIX_PATH}/board/common/dracut.conf"
|
||||
BR2_TARGET_ROOTFS_INITRAMFS=y
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
BR2_TARGET_EDK2=y
|
||||
BR2_TARGET_GRUB2=y
|
||||
BR2_TARGET_GRUB2_X86_64_EFI=y
|
||||
BR2_TARGET_GRUB2_BUILTIN_MODULES_EFI="boot linux ext2 squash4 part_gpt normal efi_gop configfile loadenv test echo reboot net efinet tftp loopback cat search"
|
||||
BR2_TARGET_GRUB2_BUILTIN_CONFIG_EFI="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/grub-embed.cfg"
|
||||
BR2_TARGET_GRUB2_INSTALL_TOOLS=y
|
||||
BR2_TARGET_BAREBOX=y
|
||||
BR2_TARGET_BAREBOX_CUSTOM_VERSION=y
|
||||
BR2_TARGET_BAREBOX_CUSTOM_VERSION_VALUE="2025.11.0"
|
||||
BR2_TARGET_BAREBOX_BOARD_DEFCONFIG="efi"
|
||||
BR2_TARGET_BAREBOX_IMAGE_FILE="barebox.efi"
|
||||
BR2_PACKAGE_HOST_DOSFSTOOLS=y
|
||||
BR2_PACKAGE_HOST_E2FSPROGS=y
|
||||
BR2_PACKAGE_HOST_ENVIRONMENT_SETUP=y
|
||||
@@ -120,10 +126,10 @@ BR2_PACKAGE_HOST_MTOOLS=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
|
||||
INFIX_VENDOR_HOME="https://www.kernelkit.org"
|
||||
INFIX_VENDOR_HOME="https://kernelkit.org"
|
||||
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
|
||||
INFIX_HOME="https://github.com/kernelkit/infix/"
|
||||
INFIX_DOC="https://www.kernelkit.org/infix/"
|
||||
INFIX_DOC="https://kernelkit.org/infix/"
|
||||
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
||||
BR2_PACKAGE_FEATURE_GPS=y
|
||||
BR2_PACKAGE_CONFD=y
|
||||
@@ -150,9 +156,6 @@ BR2_PACKAGE_MDNS_ALIAS=y
|
||||
BR2_PACKAGE_ONIEPROM=y
|
||||
BR2_PACKAGE_ROUSETTE=y
|
||||
BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y
|
||||
IMAGE_ITB_AUX=y
|
||||
IMAGE_ITB_QCOW=y
|
||||
IMAGE_ITB_RAUC=y
|
||||
IMAGE_README=y
|
||||
IMAGE_DDI=y
|
||||
TRUSTED_KEYS=y
|
||||
TRUSTED_KEYS_DEVELOPMENT=y
|
||||
|
||||
+9
-14
@@ -3,29 +3,25 @@ Change Log
|
||||
|
||||
All notable changes to the project are documented in this file.
|
||||
|
||||
[v26.02.0][] - 2026-03-01
|
||||
[v26.02.0][UNRELEASED] -
|
||||
-------------------------
|
||||
|
||||
> [!NOTE]
|
||||
> The blog and User Guide have a new address: <https://www.kernelkit.org>
|
||||
|
||||
### Changes
|
||||
|
||||
- Upgrade Linux kernel to 6.18.15 (LTS)
|
||||
- Upgrade Linux kernel to 6.18.14 (LTS)
|
||||
- Upgrade Buildroot to 2025.02.11 (LTS)
|
||||
- Upgrade FRR to 10.5.1
|
||||
- Add support for [Microchip SAMA7G54][SAMA7G54-EK] Evaluation Kit, Arm Cortex-A7
|
||||
- Add support for Microchip SAMA7G54-EK Evaluation Kit, Arm Cortex-A7
|
||||
- Add GPS/GNSS receiver support with NTP reference clock integration
|
||||
- Add support for [Banana Pi R3 Mini][BPI-R3-MINI], a 2 port router with 2 WiFi chip,
|
||||
uses the same bootloader as BPI-R3 (eMMC-version)
|
||||
- Add GPS/GNSS receiver support with NTP reference clock integration
|
||||
- Add `reset-volumes` option to `container upgrade foo` command
|
||||
|
||||
### Fixes
|
||||
|
||||
- Fix CLI `copy` command problem to copy to scp/sftp destinations
|
||||
N/A
|
||||
|
||||
[BPI-R3-MINI]: https://wiki.banana-pi.org/Banana_Pi_BPI-R3_Mini
|
||||
[SAMA7G54-EK]: https://www.microchip.com/en-us/development-tool/ev21h18a
|
||||
|
||||
|
||||
[v26.01.0][] - 2026-02-03
|
||||
-------------------------
|
||||
@@ -110,7 +106,7 @@ Noteworthy changes and additions in this release are marked below in bold text.
|
||||
- Prevent MOTD from showing on non-shell user login attempts
|
||||
- Fix mDNS reflector.
|
||||
|
||||
[wifi]: https://www.kernelkit.org/infix/latest/wifi/
|
||||
[wifi]: https://kernelkit.org/infix/latest/wifi/
|
||||
[sd card image]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-rpi64-sdcard.img
|
||||
|
||||
|
||||
@@ -728,7 +724,7 @@ renamed to ease maintenance, more info below.
|
||||
not supported (yet) in Infix, issue #709
|
||||
- The default builds now include the curiOS nftables container image,
|
||||
which can be used for advanced firewall setups. For an introduction
|
||||
see <https://www.kernelkit.org/posts/firewall-container/>
|
||||
see <https://kernelkit.org/posts/firewall-container/>
|
||||
|
||||
### Fixes
|
||||
|
||||
@@ -1931,8 +1927,7 @@ Supported YANG models in addition to those used by sysrepo and netopeer:
|
||||
- N/A
|
||||
|
||||
[buildroot]: https://buildroot.org/
|
||||
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v26.02.0...HEAD
|
||||
[v26.02.0]: https://github.com/kernelkit/infix/compare/v26.01.0...v26.02.0
|
||||
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v26.01.0...HEAD
|
||||
[v26.01.0]: https://github.com/kernelkit/infix/compare/v25.11.0...v26.01.0
|
||||
[v25.11.0]: https://github.com/kernelkit/infix/compare/v25.10.0...v25.11.0
|
||||
[v25.10.0]: https://github.com/kernelkit/infix/compare/v25.09.0...v26.10.0
|
||||
|
||||
+2
-2
@@ -295,7 +295,7 @@ linux-pc:# ssh admin@infix-c0-ff-ee.local
|
||||
(admin@infix-c0-ff-ee.local) Password:
|
||||
.-------.
|
||||
| . . | Infix OS — Immutable.Friendly.Secure
|
||||
|-. v .-| https://www.kernelkit.org
|
||||
|-. v .-| https://kernelkit.org
|
||||
'-'---'-
|
||||
|
||||
Run the command 'cli' for interactive OAM
|
||||
@@ -335,7 +335,7 @@ linux-pc:# ssh admin@infix.local
|
||||
(admin@infix.local) Password:
|
||||
.-------.
|
||||
| . . | Infix OS — Immutable.Friendly.Secure
|
||||
|-. v .-| https://www.kernelkit.org
|
||||
|-. v .-| https://kernelkit.org
|
||||
'-'---'-
|
||||
|
||||
Run the command 'cli' for interactive OAM
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ example login: <b>admin</b>
|
||||
Password:
|
||||
.-------.
|
||||
| . . | Infix OS — Immutable.Friendly.Secure
|
||||
|-. v .-| https://www.kernelkit.org
|
||||
|-. v .-| https://kernelkit.org
|
||||
'-'---'-'
|
||||
|
||||
Run the command 'cli' for interactive OAM
|
||||
|
||||
@@ -336,7 +336,7 @@ It should now be possible to access the switch from the PC via SSH (or NETCONF).
|
||||
admin@fe80::0053:00ff:fe06:1101%eth1's password:
|
||||
.-------.
|
||||
| . . | Infix OS — Immutable.Friendly.Secure
|
||||
|-. v .-| https://www.kernelkit.org
|
||||
|-. v .-| https://kernelkit.org
|
||||
'-'---'-'
|
||||
|
||||
Run the command 'cli' for interactive OAM
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ Warning: Permanently added 'fe80::ff:fe00:0%eth0' (ED25519) to the list of known
|
||||
admin@fe80::ff:fe00:0%eth0's password: *****
|
||||
.-------.
|
||||
| . . | Infix OS — Immutable.Friendly.Secure
|
||||
|-. v .-| https://www.kernelkit.org
|
||||
|-. v .-| https://kernelkit.org
|
||||
'-'---'-'
|
||||
|
||||
Run the command 'cli' for interactive OAM
|
||||
|
||||
+1
-1
@@ -152,7 +152,7 @@ infix-00-00-00 login: admin
|
||||
Password:
|
||||
.-------.
|
||||
| . . | Infix OS — Immutable.Friendly.Secure
|
||||
|-. v .-| https://www.kernelkit.org
|
||||
|-. v .-| https://kernelkit.org
|
||||
'-'---'-'
|
||||
|
||||
Run the command 'cli' for interactive OAM
|
||||
|
||||
+1
-1
@@ -170,7 +170,7 @@ example login: <b>admin</b>
|
||||
Password:
|
||||
.-------.
|
||||
| . . | Infix OS — Immutable.Friendly.Secure
|
||||
|-. v .-| https://www.kernelkit.org
|
||||
|-. v .-| https://kernelkit.org
|
||||
'-'---'-'
|
||||
|
||||
Run the command 'cli' for interactive OAM
|
||||
|
||||
+1
-1
@@ -170,6 +170,6 @@ plugins:
|
||||
|
||||
extra:
|
||||
generator: false
|
||||
homepage: https://www.kernelkit.org/
|
||||
homepage: https://kernelkit.org/
|
||||
version:
|
||||
provider: mike
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 443245154df3a713a61feffa5043da4c200b30fa Mon Sep 17 00:00:00 2001
|
||||
From 00f89f3ba9f41a1c495dddcb83b2f6bb9f938a0c Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 19 Sep 2023 18:38:10 +0200
|
||||
Subject: [PATCH 01/33] net: phy: marvell10g: Support firmware loading on
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From a81a31111af41ce03bfd0a6bf493a440195c0aa8 Mon Sep 17 00:00:00 2001
|
||||
From 2a31d49efc597de1f30f3067076a77750d29a15f Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 21 Nov 2023 20:15:24 +0100
|
||||
Subject: [PATCH 02/33] net: phy: marvell10g: Fix power-up when strapped to
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 05bbe3556f357ba52eb12aef54831c2a7270f4fe Mon Sep 17 00:00:00 2001
|
||||
From 6b0e8831d0a6303daa38e92f6cf557e476f17539 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 15 Nov 2023 20:58:42 +0100
|
||||
Subject: [PATCH 03/33] net: phy: marvell10g: Add LED support for 88X3310
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From e4d030d502f358a4ed21eb75e2c3cffbe5c2b8da Mon Sep 17 00:00:00 2001
|
||||
From b5c0e5112b0d3e01af0f67c383cb981d83c185d0 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 12 Dec 2023 09:51:05 +0100
|
||||
Subject: [PATCH 04/33] net: phy: marvell10g: Support LEDs tied to a single
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 44c1b964008099707a86150597f07fb9afa2d4ab Mon Sep 17 00:00:00 2001
|
||||
From 81a6a60b94c633a4c2e3c11ab77252f827f8ea65 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 27 Mar 2024 10:10:19 +0100
|
||||
Subject: [PATCH 05/33] net: phy: Do not resume PHY when attaching
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From a0ed79ec338c0a1ec647ecffe5de532bc93ae34e Mon Sep 17 00:00:00 2001
|
||||
From d1187bd54f9d346e1037621822738548e167a668 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Mon, 4 Mar 2024 16:47:28 +0100
|
||||
Subject: [PATCH 06/33] net: bridge: avoid classifying unknown multicast as
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 1d7a80c8f0a1f1fdb9feededbe6a81ef95ea235f Mon Sep 17 00:00:00 2001
|
||||
From d292a3a9ad8ef75d589d51bc7fe11f39371781c0 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Tue, 5 Mar 2024 06:44:41 +0100
|
||||
Subject: [PATCH 07/33] net: bridge: Ignore router ports when forwarding L2
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 7d5b408393f724aa3fb9109d0373270bff5912a4 Mon Sep 17 00:00:00 2001
|
||||
From 8786298e55fc4b5f108ad18dad5be21acd4ba911 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Thu, 4 Apr 2024 16:36:30 +0200
|
||||
Subject: [PATCH 08/33] net: bridge: drop delay for applying strict multicast
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From fcb5ec6195e9201d547148f23115305d012258e1 Mon Sep 17 00:00:00 2001
|
||||
From be0a8a1d4d6ba0bbf046cd72ebe1710800869ee5 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 16 May 2024 14:51:54 +0200
|
||||
Subject: [PATCH 09/33] net: bridge: Differentiate MDB additions from
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From ea7944d9e73280180e6e80e7de5e1a20e308ecab Mon Sep 17 00:00:00 2001
|
||||
From 75070ac3fb6fdd403039bfc9b14d9edc6c3133dc Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Fri, 24 Nov 2023 23:29:55 +0100
|
||||
Subject: [PATCH 10/33] nvmem: layouts: onie-tlv: Let device probe even when
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 6d8bdf087b6b5f4a1a714858fcf9c548afee0041 Mon Sep 17 00:00:00 2001
|
||||
From 931afb4a82cce9b479f3377a78519ad20a5e2175 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Sun, 11 Aug 2024 11:27:35 +0200
|
||||
Subject: [PATCH 11/33] net: usb: r8152: add r8153b support for link/activity
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From e6250ce25bc96c91c74ad8bdea6132087bc3c8d3 Mon Sep 17 00:00:00 2001
|
||||
From 23a3579ca235bbc5c4b3417176aef7846ba022b3 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Sun, 10 Aug 2025 18:52:54 +0200
|
||||
Subject: [PATCH 12/33] arm64: dts: mediatek: mt7986a: rename BPi R3 ports to
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From dcafe00d03f102ce48cb9068c884009e753b53bf Mon Sep 17 00:00:00 2001
|
||||
From b3eb28e66efdbe13153c13ee492b56e284dd7cc7 Mon Sep 17 00:00:00 2001
|
||||
From: Mattias Walström <lazzer@gmail.com>
|
||||
Date: Wed, 20 Aug 2025 21:38:24 +0200
|
||||
Subject: [PATCH 13/33] drm/panel-simple: Add a timing for the Raspberry Pi 7"
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 38d942ffce63ee1fa9beecf6bac3d7b30e87c87a Mon Sep 17 00:00:00 2001
|
||||
From 18b1eb460fefbd0a6dff47dc6900a5948df40a8f Mon Sep 17 00:00:00 2001
|
||||
From: Mattias Walström <lazzer@gmail.com>
|
||||
Date: Thu, 21 Aug 2025 11:20:23 +0200
|
||||
Subject: [PATCH 14/33] input:touchscreen:edt-ft5x06: Add polled mode
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 60cd0f84c208ab9bc53ad070e81bb0173e356889 Mon Sep 17 00:00:00 2001
|
||||
From 70a3642435e2510a8f16e2115a7b555dc3ec64b4 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 12 Mar 2024 10:27:24 +0100
|
||||
Subject: [PATCH 15/33] [FIX] net: dsa: mv88e6xxx: Fix timeout on waiting for
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From de9af4997489a4f2a4110412b418bb7a317664fe Mon Sep 17 00:00:00 2001
|
||||
From a8f89c96786d6dfc6d7c728b92e7ad33ec7cc12b Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 27 Mar 2024 15:52:43 +0100
|
||||
Subject: [PATCH 16/33] net: dsa: mv88e6xxx: Improve indirect register access
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 94db20c708ac578007ef56ebd6a4321f45ca2ba7 Mon Sep 17 00:00:00 2001
|
||||
From c1ff82cfcd6786690edce944c5a44616d42426fb Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Mon, 22 Apr 2024 23:18:01 +0200
|
||||
Subject: [PATCH 17/33] net: dsa: mv88e6xxx: Honor ports being managed via
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From a52c2c0be135f32dac53410a6f67226ecb59da58 Mon Sep 17 00:00:00 2001
|
||||
From dc2e3d0dc7bb298fb4fb25cd9befbac2cadbaa36 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 24 Apr 2024 22:41:04 +0200
|
||||
Subject: [PATCH 18/33] net: dsa: mv88e6xxx: Limit rsvd2cpu policy to user
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 668ba9f49cd17cb27145fbe579931b9ddf74ea88 Mon Sep 17 00:00:00 2001
|
||||
From 7b41de01eeac05ef76798168f1bf2aebb303410b Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 28 May 2024 10:38:42 +0200
|
||||
Subject: [PATCH 19/33] net: dsa: tag_dsa: Use tag priority as initial
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 79450dc7dd78cb3d1e3798180151e4927f3d862f Mon Sep 17 00:00:00 2001
|
||||
From 2993149c029e9c53d1538850173b585ae39b69d7 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 16 Jan 2024 16:00:55 +0100
|
||||
Subject: [PATCH 20/33] net: dsa: Support MDB memberships whose L2 addresses
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 7d282dfc8044ad74aa190203efdc350bf9ab8c97 Mon Sep 17 00:00:00 2001
|
||||
From 3402c2bee5c28a7c7e0e16cc75304749ec57895e Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 21 Mar 2024 19:12:15 +0100
|
||||
Subject: [PATCH 21/33] net: dsa: Support EtherType based priority overrides
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 2b0679aa4727f71f3858291002c3abb5eade7ca7 Mon Sep 17 00:00:00 2001
|
||||
From 103e7309ed96e845cbd2075a89e0e10b962490fa Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Fri, 22 Mar 2024 16:15:43 +0100
|
||||
Subject: [PATCH 22/33] net: dsa: mv88e6xxx: Support EtherType based priority
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 7f6fd96a6b80c541b0fba0e5cc9de10aa0801eb0 Mon Sep 17 00:00:00 2001
|
||||
From 0ebdd84bda066b82db85280a266e8d01e0872115 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 28 May 2024 11:04:22 +0200
|
||||
Subject: [PATCH 23/33] net: dsa: mv88e6xxx: Add mqprio qdisc support
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 54a42d398869bf484d31a499af28ba95ce75c412 Mon Sep 17 00:00:00 2001
|
||||
From 216d17528054c744b76f68731cdc61c2a7f16bf0 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 29 May 2024 13:20:41 +0200
|
||||
Subject: [PATCH 24/33] net: dsa: mv88e6xxx: Use VLAN prio over IP when both
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From dbc7e27badea74027b2742fe768db95e48edc4d7 Mon Sep 17 00:00:00 2001
|
||||
From e0e692a81515e6111a0d60a679dff7d1d382700c Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 26 Nov 2024 19:45:59 +0100
|
||||
Subject: [PATCH 25/33] [FIX] net: dsa: mv88e6xxx: Trap locally terminated
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 6ffe3f8912a00fd32f5607c9aa25b7ed8b408a47 Mon Sep 17 00:00:00 2001
|
||||
From b609b6ac8841e77f1c1b51bb8d20ba8c6aff28a1 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Thu, 16 Jan 2025 12:35:12 +0100
|
||||
Subject: [PATCH 26/33] net: dsa: mv88e6xxx: collapse disabled state into
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 6a87d9cd29e08b0b322233d35621d90470a974e6 Mon Sep 17 00:00:00 2001
|
||||
From 47c2f59a47315c3032e936b58a83fe6cb905b970 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 12 Feb 2025 22:03:14 +0100
|
||||
Subject: [PATCH 27/33] net: dsa: mv88e6xxx: Only activate LAG offloading when
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From d98d5f87b9f5202c55864da0f8a6e9b63a123d2e Mon Sep 17 00:00:00 2001
|
||||
From 09fcae28ec65a3b3c8e82a1ebffcefd1ef2f3076 Mon Sep 17 00:00:00 2001
|
||||
From: Mattias Walström <lazzer@gmail.com>
|
||||
Date: Wed, 14 Jan 2026 18:22:41 +0100
|
||||
Subject: [PATCH 28/33] net: dsa: mv88e6xxx: Add LED support for 6393X
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From f844b2470f23814f3d98c22fc1958958155f2370 Mon Sep 17 00:00:00 2001
|
||||
From 3fd13d10d7153f700233e4f91b2070bfa280c265 Mon Sep 17 00:00:00 2001
|
||||
From: Mattias Walström <lazzer@gmail.com>
|
||||
Date: Thu, 15 Jan 2026 22:47:37 +0100
|
||||
Subject: [PATCH 29/33] wifi: brcmfmac: support deletion and recreation of
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 58dcf72c338bd0248dad8105a4169be926d19be2 Mon Sep 17 00:00:00 2001
|
||||
From e30fdea3ea2c1d52b258d78796e8a2d5307c8e57 Mon Sep 17 00:00:00 2001
|
||||
From: Mattias Walström <lazzer@gmail.com>
|
||||
Date: Mon, 19 Jan 2026 13:06:53 +0100
|
||||
Subject: [PATCH 30/33] wifi: brcmfmac: check connection state before querying
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From b408ba43a37bb71f8ea2b83c7f4a4ba0b806f2c7 Mon Sep 17 00:00:00 2001
|
||||
From 03fbaedfaef56f23862d6b390eeb4a53830ba5b9 Mon Sep 17 00:00:00 2001
|
||||
From: Mattias Walström <lazzer@gmail.com>
|
||||
Date: Tue, 20 Jan 2026 20:12:10 +0100
|
||||
Subject: [PATCH 31/33] wifi: brcmfmac: suppress log spam for
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 2558ffc3abdbbc38a367d6a83c9133e39238339f Mon Sep 17 00:00:00 2001
|
||||
From e0da4bfce5f50959b9e1874019cfe242970a9071 Mon Sep 17 00:00:00 2001
|
||||
From: Mattias Walström <lazzer@gmail.com>
|
||||
Date: Tue, 20 Jan 2026 20:18:45 +0100
|
||||
Subject: [PATCH 32/33] wifi: brcmfmac: reduce log noise during AP to station
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From fdfab37c4e5c375c204c797f77f91ee6edcbe983 Mon Sep 17 00:00:00 2001
|
||||
From 384b9a4f22df36918c26f893a3e808a6c7879ba7 Mon Sep 17 00:00:00 2001
|
||||
From: Mattias Walström <lazzer@gmail.com>
|
||||
Date: Tue, 17 Feb 2026 21:59:59 +0100
|
||||
Subject: [PATCH 33/33] net: phy: air_en8811h: add OF device table for
|
||||
@@ -1,2 +1,2 @@
|
||||
# Calculated with utils/kernel-refresh.sh
|
||||
sha256 7c716216c3c4134ed0de69195701e677577bbcdd3979f331c182acd06bf2f170 linux-6.18.15.tar.xz
|
||||
sha256 8d1934a72a185f1be6b56e3ad8ea31fd9a381ffec0346c69f06c90d776da7cb8 linux-6.18.14.tar.xz
|
||||
|
||||
+3
-4
@@ -466,7 +466,7 @@ static int curl(char *op, const char *path, const char *uri)
|
||||
{
|
||||
char *argv[10] = { "curl", "-L", NULL };
|
||||
int err = 1, i = 2;
|
||||
int path_i, uri_i = 0, user_i = 0;
|
||||
int path_i, uri_i, user_i = 0;
|
||||
|
||||
argv[i++] = op;
|
||||
|
||||
@@ -492,8 +492,7 @@ static int curl(char *op, const char *path, const char *uri)
|
||||
|
||||
out:
|
||||
free(argv[path_i]);
|
||||
if (uri_i)
|
||||
free(argv[uri_i]);
|
||||
free(argv[uri_i]);
|
||||
if (user_i)
|
||||
free(argv[user_i]);
|
||||
return err;
|
||||
@@ -753,7 +752,7 @@ static int copy(const char *src, const char *dst)
|
||||
* meaningful name instead: the datastore's on-disk filename, or the
|
||||
* source file's own basename.
|
||||
*/
|
||||
if (dst && is_ssh_uri(dst) && dst[strlen(dst) - 1] == '/') {
|
||||
if (is_ssh_uri(dst) && dst[strlen(dst) - 1] == '/') {
|
||||
const char *bn, *slash;
|
||||
|
||||
if (srcds && srcds->path) {
|
||||
|
||||
@@ -144,7 +144,7 @@ static void add(const char *ifname, struct lyd_node *cfg)
|
||||
|
||||
fprintf(fp, "# Generated by Infix confd\n");
|
||||
fprintf(fp, "metric=%s\n", metric);
|
||||
fprintf(fp, "service <!pid/netd> name:dhcp-client :%s <net/%s/running> \\\n"
|
||||
fprintf(fp, "service <!> name:dhcp-client :%s <net/%s/running> \\\n"
|
||||
" [2345] udhcpc -f -p /run/dhcp-client-%s.pid -t 3 -T 5 -A 30 %s -S -R \\\n"
|
||||
" %s%s \\\n"
|
||||
" -i %s %s %s \\\n"
|
||||
|
||||
+12
-11
@@ -695,17 +695,18 @@ int hardware_change(sr_session_ctx_t *session, struct lyd_node *config, struct l
|
||||
wifi_find_interfaces_on_radio(interfaces_config, name,
|
||||
&wifi_iface_list, &wifi_iface_count);
|
||||
|
||||
if (wifi_iface_list) {
|
||||
if (wifi_iface_count) {
|
||||
/* Generate AP config (hostapd) for all APs on this radio */
|
||||
rc = wifi_gen_aps_on_radio(name, interfaces_config, cwifi_radio, config);
|
||||
if (rc != SR_ERR_OK)
|
||||
ERROR("Failed to generate AP config for radio %s", name);
|
||||
}
|
||||
free(wifi_iface_list);
|
||||
wifi_iface_list = NULL;
|
||||
wifi_iface_count = 0;
|
||||
}
|
||||
|
||||
if (!wifi_iface_count)
|
||||
continue;
|
||||
|
||||
/* Generate AP config (hostapd) for all APs on this radio */
|
||||
rc = wifi_gen_aps_on_radio(name, interfaces_config, cwifi_radio, config);
|
||||
if (rc != SR_ERR_OK)
|
||||
ERROR("Failed to generate AP config for radio %s", name);
|
||||
/* Free the interface list */
|
||||
free(wifi_iface_list);
|
||||
wifi_iface_list = NULL;
|
||||
wifi_iface_count = 0;
|
||||
} else if (!strcmp(class, "infix-hardware:gps")) {
|
||||
if (event != SR_EV_DONE)
|
||||
continue;
|
||||
|
||||
@@ -458,8 +458,7 @@ static void frr_daemons_write(int ospfd, int ripd, int bfdd)
|
||||
fp);
|
||||
|
||||
fclose(fp);
|
||||
if (rename(next, FRR_DAEMONS))
|
||||
ERROR("Failed to rename %s to %s: %m", next, FRR_DAEMONS);
|
||||
rename(next, FRR_DAEMONS);
|
||||
}
|
||||
|
||||
int routing_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
@@ -520,6 +519,7 @@ int routing_change(sr_session_ctx_t *session, struct lyd_node *config, struct ly
|
||||
num = parse_rip(session, lydx_get_child(cplane, "rip"), fp);
|
||||
if (num > 0) {
|
||||
touch(RIPD_SIGNAL_NEXT);
|
||||
ripd_enabled = 1;
|
||||
netd_enabled = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,15 +178,9 @@
|
||||
</COMMAND>
|
||||
|
||||
<COMMAND name="upgrade" help="Upgrade image of a container (writable layer is lost!)">
|
||||
<PARAM name="name" ptype="/CONTAINERSa" help="Container name" />
|
||||
<SWITCH name="optional" min="0" max="1">
|
||||
<COMMAND name="reset-volumes" help="Delete named volumes, re-initialize from new image (all config lost!)" />
|
||||
</SWITCH>
|
||||
<PARAM name="name" ptype="/CONTAINERS" help="Container name" />
|
||||
<ACTION sym="script" out="tty" interrupt="true">
|
||||
if env | grep -q 'reset-volumes' >/dev/null; then
|
||||
opt="-R"
|
||||
fi
|
||||
doas container $opt upgrade $KLISH_PARAM_name
|
||||
doas container upgrade $KLISH_PARAM_name
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
</COMMAND>
|
||||
|
||||
@@ -461,7 +461,7 @@ echo "Public: $pub"
|
||||
<ACTION sym="printl">peer</ACTION>
|
||||
</COMPL>
|
||||
</PARAM>
|
||||
<PARAM name="peer" ptype="/STRING" help="Peer IP address" min="0" max="1"/>
|
||||
<PARAM name="peer_addr" ptype="/STRING" help="Peer IP address" min="0" max="1"/>
|
||||
<SWITCH name="optional" min="0">
|
||||
<COMMAND name="brief" help="Show brief output" mode="switch"/>
|
||||
</SWITCH>
|
||||
@@ -471,7 +471,7 @@ echo "Public: $pub"
|
||||
BRIEF_ARG="brief"
|
||||
fi
|
||||
# Pass subcommand, optional peer address, and brief flag
|
||||
show bfd ${KLISH_PARAM_subcommand:+"$KLISH_PARAM_subcommand"} ${KLISH_PARAM_peer:+"$KLISH_PARAM_peer"} ${BRIEF_ARG:+"$BRIEF_ARG"} |pager
|
||||
show bfd ${KLISH_PARAM_subcommand:+"$KLISH_PARAM_subcommand"} ${KLISH_PARAM_peer_addr:+"$KLISH_PARAM_peer_addr"} ${BRIEF_ARG:+"$BRIEF_ARG"} |pager
|
||||
</ACTION>
|
||||
</COMMAND>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ IMAGE_ID="infix-x86_64"
|
||||
ARCHITECTURE="x86_64"
|
||||
HOME_URL=https://github.com/kernelkit/infix/
|
||||
VENDOR_NAME="KernelKit"
|
||||
VENDOR_HOME="https://www.kernelkit.org"
|
||||
DOCUMENTATION_URL="https://www.kernelkit.org/infix/"
|
||||
VENDOR_HOME="https://kernelkit.org"
|
||||
DOCUMENTATION_URL="https://kernelkit.org/infix/"
|
||||
SUPPORT_URL="mailto:kernelkit@googlegroups.com"
|
||||
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from 5 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
|
||||
|
||||
Executable
+209
@@ -0,0 +1,209 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import random
|
||||
import struct
|
||||
|
||||
class ID:
|
||||
def __init__(self):
|
||||
charset = "abcdefghijklmnopqrstuvwxyz"
|
||||
charset += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
charset += "0123456789"
|
||||
|
||||
b = random.choices(charset, k=32)
|
||||
self.bytes = "".join(b).encode()
|
||||
|
||||
def dashed(self):
|
||||
return self.bytes[0:6].decode() + \
|
||||
"-" + self.bytes[6:10].decode() + \
|
||||
"-" + self.bytes[10:14].decode() + \
|
||||
"-" + self.bytes[14:18].decode() + \
|
||||
"-" + self.bytes[18:22].decode() + \
|
||||
"-" + self.bytes[22:26].decode() + \
|
||||
"-" + self.bytes[26:32].decode()
|
||||
|
||||
def crc32(data: bytes) -> int:
|
||||
crc = 0xf597a6cf
|
||||
|
||||
for byte in data:
|
||||
crc ^= byte
|
||||
for _ in range(8):
|
||||
if crc & 1:
|
||||
crc = (crc >> 1) ^ 0xedb88320
|
||||
else:
|
||||
crc >>= 1
|
||||
|
||||
return crc & 0xffffffff
|
||||
|
||||
def sendfile(dst, src, count):
|
||||
while count > 0:
|
||||
chunk = os.sendfile(dst, src, None, count)
|
||||
if chunk < 0:
|
||||
raise OSError("sendfile")
|
||||
|
||||
count -= chunk
|
||||
|
||||
class Linear:
|
||||
def __init__(self, start, align, path, name=None):
|
||||
self.id = ID()
|
||||
self.name = name if name else os.path.basename(path)
|
||||
self.path = path
|
||||
self.start = start
|
||||
self.align = align
|
||||
self.size = os.path.getsize(path)
|
||||
self.asize = (self.size + align - 1) & ~(align - 1)
|
||||
|
||||
def sendfile(self, fd):
|
||||
pad = self.asize - self.size
|
||||
|
||||
with open(self.path, "rb") as f:
|
||||
sendfile(fd, f.fileno(), self.size)
|
||||
|
||||
if pad:
|
||||
os.write(fd, b"\0" * pad)
|
||||
|
||||
def meta(self):
|
||||
return f""" {self.name} {{
|
||||
id = "{self.id.dashed()}"
|
||||
status = ["READ", "WRITE", "VISIBLE"]
|
||||
segment_count = 1
|
||||
|
||||
segment1 {{
|
||||
start_extent = 0
|
||||
extent_count = {self.asize // self.align }
|
||||
type = "striped"
|
||||
stripe_count = 1
|
||||
stripes = [
|
||||
"pv0", {self.start // self.align }
|
||||
]
|
||||
}}
|
||||
}}"""
|
||||
|
||||
class InternalPV:
|
||||
def __init__(self, images=[], align=(1 << 20), creation_time=0):
|
||||
self.pvid = ID()
|
||||
self.vgid = ID()
|
||||
self.align = align
|
||||
self.creation_time = creation_time
|
||||
|
||||
self.lvs = []
|
||||
self.dsize = 0
|
||||
for img in images:
|
||||
lv = Linear(self.dsize, align, img)
|
||||
self.lvs.append(lv)
|
||||
self.dsize += lv.asize
|
||||
|
||||
# Reserve `align` bytes for primary metadata area, the size
|
||||
# used by all LVs, and another `aligned` bytes for the backup
|
||||
# metadata area
|
||||
self.size = align + self.dsize + align
|
||||
|
||||
def write(self, dst):
|
||||
for i in range(4):
|
||||
dst.write(self._label(i))
|
||||
|
||||
dst.write(b"\0" * 0x800)
|
||||
|
||||
dst.write(self._metadata(True))
|
||||
|
||||
for lv in self.lvs:
|
||||
lv.sendfile(dst.fileno())
|
||||
|
||||
dst.write(self._metadata(False))
|
||||
|
||||
def _label(self, sector: int):
|
||||
headfmt, tailfmt = "<8s Q I", "<I8s 32sQ QQ QQ QQ QQ QQ II"
|
||||
padsize = 512 - struct.calcsize(headfmt) - struct.calcsize(tailfmt)
|
||||
|
||||
tail = struct.pack(tailfmt,
|
||||
32, b"LVM2 001",
|
||||
self.pvid.bytes, self.size,
|
||||
# Data area (size=0 ~= all available space (?))
|
||||
self.align, 0,
|
||||
0, 0,
|
||||
# Primary metadata area
|
||||
0x1000, self.align - 0x1000,
|
||||
# Backup metadata area
|
||||
self.align + self.dsize, self.align,
|
||||
0, 0,
|
||||
# Supported extensions (Unsure which
|
||||
# extensions this maps to, but it makes the
|
||||
# LVM tooling happy :))
|
||||
2, 1) + b"\0" * padsize
|
||||
|
||||
head = struct.pack(headfmt, b"LABELONE", sector, crc32(tail))
|
||||
|
||||
return head + tail
|
||||
|
||||
def _metadata(self, primary):
|
||||
headfmt, tailfmt = "<I", "<16sI QQ QQII QQII"
|
||||
padsize = 512 - struct.calcsize(headfmt) - struct.calcsize(tailfmt)
|
||||
|
||||
offs = 0x1000 if primary else (self.align + self.dsize)
|
||||
size = self.align - 0x1000 if primary else self.align
|
||||
|
||||
txt = self._meta_txt()
|
||||
txtpadsize = size - 512 - len(txt)
|
||||
|
||||
tail = struct.pack(tailfmt,
|
||||
b" LVM2 x[5A%r0N*>", 1,
|
||||
offs, size,
|
||||
512, len(txt), crc32(txt), 0,
|
||||
0, 0, 0, 0) + b"\0" * padsize
|
||||
|
||||
head = struct.pack(headfmt, crc32(tail))
|
||||
|
||||
return head + tail + txt + bytes([0] * txtpadsize)
|
||||
|
||||
def _meta_txt(self):
|
||||
return f"""internal {{
|
||||
id = "{self.vgid.dashed()}"
|
||||
seqno = 1
|
||||
status = ["RESIZEABLE", "READ", "WRITE"]
|
||||
extent_size = {self.align >> 9}
|
||||
max_pv = 0
|
||||
max_lv = 0
|
||||
metadata_copies = 2
|
||||
|
||||
physical_volumes {{
|
||||
pv0 {{
|
||||
id = "{self.pvid.dashed()}"
|
||||
dev = "/dev/internal"
|
||||
status = ["ALLOCATABLE"]
|
||||
dev_size = {self.size >> 9}
|
||||
pe_start = {self.align >> 9}
|
||||
pe_count = {self.dsize // self.align }
|
||||
}}
|
||||
}}
|
||||
|
||||
logical_volumes {{
|
||||
{"\n".join([lv.meta() for lv in self.lvs])}
|
||||
}}
|
||||
}}
|
||||
|
||||
contents = "Text Format Volume Group"
|
||||
version = 1
|
||||
description = "Internal image storage"
|
||||
creation_host = "infix-build-system"
|
||||
creation_time = {self.creation_time}
|
||||
""".encode()
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
import datetime
|
||||
import sys
|
||||
|
||||
parser = argparse.ArgumentParser(description="Create LVM PV containing a set of images")
|
||||
parser.add_argument("-T", "--creation-time", metavar="TIMESTAMP",
|
||||
default=int(datetime.datetime.now().timestamp()))
|
||||
parser.add_argument("images", metavar="IMAGE", nargs="*")
|
||||
args = parser.parse_args()
|
||||
|
||||
random.seed(args.creation_time)
|
||||
|
||||
pv = InternalPV(args.images, creation_time=args.creation_time)
|
||||
pv.write(sys.stdout.buffer)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user