Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d1d8c31
feat(log): add Ubuntu cloud image support
userhaptop Feb 7, 2026
41c8329
feat(log): add Ubuntu cloud image support
userhaptop Feb 7, 2026
4cfedfc
feat(log): fix format error
userhaptop Feb 7, 2026
627de0f
feat(log): add multi-distro image support, custom image handling, and…
userhaptop Feb 10, 2026
edb0208
feat(log): Solving the problem of comments being abnormally overwritten
userhaptop Feb 10, 2026
baf42f5
feat(log): add Ubuntu/Fedora/Arch + custom images, streaming hash, an…
userhaptop Feb 22, 2026
f52f7e2
feat(log): Adjust file structure
userhaptop Feb 22, 2026
ee25d9a
feat(log): Adjust file structure
userhaptop Feb 22, 2026
f0f82b5
Merge branch 'main' into main
userhaptop Feb 22, 2026
e312ef9
ci: rerun
userhaptop Feb 22, 2026
da0ede4
tests: remove obsolete streaming_hash and custom_image tests
userhaptop Feb 22, 2026
fcdc6b3
feat(log): Split VM prerequisites vs image-extraction deps so Ubuntu …
userhaptop Feb 22, 2026
b341929
feat(log): Fixed and enhanced issues raised in the review regarding m…
userhaptop Feb 23, 2026
826d7c8
feat(log): Improved stability of image downloads and E2E testing in W…
userhaptop Feb 24, 2026
04a4aa2
feat(log): make ubuntu/fedora/arch image tests run reliably with real…
userhaptop Feb 24, 2026
37364c7
feat(log): revert noisy serial output logging from debug to trace
userhaptop Feb 25, 2026
2b05d4b
feat(log): fmt
userhaptop Feb 25, 2026
cd214dd
feat(log): With QLEAN_RUN_E2E=1, Fedora/Arch integration tests run th…
userhaptop Mar 5, 2026
4aede8c
feat(log): Remove redundant code
userhaptop Mar 8, 2026
cf6c017
feat(log): Remove redundant code
userhaptop Mar 8, 2026
59e9c7c
feat(log): Fix configuration issues
userhaptop Mar 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ russh-sftp = "2.1.1"
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.148"
serde_yml = "0.0.12"
toml = "0.8.19"
sha2 = "0.10"
shell-escape = "0.1.5"
termion = "4.0.6"
Expand Down
27 changes: 27 additions & 0 deletions qlean-images.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Default official image sources used by Qlean integration tests.
# Users may edit these URLs/checksum files directly to point to their preferred
# official mirror or pinned image release.

[debian]
image_url = "https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2"
checksum_url = "https://cloud.debian.org/images/cloud/trixie/latest/SHA512SUMS"
checksum_entry = "debian-13-generic-amd64.qcow2"
checksum_type = "Sha512"

[ubuntu]
image_url = "https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
checksum_url = "https://cloud-images.ubuntu.com/noble/current/SHA256SUMS"
checksum_entry = "noble-server-cloudimg-amd64.img"
checksum_type = "Sha256"

[fedora]
image_url = "https://download.fedoraproject.org/pub/fedora/linux/releases/43/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-43-1.6.x86_64.qcow2"
checksum_url = "https://download.fedoraproject.org/pub/fedora/linux/releases/43/Cloud/x86_64/images/Fedora-Cloud-43-1.6-x86_64-CHECKSUM"
checksum_entry = "Fedora-Cloud-Base-Generic-43-1.6.x86_64.qcow2"
checksum_type = "Sha256"

[arch]
image_url = "https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.qcow2"
checksum_url = "https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.qcow2.SHA256"
checksum_entry = "Arch-Linux-x86_64-cloudimg.qcow2"
checksum_type = "Sha256"
158 changes: 158 additions & 0 deletions scripts/setup-host-prereqs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#!/usr/bin/env bash
set -euo pipefail

# Qlean host prerequisites helper.
#
# This script configures the explicit host prerequisites required by Qlean:
# - qemu-bridge-helper permissions for the Qlean bridge
# - the libvirt 'qlean' network and qlbr0 bridge
# - host libguestfs-tools installation/runtime verification
#
# Qlean no longer provisions or discovers fallback paths at runtime; run this
# script once before using distro image creation or E2E tests.

BRIDGE_NAME="${QLEAN_BRIDGE_NAME:-qlbr0}"
VIRSH_URI="qemu:///system"

