feat: assemble an installable Gentoo live image in an exported rootfs

This commit is contained in:
Codex
2026-10-13 04:32:18 +03:00
parent 38914cf67f
commit 0f71430b8e
32 changed files with 874 additions and 10 deletions
+33
View File
@@ -0,0 +1,33 @@
#!/bin/bash
set -euo pipefail
if [[ $# != 1 || "$1" != /hydra-output/rootfs ]]; then
echo "configure-rootfs: expected the isolated /hydra-output/rootfs export" >&2
exit 1
fi
root=$1
python3 /hydra-source/hydra/image.py configure "$root" --source /hydra-source
for group in wheel kvm video render audio; do
chroot "$root" getent group "$group" >/dev/null || chroot "$root" groupadd -r "$group"
done
if ! chroot "$root" getent passwd hydra-live >/dev/null; then
chroot "$root" useradd --uid 1000 --create-home --home-dir /home/hydra-live --shell /bin/bash --groups wheel,kvm,video,render,audio hydra-live
fi
chroot "$root" usermod --lock hydra-live
chroot "$root" usermod --lock root
chroot "$root" locale-gen
ln -snf /usr/share/zoneinfo/Europe/Moscow "$root/etc/localtime"
# Enable the ordinary per-user sound services without starting a user manager.
systemctl --root="$root" --global enable pipewire.socket wireplumber.service
# Set rootfs permissions now; capabilities are regenerated in the boot namespace.
chroot "$root" chown root:kvm /usr/libexec/qemu-bridge-helper
chroot "$root" chmod 0750 /usr/libexec/qemu-bridge-helper
chroot "$root" visudo --check
systemctl --root="$root" enable NetworkManager.service greetd.service hydra-network.service hydra-dnsmasq.service hydra-bridge-permissions.service getty@tty2.service serial-getty@ttyS0.service
systemctl --root="$root" set-default graphical.target
# This is a separate rootfs inside the assembly container, never the host root.
mount --bind /dev "$root/dev"
mount -t proc proc "$root/proc"
mount --bind /sys "$root/sys"
trap 'umount "$root/sys" "$root/proc" "$root/dev"' EXIT
kernel=$(python3 /hydra-source/hydra/image.py kernel "$root")
chroot "$root" dracut --force --no-hostonly --no-hostonly-cmdline --conf /etc/hydra/live-mode/dracut.conf --confdir /etc/hydra/live-mode/dracut.conf.d --add dmsquash-live /boot/initramfs-live.img "$kernel"
+6
View File
@@ -0,0 +1,6 @@
hostonly="no"
hostonly_cmdline="no"
add_dracutmodules+=" dmsquash-live "
filesystems+=" squashfs overlay iso9660 vfat ext4 "
add_drivers+=" vmd nvme xhci_pci thunderbolt usb_storage uas sd_mod virtio_pci virtio_blk virtio_scsi virtio_net virtio_gpu i915 loop squashfs overlay sr_mod ahci "
compress="zstd"
+12
View File
@@ -0,0 +1,12 @@
set default=0
set timeout=5
insmod all_video
insmod serial
serial --unit=0 --speed=115200
terminal_input console serial
terminal_output console serial
menuentry "HydraOS live (volatile host root)" {
search --no-floppy --label HYDRA_OS --set=root
linux /boot/vmlinuz root=live:CDLABEL=HYDRA_OS rd.live.image rd.live.overlay.overlayfs=1 ro console=tty0 console=ttyS0,115200n8
initrd /boot/initramfs-live.img
}
+1
View File
@@ -28,3 +28,4 @@ dev-libs/libisoburn
dev-lang/python
sec-keys/openpgp-keys-gentoo-release
sec-keys/openpgp-keys-gentoo-auth
sys-apps/brightnessctl
+1 -1
View File
@@ -7,7 +7,7 @@ MAKEOPTS="-j4"
EMERGE_DEFAULT_OPTS="--jobs=1 --getbinpkg --binpkg-respect-use=y --autounmask=n"
FEATURES="getbinpkg binpkg-request-signature -usersandbox -sandbox -network-sandbox -ipc-sandbox -pid-sandbox"
ACCEPT_LICENSE="@FREE @BINARY-REDISTRIBUTABLE linux-fw-redistributable no-source-code Intel-SDP"
VIDEO_CARDS="intel"
VIDEO_CARDS="intel virgl"
USE="X dbus wayland opengl alsa"
QEMU_SOFTMMU_TARGETS="x86_64"
QEMU_USER_TARGETS=""
+3
View File
@@ -0,0 +1,3 @@
GRUB_DISTRIBUTOR="HydraOS"
GRUB_TIMEOUT=5
GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
@@ -0,0 +1,3 @@
hostonly="no"
hostonly_cmdline="no"
omit_dracutmodules+=" dmsquash-live "
+5
View File
@@ -0,0 +1,5 @@
[terminal]
vt = 1
[default_session]
command = "/usr/bin/agreety --cmd /usr/bin/hydra-session"
user = "greetd"
+8
View File
@@ -0,0 +1,8 @@
[terminal]
vt = 1
[default_session]
command = "/usr/bin/agreety --cmd /usr/bin/hydra-session"
user = "greetd"
[initial_session]
command = "/usr/bin/hydra-session"
user = "hydra-live"
+5
View File
@@ -0,0 +1,5 @@
network = "bridge"
bridge = "hydrabr0"
width = 1920
height = 1080
refresh_millihz = 144000
+11
View File
@@ -0,0 +1,11 @@
interface=hydrabr0
bind-dynamic
except-interface=lo
listen-address=10.203.0.1
dhcp-range=10.203.0.20,10.203.0.254,255.255.255.0,12h
dhcp-option=option:router,10.203.0.1
dhcp-option=option:dns-server,10.203.0.1
dhcp-leasefile=/var/lib/hydra/dnsmasq.leases
resolv-file=/run/NetworkManager/resolv.conf
domain-needed
bogus-priv
+1
View File
@@ -0,0 +1 @@
HydraOS live medium: changes to the host root are not persistent.
@@ -0,0 +1,7 @@
[
"/etc/greetd/live.toml",
"/etc/sudoers.d/90-hydra-live",
"/etc/systemd/system/greetd.service.d/90-hydra-live.conf",
"/etc/systemd/system/getty@tty2.service.d/90-hydra-live.conf",
"/etc/systemd/system/serial-getty@ttyS0.service.d/90-hydra-live.conf"
]
+1
View File
@@ -0,0 +1 @@
LANG=en_US.UTF-8
+2
View File
@@ -0,0 +1,2 @@
en_US.UTF-8 UTF-8
ru_RU.UTF-8 UTF-8
+5
View File
@@ -0,0 +1,5 @@
HydraOS: fullscreen VMs with an ordinary Gentoo host underneath.
Live host changes are volatile. Use sudo hydra-install for the guarded installer.
Use hydra --help, nmcli, or nmtui to configure VMs and network connections.
Ctrl+Alt+F2 opens local recovery; return to the graphical session on Ctrl+Alt+F1.
Guest bridge: 10.203.0.0/24. Routed LAN access requires a route on your LAN router.
+6
View File
@@ -0,0 +1,6 @@
# Preserve the scoped bridge-helper permission after ordinary QEMU updates.
post_pkg_postinst() {
if [[ ${CATEGORY}/${PN} == app-emulation/qemu ]]; then
"${EROOT}usr/libexec/hydra-bridge-permissions" || die "Hydra bridge permissions failed"
fi
}
+1
View File
@@ -0,0 +1 @@
allow hydrabr0
@@ -0,0 +1 @@
%wheel ALL=(ALL:ALL) ALL
+1
View File
@@ -0,0 +1 @@
hydra-live ALL=(ALL:ALL) NOPASSWD: ALL
@@ -0,0 +1 @@
net.ipv4.ip_forward = 1
@@ -0,0 +1,3 @@
[Login]
KillUserProcesses=no
UserStopDelaySec=infinity
@@ -0,0 +1,3 @@
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin hydra-live --noclear %I $TERM
@@ -0,0 +1,3 @@
[Service]
ExecStart=
ExecStart=/usr/bin/greetd --config /etc/greetd/live.toml
@@ -0,0 +1,8 @@
[Unit]
Description=Restrict QEMU bridge helper to HydraOS VM users
Before=greetd.service
[Service]
Type=oneshot
ExecStart=/usr/libexec/hydra-bridge-permissions
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,12 @@
[Unit]
Description=DHCP and DNS for HydraOS guests
Requires=hydra-network.service
PartOf=hydra-network.service
After=hydra-network.service NetworkManager.service
[Service]
Type=simple
StateDirectory=hydra
ExecStart=/usr/sbin/dnsmasq --keep-in-foreground --conf-file=/etc/hydra/dnsmasq.conf
Restart=on-failure
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,12 @@
[Unit]
Description=HydraOS guest bridge and Internet NAT
Requires=NetworkManager.service
PartOf=NetworkManager.service
After=NetworkManager.service
Before=hydra-dnsmasq.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/hydra-network
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,3 @@
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin hydra-live --noclear %I $TERM
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
set -eu
helper=/usr/libexec/qemu-bridge-helper
[ -f "$helper" ] && [ ! -L "$helper" ]
chown root:kvm "$helper"
chmod 0750 "$helper"
setcap cap_net_admin+ep "$helper"