commit
6be518a3ab
25 changed files with 676 additions and 0 deletions
@ -0,0 +1,8 @@ |
|||||
|
/etc |
||||
|
*.pem |
||||
|
auth.json |
||||
|
cache-*/ |
||||
|
*.iso |
||||
|
*.qcow2 |
||||
|
*.tar |
||||
|
osbuild.ks |
||||
@ -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 |
||||
@ -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 |
||||
@ -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 |
||||
@ -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 |
||||
@ -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 |
||||
@ -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,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" |
||||
@ -0,0 +1 @@ |
|||||
|
* |
||||
@ -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] |
||||
@ -0,0 +1 @@ |
|||||
|
* |
||||
@ -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] |
||||
@ -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 |
||||
@ -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 |
||||
@ -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 |
||||
@ -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 |
||||
@ -0,0 +1 @@ |
|||||
|
Hello, World! |
||||
@ -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 |
||||
@ -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 |
||||
@ -0,0 +1,2 @@ |
|||||
|
KEYMAP="fr-oss" |
||||
|
FONT="eurlatgr" |
||||
@ -0,0 +1,2 @@ |
|||||
|
kargs = ["console=tty0", "console=ttyS0"] |
||||
|
match-architectures = ["x86_64"] |
||||
@ -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 |
||||
@ -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 |
||||
@ -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…
Reference in new issue