need_root() {
if [[ "$(id -u)" -ne 0 ]]; then
echo "ERROR: Please run as root (e.g. sudo $0)" >&2
exit 1
fi
}

ensure_bridge_conf() {
mkdir -p /etc/qemu
local conf=/etc/qemu/bridge.conf

if [[ -f "$conf" ]]; then
if grep -qE "^allow[[:space:]]+all$" "$conf"; then
echo "OK: $conf already allows all bridges"
chmod 0644 "$conf"
return
fi
if grep -qE "^allow[[:space:]]+${BRIDGE_NAME}$" "$conf"; then
echo "OK: $conf already allows ${BRIDGE_NAME}"
chmod 0644 "$conf"
return
fi
fi

echo "allow ${BRIDGE_NAME}" >> "$conf"
chmod 0644 "$conf"
echo "Wrote: allow ${BRIDGE_NAME} -> $conf"
}

find_qemu_bridge_helper() {
local candidates=(
/usr/lib/qemu/qemu-bridge-helper
/usr/libexec/qemu-bridge-helper
/usr/lib64/qemu/qemu-bridge-helper
)

for p in "${candidates[@]}"; do
if [[ -x "$p" ]]; then
echo "$p"
return 0
fi
done

if command -v qemu-bridge-helper >/dev/null 2>&1; then
command -v qemu-bridge-helper
return 0
fi

return 1
}

ensure_bridge_helper_caps() {
local helper
if ! helper="$(find_qemu_bridge_helper)"; then
echo "WARN: qemu-bridge-helper not found. Install QEMU first." >&2
return
fi

if command -v setcap >/dev/null 2>&1; then
chmod u-s "$helper" || true
setcap cap_net_admin+ep "$helper"

echo "OK: setcap cap_net_admin+ep $helper"
if command -v getcap >/dev/null 2>&1; then
getcap "$helper" || true
fi
else
echo "WARN: setcap not found. On Debian/Ubuntu install libcap2-bin." >&2
fi
}

ensure_qlean_network() {
if ! command -v virsh >/dev/null 2>&1; then
echo "ERROR: virsh not found. Install libvirt-clients/libvirt-daemon-system first." >&2
exit 1
fi

if ! virsh -c "$VIRSH_URI" net-info qlean >/dev/null 2>&1; then
local xml
xml=$(mktemp)
cat > "$xml" <<EOF
<network>
<name>qlean</name>
<bridge name='${BRIDGE_NAME}'/>
<forward mode='nat'/>
<ip address='192.168.221.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.221.2' end='192.168.221.254'/>
</dhcp>
</ip>
</network>
EOF
echo "INFO: defining libvirt network qlean"
virsh -c "$VIRSH_URI" net-define "$xml"
rm -f "$xml"
else
echo "OK: libvirt network qlean already defined"
fi

echo "INFO: ensuring libvirt network qlean is active"
virsh -c "$VIRSH_URI" net-start qlean >/dev/null 2>&1 || true
virsh -c "$VIRSH_URI" net-autostart qlean >/dev/null 2>&1 || true
}

maybe_install_guestfs_tools_ubuntu() {
if ! command -v apt-get >/dev/null 2>&1; then
return
fi

if command -v guestfish >/dev/null 2>&1 \
&& command -v virt-copy-out >/dev/null 2>&1 \
&& command -v libguestfs-test-tool >/dev/null 2>&1; then
echo "OK: libguestfs tools already installed"
return
fi

echo "INFO: Installing libguestfs tools (guestfish, virt-copy-out) via apt-get"
apt-get update -y
apt-get install -y libguestfs-tools
}

verify_guestfs_runtime() {
if ! command -v libguestfs-test-tool >/dev/null 2>&1; then
echo "WARN: libguestfs-test-tool not found after installation. Check your libguestfs-tools package." >&2
return
fi

echo "INFO: Verifying host libguestfs runtime (LIBGUESTFS_BACKEND=direct libguestfs-test-tool)"
if ! LIBGUESTFS_BACKEND=direct libguestfs-test-tool; then
echo "ERROR: libguestfs-test-tool failed. Fix the host libguestfs-tools installation before using Qlean image extraction." >&2
exit 1
fi
}

need_root
ensure_bridge_conf
ensure_bridge_helper_caps
ensure_qlean_network
maybe_install_guestfs_tools_ubuntu
verify_guestfs_runtime

echo "DONE"
Loading