Browse Source

initial commit

main
Nicolas Massé 6 months ago
commit
6be518a3ab
  1. 8
      bootc/.gitignore
  2. 32
      bootc/Containerfile
  3. 163
      bootc/artefacts-iso.sh
  4. 40
      bootc/artefacts-qcow2.sh
  5. 37
      bootc/build.sh
  6. 37
      bootc/common.sh
  7. 12
      bootc/config-iso.toml
  8. 0
      bootc/config-qcow2.toml
  9. 17
      bootc/env.sh
  10. 1
      bootc/post/etc/NetworkManager/system-connections/.gitignore
  11. 23
      bootc/post/etc/NetworkManager/system-connections/Sample-Wifi.nmconnection
  12. 1
      bootc/pre/etc/NetworkManager/system-connections/.gitignore
  13. 23
      bootc/pre/etc/NetworkManager/system-connections/Sample-Wifi.nmconnection
  14. 23
      bootc/root/etc/containers/systemd/intelligent-train.container
  15. 20
      bootc/root/etc/containers/systemd/mosquitto.container
  16. 6
      bootc/root/etc/intelligent-train.env
  17. 7
      bootc/root/etc/mosquitto/mosquitto.conf
  18. 1
      bootc/root/etc/motd.d/hello-world
  19. 15
      bootc/root/etc/systemd/system/nvidia-ctk-init.service
  20. 12
      bootc/root/etc/systemd/system/repo-intelligent-train.service
  21. 2
      bootc/root/etc/vconsole.conf
  22. 2
      bootc/root/usr/lib/bootc/kargs.d/00-console.toml
  23. 60
      bootc/template-offline.ks
  24. 64
      bootc/template-online.ks
  25. 70
      bootc/test.sh

8
bootc/.gitignore

@ -0,0 +1,8 @@
/etc
*.pem
auth.json
cache-*/
*.iso
*.qcow2
*.tar
osbuild.ks

32
bootc/Containerfile

@ -0,0 +1,32 @@
FROM registry.redhat.io/rhel9/rhel-bootc:9.4
ARG ADMIN_USERNAME=demo \
ADMIN_PASSWORD=redhat \
NVIDIA_KERNEL_VERSION=5.14.0-427.22.1.el9_4
RUN set -Eeuo pipefail ; \
if ! grep -qxF 'keepcache=1'; then \
sed -i.bak '/^\[main\]$/a keepcache=1' /etc/dnf/dnf.conf ; \
fi ; \
echo "Replacing current kernel with a version compatible with the kernel modules shipped by Nvidia" ; \
mkdir -p /tmp/rpms ; \
dnf download -y --destdir /tmp/rpms kernel{,-core,-modules,-modules-core}-$NVIDIA_KERNEL_VERSION ; \
rpm-ostree override replace /tmp/rpms/*.rpm ; \
rm -rf /tmp/rpms ; \
dnf config-manager --enable codeready-builder-for-rhel-9-$(arch)-rpms ; \
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm ; \
dnf install -y mkpasswd NetworkManager-wifi podman skopeo git mosquitto ; \
if [[ "$(arch)" == "aarch64" ]]; then \
echo "Installing the Nvidia stuff..." ; \
curl -sSfL -o /etc/yum.repos.d/nvidia-l4t.repo https://repo.download.nvidia.com/jetson/rhel-9.4/r36.3.1/nvidia-l4t.repo ; \
curl -sSfL -o /etc/yum.repos.d/nvidia-container-toolkit.repo https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo ; \
dnf config-manager --enable nvidia-container-toolkit-experimental ; \
dnf install -y nvidia-jetpack-kmod nvidia-jetpack-all nvidia-container-toolkit-base ; \
fi ; \
useradd -m -G wheel -p "$(echo -n "$ADMIN_PASSWORD" | mkpasswd -m bcrypt --stdin)" "$ADMIN_USERNAME"
ADD --chown=root:root root /
RUN set -Eeuo pipefail ; \
systemctl enable nvidia-ctk-init.service ; \
systemctl enable repo-intelligent-train.service

163
bootc/artefacts-iso.sh

@ -0,0 +1,163 @@
#!/bin/sh
set -Eeuo pipefail
# Source variables and environment
source ./env.sh
# Kernel command line params per architecture
# Note: You can use multiple console= options; boot messages will be displayed on all consoles, but anaconda will put its display on the last console listed.
declare -A ARCH_KERNEL_CMDLINE=(["aarch64"]="console=ttyTCU0 console=tty0" ["x86_64"]="console=ttyS0 console=tty0")
###
### KICKSTART
###
##
## If you need to embed a file in the kickstart (pre/post script), encode it in Base32 as such:
##
# umask 0700
# mkdir -p \$XDG_RUNTIME_DIR/containers
# base32 -d > \$XDG_RUNTIME_DIR/containers/auth.json <<"EOB32"
# $(base32 -w 80 auth.json)
# EOB32
declare -a KICKSTART_ADDITIONAL_FILES_TAR_CMD_PRE=( )
declare -a KICKSTART_ADDITIONAL_FILES_TAR_CMD_POST=( tar -zc -C post --owner=root --group=root . )
declare -A KICKSTART_SNIPPETS=()
KICKSTART_SNIPPETS+=( ["restart networkmanager"]="
systemctl restart --no-block NetworkManager.service
" )
KICKSTART_SNIPPETS+=( ["bootc switch"]="
bootc switch --mutate-in-place --transport registry $TARGET_IMAGE
" )
KICKSTART_SNIPPETS+=( ["/etc/ostree/auth.json"]="
base32 -d > /etc/ostree/auth.json <<\"EOB32\"
$(base32 -w 80 auth.json)
EOB32
chmod 600 /etc/ostree/auth.json
" )
KICKSTART_SNIPPETS+=( ["/etc/containers/registries.conf.d/bootc-registry.conf"]="
cat > /etc/containers/registries.conf.d/bootc-registry.conf <<\"EOF\"
[[registry]]
location=\"${TARGET_IMAGE%%/*}\"
insecure=true
EOF
" )
# Inject NetworkManager connections to kickstart
KICKSTART_SNIPPETS+=( ["/etc/NetworkManager/system-connections"]="" )
if [ -d root/etc/NetworkManager/system-connections ]; then
for file in root/etc/NetworkManager/system-connections/*.nmconnection; do
filename="$(basename "$file")"
KICKSTART_SNIPPETS["/etc/NetworkManager/system-connections"]+="
base32 -d > \"/etc/NetworkManager/system-connections/$filename\" <<\"EOB32\"
$(base32 -w 80 "$file")
EOB32
"
done
fi
# Inject arbitrary files in kickstart
if [ -d pre ]; then
KICKSTART_SNIPPETS+=( ["additional files pre"]="
base32 -d <<\"EOB32\" | tar -zx -C / --warning=none
$(cd pre && tar -zc --owner=root --group=root * | base32 -w 80)
EOB32
" )
else
KICKSTART_SNIPPETS+=( ["additional files pre"]="" )
fi
if [ -d post ]; then
KICKSTART_SNIPPETS+=( ["additional files post"]="
base32 -d <<\"EOB32\" | tar -zx -C / --warning=none
$(cd post && tar -zc --owner=root --group=root * | base32 -w 80)
EOB32
" )
else
KICKSTART_SNIPPETS+=( ["additional files post"]="" )
fi
KICKSTART_PREPOST_ONLINE="
##
## Pre/post-install scripts
##
%pre --interpreter=/bin/bash --logfile=/tmp/anaconda-pre.log --erroronfail
set -Eeuo pipefail
${KICKSTART_SNIPPETS["/etc/ostree/auth.json"]}
${KICKSTART_SNIPPETS["/etc/containers/registries.conf.d/bootc-registry.conf"]}
${KICKSTART_SNIPPETS["/etc/NetworkManager/system-connections"]}
${KICKSTART_SNIPPETS["additional files pre"]}
${KICKSTART_SNIPPETS["restart networkmanager"]}
%end
%post --interpreter=/bin/bash --logfile=/var/log/anaconda-post.log --erroronfail
set -Eeuo pipefail
${KICKSTART_SNIPPETS["/etc/ostree/auth.json"]}
${KICKSTART_SNIPPETS["/etc/containers/registries.conf.d/bootc-registry.conf"]}
${KICKSTART_SNIPPETS["/etc/NetworkManager/system-connections"]}
${KICKSTART_SNIPPETS["additional files post"]}
%end
"
KICKSTART_PREPOST_OFFLINE="
##
## Pre/post-install scripts
##
%pre --interpreter=/bin/bash --logfile=/tmp/anaconda-pre.log --erroronfail
${KICKSTART_SNIPPETS["additional files pre"]}
${KICKSTART_SNIPPETS["restart networkmanager"]}
%end
%post --interpreter=/bin/bash --logfile=/var/log/anaconda-post.log --erroronfail
set -Eeuo pipefail
${KICKSTART_SNIPPETS["/etc/ostree/auth.json"]}
${KICKSTART_SNIPPETS["/etc/containers/registries.conf.d/bootc-registry.conf"]}
${KICKSTART_SNIPPETS["bootc switch"]}
${KICKSTART_SNIPPETS["additional files post"]}
%end
"
declare -A KICKSTART_PREPOST=(["online"]="$KICKSTART_PREPOST_ONLINE" ["offline"]="$KICKSTART_PREPOST_OFFLINE")
# Types of ISO with kickstart to build
declare -a KICKSTART_TYPES=("online" "offline")
ARCH="$(arch)"
for type in "${KICKSTART_TYPES[@]}"; do
KICKSTART_FILE="template-$type.ks"
echo "Templating Kickstart $KICKSTART_FILE..."
(
export ARCH
export TARGET_IMAGE
export KERNEL_CMDLINE="${ARCH_KERNEL_CMDLINE[$ARCH]}"
envsubst < "$KICKSTART_FILE" > osbuild.ks
echo "${KICKSTART_PREPOST[$type]}" >> osbuild.ks
)
echo "Validating Kickstart..."
ksvalidator osbuild.ks
if [[ "$type" == "offline" ]]; then
echo "Exporting container image..."
# Shortcut: tag the container image as if it had been pulled from the registry (save a roundtrip with the registry)
podman tag localhost/$NAME-$ARCH $TARGET_IMAGE
# Export the container image as oci-dir to embed it later in the
mkdir -p cache-$ARCH
rm -rf cache-$ARCH/container
podman save --format oci-dir -o cache-$ARCH/container $TARGET_IMAGE
# Remove shortcut to prevent side effects
podman rmi $TARGET_IMAGE
fi
echo "Injecting artefacts into ISO $type..."
rm -f "install-$NAME-$ARCH-$type.iso"
if [[ "$type" == "offline" ]]; then
mkkiso_extra_args="-a cache-$ARCH/container"
else
mkkiso_extra_args=""
fi
mkksiso -R 'set timeout=60' 'set timeout=5' -R 'set default="1"' 'set default="0"' -c "${ARCH_KERNEL_CMDLINE[$ARCH]}" $mkkiso_extra_args --ks "osbuild.ks" "rhel-$RHEL_VERSION-$ARCH-boot.iso" "install-$NAME-$ARCH-$type.iso"
done

40
bootc/artefacts-qcow2.sh

@ -0,0 +1,40 @@
#!/bin/sh
set -Eeuo pipefail
# Source variables and environment
source ./env.sh
function bootc_image_builder () {
local type="$1"
local rpmmd="$2"
local store="$3"
local output="$4"
local config_file="$5"
local image="$6"
shift 6
local -a args=("$@")
echo "Running bootc-image-builder with type = '$type', image = '$image' and opts = '$@'..."
podman run --rm --network "$PODMAN_NETWORK" --privileged --security-opt label=type:unconfined_t \
-v "$config_file:/config.toml:ro" -v "$output:/output" -v "$rpmmd:/rpmmd" -v "$store:/store" \
-v /var/lib/containers/storage:/var/lib/containers/storage \
-v "$REGISTRY_AUTH_FILE:/auth.json:ro" -e "REGISTRY_AUTH_FILE=/auth.json" \
"$BOOTC_IMAGE:$RHEL_VERSION" --type "$type" --config /config.toml "$image" "${args[@]}"
}
arch="$(arch)"
mkdir -p cache-$arch/{rpmmd,store,output}
# Shortcut: tag the container image as if it had been pulled from the registry (save a roundtrip with the registry)
podman tag localhost/$NAME-$arch $TARGET_IMAGE
# Build ISO with Kickstart
#bootc_image_builder iso "$PWD/image-$arch/rpmmd" "$PWD/image-$arch/store" "$PWD/image-$arch/output" "$PWD/config-iso.toml" "$TARGET_IMAGE" --local --log-level info
#cp "image-$arch/output/bootiso/install.iso" "install-$NAME-$arch.iso"
# Build qcow2
bootc_image_builder qcow2 "$PWD/cache-$arch/rpmmd" "$PWD/cache-$arch/store" "$PWD/cache-$arch/output" "$PWD/config-qcow2.toml" "$TARGET_IMAGE" --local
cp "cache-$arch/output/qcow2/disk.qcow2" "disk-$NAME-$arch.qcow2"
# Remove shortcut to prevent side effects
podman rmi $TARGET_IMAGE

37
bootc/build.sh

@ -0,0 +1,37 @@
#!/bin/sh
set -Eeuo pipefail
# Source variables and environment
source ./env.sh
# Login to registries, pull, etc.
./common.sh
# Build images
declare -A PODMAN_ARCH_OPTS=(["aarch64"]="--platform linux/arm64/v8" ["x86_64"]="--platform linux/amd64")
for arch in "${ARCHITECTURES[@]}"; do
echo "Building $NAME image for $arch..."
rm -rf etc
tar -xf etc-$arch.tar
mkdir -p cache-$arch/dnf cache-$arch/rpm-ostree
podman build ${PODMAN_ARCH_OPTS[$arch]} --no-cache --from "$RHEL_IMAGE-$arch:$RHEL_VERSION" \
-v $PWD/etc/pki/entitlement/:/etc/pki/entitlement:z -v $PWD/etc/rhsm:/etc/rhsm:z \
-v $PWD/etc/pki/entitlement/:/run/secrets/etc-pki-entitlement:z -v $PWD/etc/rhsm:/run/secrets/rhsm:z \
-v $PWD/etc/yum.repos.d:/etc/yum.repos.d:z -v $PWD/cache-$arch/dnf:/var/cache/dnf:z \
-v $PWD/cache-$arch/rpm-ostree:/var/cache/rpm-ostree:z \
--network $PODMAN_NETWORK -t localhost/$NAME-$arch .
podman save --format oci-archive -o $NAME-$arch.tar localhost/$NAME-$arch
done
# Push Manifest
echo "Pushing to $TARGET_IMAGE..."
read -p "Press enter to continue "
if podman manifest exists localhost/$NAME; then
podman manifest rm localhost/$NAME
fi
podman manifest create localhost/$NAME
for arch in "${ARCHITECTURES[@]}"; do
podman manifest add localhost/$NAME localhost/$NAME-$arch
done
podman manifest push localhost/$NAME $TARGET_IMAGE

37
bootc/common.sh

@ -0,0 +1,37 @@
#!/bin/sh
# Source variables and environment
source ./env.sh
# Pre-requisites
if ! podman network exists $PODMAN_NETWORK; then
podman network create $PODMAN_NETWORK --disable-dns
fi
# Login to registries
if [ ! -f "$REGISTRY_AUTH_FILE" ]; then
echo "Logging in registry.redhat.io"
podman login registry.redhat.io
echo "Logging in quay.io registry"
podman login quay.io
echo "Done"
read -p "Press enter to continue "
fi
# Pull
echo "Pulling images..."
if ! podman image exists $BOOTC_IMAGE:$RHEL_VERSION; then
podman pull $BOOTC_IMAGE:$RHEL_VERSION
fi
if ! podman image exists $RHEL_IMAGE-x86_64:$RHEL_VERSION; then
podman rmi -i $RHEL_IMAGE:$RHEL_VERSION
podman pull --platform linux/amd64 $RHEL_IMAGE:$RHEL_VERSION
podman tag $RHEL_IMAGE:$RHEL_VERSION $RHEL_IMAGE-x86_64:$RHEL_VERSION
podman rmi $RHEL_IMAGE:$RHEL_VERSION
fi
if ! podman image exists $RHEL_IMAGE-aarch64:$RHEL_VERSION; then
podman rmi -i $RHEL_IMAGE:$RHEL_VERSION
podman pull --platform linux/arm64/v8 $RHEL_IMAGE:$RHEL_VERSION
podman tag $RHEL_IMAGE:$RHEL_VERSION $RHEL_IMAGE-aarch64:$RHEL_VERSION
podman rmi $RHEL_IMAGE:$RHEL_VERSION
fi

12
bootc/config-iso.toml

@ -0,0 +1,12 @@
[customizations.installer.kickstart]
contents = """
lang fr_FR.UTF-8
keyboard fr
timezone UTC
rootpw --lock
zerombr
clearpart --all --initlabel
autopart --type=plain
reboot --eject
bootloader --append="console=tty0 console=ttyS0"
"""

0
bootc/config-qcow2.toml

17
bootc/env.sh

@ -0,0 +1,17 @@
###
### General
###
PODMAN_NETWORK="edge-ai"
RHEL_VERSION="9.4"
RHEL_IMAGE="registry.redhat.io/rhel9/rhel-bootc"
BOOTC_IMAGE="registry.redhat.io/rhel9/bootc-image-builder"
NAME="bootc-edge-ai"
TARGET_IMAGE="quay.io/nmasse-redhat/$NAME:latest"
# All architectures to build for
declare -a ARCHITECTURES=("x86_64" "aarch64")
###
### Environment Variables
###
export REGISTRY_AUTH_FILE="$PWD/auth.json"

1
bootc/post/etc/NetworkManager/system-connections/.gitignore

@ -0,0 +1 @@
*

23
bootc/post/etc/NetworkManager/system-connections/Sample-Wifi.nmconnection

@ -0,0 +1,23 @@
[connection]
id=Sample-Wifi
uuid=e6b2f736-4787-43f2-866d-996ad025d95a
type=wifi
interface-name=wlP1p1s0
[wifi]
mode=infrastructure
ssid=Sample-Wifi
[wifi-security]
auth-alg=open
key-mgmt=wpa-psk
psk=REDACTED
[ipv4]
method=auto
[ipv6]
addr-gen-mode=default
method=auto
[proxy]

1
bootc/pre/etc/NetworkManager/system-connections/.gitignore

@ -0,0 +1 @@
*

23
bootc/pre/etc/NetworkManager/system-connections/Sample-Wifi.nmconnection

@ -0,0 +1,23 @@
[connection]
id=Sample-Wifi
uuid=e6b2f736-4787-43f2-866d-996ad025d95a
type=wifi
interface-name=wlP1p1s0
[wifi]
mode=infrastructure
ssid=Sample-Wifi
[wifi-security]
auth-alg=open
key-mgmt=wpa-psk
psk=REDACTED
[ipv4]
method=auto
[ipv6]
addr-gen-mode=default
method=auto
[proxy]

23
bootc/root/etc/containers/systemd/intelligent-train.container

@ -0,0 +1,23 @@
[Unit]
Description=AI Auto-Pilot
After=local-fs.target
[Service]
ExecStartPre=-podman network create --ignore app
[Container]
ContainerName=intelligent-train
Image=quay.io/demo-ai-edge-crazy-train/intelligent-train:latest
Network=app
PublishPort=8080:8080
EnvironmentFile=/etc/intelligent-train.env
# Needed for Nvidia GPU Acceleration
PodmanArgs=--runtime /usr/bin/nvidia-container-runtime
GroupAdd=keep-groups
SecurityLabelDisable=true
Environment=NVIDIA_VISIBLE_DEVICES=nvidia.com/gpu=all
[Install]
# Start by default on boot
WantedBy=multi-user.target default.target

20
bootc/root/etc/containers/systemd/mosquitto.container

@ -0,0 +1,20 @@
[Unit]
Description=Mosquitto MQTT Broker
After=local-fs.target
[Service]
ExecStartPre=-podman network create --ignore app
[Container]
ContainerName=mosquitto
Image=docker.io/library/eclipse-mosquitto:latest
Network=app
PublishPort=1883:1883
PublishPort=9001:9001
Volume=/var/lib/mosquitto/data:/mosquitto/data:z
Volume=/var/lib/mosquitto/log:/mosquitto/log:z
Volume=/etc/mosquitto:/mosquitto/config:z
[Install]
# Start by default on boot
WantedBy=multi-user.target default.target

6
bootc/root/etc/intelligent-train.env

@ -0,0 +1,6 @@
MQTT_BROKER=mosquitto
MQTT_PORT=1883
MQTT_TOPIC=train-image
MQTT_PUB_TOPIC=train-model-result
MODEL_PATH=models/model.onnx
MIN_CONF_THRESHOLD=0.7

7
bootc/root/etc/mosquitto/mosquitto.conf

@ -0,0 +1,7 @@
user mosquitto
persistence true
persistence_location /mosquitto/data/
listener 1883 0.0.0.0
protocol mqtt
allow_anonymous true
log_dest file /mosquitto/log/mosquitto.log

1
bootc/root/etc/motd.d/hello-world

@ -0,0 +1 @@
Hello, World!

15
bootc/root/etc/systemd/system/nvidia-ctk-init.service

@ -0,0 +1,15 @@
[Unit]
Description=Run nvidia-ctk cdi generate
Wants=local-fs.target
After=local-fs.target
ConditionPathExists=!/etc/cdi/nvidia.yaml
ConditionPathExists=/usr/bin/nvidia-ctk
ConditionArchitecture=arm64
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=nvidia-ctk cdi generate --output=/etc/cdi/nvidia
[Install]
WantedBy=multi-user.target

12
bootc/root/etc/systemd/system/repo-intelligent-train.service

@ -0,0 +1,12 @@
[Unit]
Description=Sync the intelligent-train git repo
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/sh -c 'if [ -d /root/intelligent-train ]; then cd /root/intelligent-train && git pull ; else git clone -b main https://github.com/Demo-AI-Edge-Crazy-Train/intelligent-train.git /root/intelligent-train ; fi'
[Install]
WantedBy=multi-user.target

2
bootc/root/etc/vconsole.conf

@ -0,0 +1,2 @@
KEYMAP="fr-oss"
FONT="eurlatgr"

2
bootc/root/usr/lib/bootc/kargs.d/00-console.toml

@ -0,0 +1,2 @@
kargs = ["console=tty0", "console=ttyS0"]
match-architectures = ["x86_64"]

60
bootc/template-offline.ks

@ -0,0 +1,60 @@
##
## Environment setup
##
# Install mode: text (interactive installs) or cmdline (unattended installs)
text
# French keyboard layout
keyboard --vckeymap=fr --xlayouts='fr'
# English i18n
lang en_US.UTF-8 --addsupport fr_FR.UTF-8
# Accept the EULA
eula --agreed
# Which action to perform after install: poweroff or reboot
reboot
# Timezone is GMT
timezone Etc/GMT --utc
##
## network configuration
##
# THERE IS NOTHING HERE SINCE IT IS AN OFFLINE INSTALL
##
## partitioning
##
# Install on /dev/vda
#ignoredisk --only-use=vda
# Install Grub in the MBR of /dev/vda
#bootloader --location=mbr --boot-drive=vda
# Append kernel args to the boot command
bootloader --append="$KERNEL_CMDLINE"
# Clear the target disk
zerombr
# Remove existing partitions
clearpart --all --initlabel
# Automatically create partitions required by hardware platform
reqpart --add-boot
# Create a root and a /var partition
part / --fstype xfs --size=1 --grow --asprimary --label=root
#part /var --fstype xfs --size=1 --grow --asprimary --label=var
##
## Installation
##
rootpw --lock
ostreecontainer --url=/run/install/repo/container --transport=oci --no-signature-verification

64
bootc/template-online.ks

@ -0,0 +1,64 @@
##
## Environment setup
##
# Install mode: text (interactive installs) or cmdline (unattended installs)
text
# French keyboard layout
keyboard --vckeymap=fr --xlayouts='fr'
# English i18n
lang en_US.UTF-8 --addsupport fr_FR.UTF-8
# Accept the EULA
eula --agreed
# Which action to perform after install: poweroff or reboot
reboot
# Timezone is GMT
timezone Etc/GMT --utc
##
## network configuration
##
# Configure the first network device
network --bootproto=dhcp --device=enp1s0 --noipv6 --activate
# Set the hostname
#network --hostname=localhost.localdomain
##
## partitioning
##
# Install on /dev/vda
#ignoredisk --only-use=vda
# Install Grub in the MBR of /dev/vda
#bootloader --location=mbr --boot-drive=vda
# Append kernel args to the boot command
bootloader --append="$KERNEL_CMDLINE"
# Clear the target disk
zerombr
# Remove existing partitions
clearpart --all --initlabel
# Automatically create partitions required by hardware platform
reqpart --add-boot
# Create a root and a /var partition
part / --fstype xfs --size=1 --grow --asprimary --label=root
#part /var --fstype xfs --size=1 --grow --asprimary --label=var
##
## Installation
##
rootpw --lock
ostreecontainer --url="$TARGET_IMAGE" --transport=registry --no-signature-verification

70
bootc/test.sh

@ -0,0 +1,70 @@
#!/bin/sh
set -Eeuo pipefail
# Source variables and environment
source ./env.sh
# Constants
LOCAL_ARCH="$(arch)"
ARCH="${1:-$LOCAL_ARCH}"
TYPE="${2:-qcow2}"
DOMAIN_NAME="test-$NAME-$TYPE-$ARCH"
# Cleanup
if virsh list --name | grep -Eq "^$DOMAIN_NAME\$"; then
virsh destroy "$DOMAIN_NAME"
fi
if virsh list --all --name | grep -Eq "^$DOMAIN_NAME\$"; then
virsh undefine "$DOMAIN_NAME" --nvram
fi
rm -rf "/var/lib/libvirt/images/$DOMAIN_NAME"
mkdir -p "/var/lib/libvirt/images/$DOMAIN_NAME"
# Computing virt-install options
declare -a VIRT_INSTALL_OPTS=()
if [[ "$ARCH" != "$LOCAL_ARCH" ]]; then
VIRT_INSTALL_OPTS+=("--virt-type" "qemu" "--arch" "$ARCH")
else
VIRT_INSTALL_OPTS+=("--cpu" "host-passthrough")
fi
case "$TYPE" in
"qcow2")
cp "disk-$NAME-$ARCH.qcow2" "/var/lib/libvirt/images/$DOMAIN_NAME/disk.qcow2"
VIRT_INSTALL_OPTS+=("--disk" "path=/var/lib/libvirt/images/$DOMAIN_NAME/disk.qcow2,format=qcow2,bus=virtio,size=100"
"--import"
"--network" "network=default")
;;
"kickstart")
cp "install-$NAME-$ARCH.iso" "/var/lib/libvirt/images/$DOMAIN_NAME/install.iso"
VIRT_INSTALL_OPTS+=("--disk" "path=/var/lib/libvirt/images/$DOMAIN_NAME/disk.qcow2,format=qcow2,bus=virtio,size=100"
"--location" "/var/lib/libvirt/images/$DOMAIN_NAME/install.iso,kernel=images/pxeboot/vmlinuz,initrd=images/pxeboot/initrd.img"
"--extra-args" "console=ttyS0 inst.ks=cdrom:/osbuild.ks"
"--network" "network=default")
;;
"kickstart-online")
cp "install-$NAME-$ARCH-online.iso" "/var/lib/libvirt/images/$DOMAIN_NAME/install.iso"
VIRT_INSTALL_OPTS+=("--disk" "path=/var/lib/libvirt/images/$DOMAIN_NAME/disk.qcow2,format=qcow2,bus=virtio,size=100"
"--location" "/var/lib/libvirt/images/$DOMAIN_NAME/install.iso,kernel=images/pxeboot/vmlinuz,initrd=images/pxeboot/initrd.img"
"--extra-args" "console=ttyS0 inst.ks=cdrom:/osbuild.ks"
"--network" "network=default")
;;
"kickstart-offline")
cp "install-$NAME-$ARCH-offline.iso" "/var/lib/libvirt/images/$DOMAIN_NAME/install.iso"
VIRT_INSTALL_OPTS+=("--disk" "path=/var/lib/libvirt/images/$DOMAIN_NAME/disk.qcow2,format=qcow2,bus=virtio,size=100"
"--location" "/var/lib/libvirt/images/$DOMAIN_NAME/install.iso,kernel=images/pxeboot/vmlinuz,initrd=images/pxeboot/initrd.img"
"--extra-args" "console=ttyS0 inst.ks=cdrom:/osbuild.ks"
"--network" "none")
;;
*)
echo "Wrong artefact type $TYPE: expected either 'qcow2' or 'kickstart'."
exit 1
;;
esac
# Boot VM
set -x
virt-install --name "$DOMAIN_NAME" --memory 4096 --vcpus 2 \
--console pty,target_type=virtio --serial pty --graphics none \
--os-variant rhel9-unknown --boot uefi \
"${VIRT_INSTALL_OPTS[@]}"
Loading…
Cancel
Save