brusq-RH 2 months ago
parent
commit
10a8d7f934
  1. 4
      aap/playbooks/templates/cloud-init/network-config.j2
  2. 4
      ansible/templates/cloud-init/network-config.j2
  3. 22
      bootc/baremetal/Containerfile
  4. 57
      bootc/baremetal/root/etc/libvirt/hooks/qemu.d/30-iptables.sh
  5. 0
      bootc/baremetal/root/etc/libvirt/qemu/networks/autostart/default.xml
  6. 0
      bootc/baremetal/root/etc/libvirt/qemu/networks/default.xml
  7. 7
      bootc/baremetal/root/etc/systemd/system/bootstrap-vm@.service
  8. 7
      bootc/baremetal/root/etc/systemd/system/migrate-vm@.service
  9. 0
      bootc/baremetal/root/usr/local/bin/bootstrap-vm.sh
  10. 0
      bootc/baremetal/root/usr/local/bin/migrate-vm.sh
  11. 22
      bootc/base/Containerfile
  12. 4
      bootc/base/root/etc/flightctl/hooks.d/afterupdating/99_greenboot.yaml
  13. 8
      bootc/scenario1/Containerfile
  14. 10
      bootc/scenario1/root/etc/flightctl/hooks.d/afterupdating/30-nextcloud.yaml
  15. 8
      bootc/scenario2/Containerfile
  16. 8
      bootc/scenario3a/Containerfile
  17. 49
      bootc/scenario3a/root/etc/libvirt/hooks/qemu
  18. 2
      bootc/scenario3a/root/etc/libvirt/hooks/qemu.d/nextcloud/iptables
  19. 1
      bootc/scenario3a/root/etc/libvirt/qemu/networks/autostart/default.xml
  20. 19
      bootc/scenario3a/root/etc/libvirt/qemu/networks/default.xml
  21. 8
      bootc/scenario4/Containerfile
  22. 10
      bootc/scenario4/root/etc/flightctl/hooks.d/afterupdating/30-odoo.yaml
  23. 54
      bootc/scripts/build-image.sh
  24. 29
      bootc/scripts/build-qcow2.sh
  25. 8
      bootc/scripts/buildall.sh
  26. 20
      bootc/virtualmachine/Containerfile
  27. 0
      bootc/virtualmachine/root/etc/systemd/system/flightctl-agent.service.d/override.conf
  28. 5
      flightctl/apps/hyperv-migration/etc/flightctl/hooks.d/afterupdating/30-hyperv-migration.yaml
  29. 5
      flightctl/apps/hyperv-migration/etc/flightctl/hooks.d/beforeupdating/30-hyperv-migration.yaml
  30. 6
      flightctl/apps/hyperv-migration/etc/greenboot/check/required.d/30_printserver_check.sh
  31. 13
      flightctl/apps/nextcloud/etc/containers/systemd/nextcloud-app.container
  32. 11
      flightctl/apps/nextcloud/etc/containers/systemd/nextcloud-db.container
  33. 9
      flightctl/apps/nextcloud/etc/containers/systemd/nextcloud-nginx.container
  34. 9
      flightctl/apps/nextcloud/etc/containers/systemd/nextcloud-redis.container
  35. 0
      flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/nextcloud-app.env
  36. 0
      flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/nextcloud-config.env.tmpl
  37. 0
      flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/nextcloud-db.env
  38. 0
      flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/nextcloud-redis.env
  39. 2
      flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/nginx.conf
  40. 0
      flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/redis-session.ini
  41. 0
      flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/redis.conf
  42. 0
      flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/www.conf
  43. 5
      flightctl/apps/nextcloud/etc/flightctl/hooks.d/afterupdating/30-nextcloud.yaml
  44. 5
      flightctl/apps/nextcloud/etc/flightctl/hooks.d/beforeupdating/30-nextcloud.yaml
  45. 6
      flightctl/apps/nextcloud/etc/greenboot/check/required.d/30_nextcloud_check.sh
  46. 0
      flightctl/apps/nextcloud/etc/systemd/system/nextcloud.target
  47. 7
      flightctl/apps/odoo/etc/containers/systemd/odoo-app.container
  48. 13
      flightctl/apps/odoo/etc/containers/systemd/odoo-db.container
  49. 9
      flightctl/apps/odoo/etc/containers/systemd/odoo-init.container
  50. 0
      flightctl/apps/odoo/etc/containers/systemd/odoo/odoo-config.env.tmpl
  51. 1
      flightctl/apps/odoo/etc/containers/systemd/odoo/odoo-db.env
  52. 5
      flightctl/apps/odoo/etc/flightctl/hooks.d/afterupdating/30-odoo.yaml
  53. 5
      flightctl/apps/odoo/etc/flightctl/hooks.d/beforeupdating/30-odoo.yaml
  54. 6
      flightctl/apps/odoo/etc/greenboot/check/required.d/30_odoo_check.sh
  55. 0
      flightctl/apps/odoo/etc/odoo/init.sh
  56. 2
      flightctl/apps/odoo/etc/odoo/odoo.conf
  57. 0
      flightctl/apps/odoo/etc/systemd/system/odoo.target
  58. 5
      flightctl/apps/vm-nextcloud/etc/flightctl/hooks.d/afterupdating/30-edge-vm.yaml
  59. 5
      flightctl/apps/vm-nextcloud/etc/flightctl/hooks.d/beforeupdating/30-edge-vm.yaml
  60. 6
      flightctl/apps/vm-nextcloud/etc/greenboot/check/required.d/30_nextcloud_check.sh
  61. 138
      flightctl/fleets.yaml
  62. 0
      flightctl/fleets/baremetal/sites/default/etc/motd.d/unconfigured
  63. 4
      flightctl/fleets/baremetal/sites/paris-wagram/etc/containers/systemd/nextcloud/nextcloud-config.env
  64. 0
      flightctl/fleets/baremetal/sites/paris-wagram/etc/containers/systemd/odoo/odoo-config.env
  65. 4
      flightctl/fleets/baremetal/sites/paris-wagram/etc/default/bootstrap-vm-nextcloud.env
  66. 2
      flightctl/fleets/baremetal/sites/paris-wagram/etc/libvirt-hooks/nextcloud/iptables
  67. 0
      flightctl/fleets/baremetal/sites/villeneuve-d-ascq/etc/containers/systemd/odoo/odoo-config.env
  68. 8
      flightctl/fleets/baremetal/sites/villeneuve-d-ascq/etc/default/bootstrap-vm-nextcloud.env
  69. 0
      flightctl/fleets/baremetal/sites/villeneuve-d-ascq/etc/default/migrate-vm-printserver.env
  70. 2
      flightctl/fleets/baremetal/sites/villeneuve-d-ascq/etc/libvirt-hooks/nextcloud/iptables
  71. 0
      flightctl/fleets/vm-nextcloud/sites/default/etc/motd.d/unconfigured
  72. 16
      flightctl/fleets/vm-nextcloud/sites/paris-wagram/etc/containers/systemd/nextcloud/nextcloud-config.env
  73. 4
      flightctl/fleets/vm-nextcloud/sites/villeneuve-d-ascq/etc/containers/systemd/nextcloud/nextcloud-config.env
  74. 6
      flightctl/scenario4/sites/default/etc/motd.d/unconfigured
  75. 4
      flightctl/scenario4/sites/paris-wagram/etc/containers/systemd/configs/odoo-config.env
  76. 4
      flightctl/scenario4/sites/villeneuve-d-ascq/etc/containers/systemd/configs/odoo-config.env
  77. 24
      pxe-boot/install.sh
  78. 47
      pxe-boot/tftpboot/menu.ipxe
  79. 2
      pxe-boot/www/ks/mac-00190f440391.ks
  80. 2
      pxe-boot/www/ks/mac-00be43ec5619.ks

4
aap/playbooks/templates/cloud-init/network-config.j2

@ -1,9 +1,9 @@
version: 2
ethernets:
enp1s0:
demo0:
match:
macaddress: "{{ libvirt_domain_mac_address }}"
set-name: enp1s0
set-name: demo0
addresses:
- "{{ libvirt_domain_parameters.ipv4_address }}"
gateway4: "{{ libvirt_domain_parameters.ipv4_gateway }}"

4
ansible/templates/cloud-init/network-config.j2

@ -1,9 +1,9 @@
version: 2
ethernets:
enp1s0:
demo0:
match:
macaddress: "{{ libvirt_domain_mac_address }}"
set-name: enp1s0
set-name: demo0
addresses:
- "{{ libvirt_domain_parameters.ipv4_address }}"
gateway4: "{{ libvirt_domain_parameters.ipv4_gateway }}"

22
bootc/baremetal/Containerfile

@ -0,0 +1,22 @@
FROM edge-registry.itix.fr/demo-edge-retail/base:latest
RUN <<EOF
set -Eeuo pipefail
# Install virtualization packages
dnf install -y cockpit-machines libvirt libvirt-daemon-kvm virt-install virt-top \
libguestfs-tools genisoimage smartmontools hdparm rclone virt-v2v \
virt-v2v-bash-completion libguestfs-winsupport
dnf clean all
EOF
ADD --chown=root:root root /
RUN <<EOF
set -Eeuo pipefail
# Enable systemd services and sockets
systemctl enable libvirtd.service libvirt-guests.service
EOF

57
bootc/baremetal/root/etc/libvirt/hooks/qemu.d/30-iptables.sh

@ -0,0 +1,57 @@
#!/bin/bash
set -Eeuo pipefail
# The standard output is used to alter the domain's XML configuration.
# Suppress all output to avoid interfering with libvirt's operation.
exec > /dev/null
function log () {
echo "$@" >&2
}
# This script is called by libvirt when a VM is started or stopped.
# It is used to set up and tear down networking for the VM.
# The script takes two arguments: the VM name and the action (start or stop).
VM_NAME="$1"
ACTION="$2"
# Check if the networking configuration file exists for the VM
if [ ! -f "/etc/libvirt-hooks/${VM_NAME}/iptables" ]; then
log "No networking configuration found for VM '$VM_NAME'. Skipping."
exit 0
fi
if [ "$ACTION" = "started" ] || [ "$ACTION" = "reconnect" ] || [ "$ACTION" = "restore" ]; then
log "Setting up networking for VM '$VM_NAME'..."
# Set up iptables rules
while read -r rule; do
if [ -z "$rule" ]; then
continue
fi
iptables $rule
done < "/etc/libvirt-hooks/${VM_NAME}/iptables"
log "Networking setup complete for VM '$VM_NAME'."
elif [ "$ACTION" = "stopped" ] || [ "$ACTION" = "disconnect" ]; then
log "Tearing down networking for VM '$VM_NAME'..."
# Tear down iptables rules
while read -r rule; do
if [ -z "$rule" ]; then
continue
fi
# Replace '-A'/'-I' with '-D' to delete the rule
rule="${rule/-A/-D}"
rule="${rule/-I/-D}"
iptables $rule || log "Warning: Failed to delete iptables rule: iptables $rule"
done < "/etc/libvirt-hooks/${VM_NAME}/iptables"
log "Networking teardown complete for VM '$VM_NAME'."
else
log "Unknown action '$ACTION'. Supported actions are 'started', 'stopped', 'reconnect', and 'disconnect'."
log "Skipping."
fi
exit 0

0
bootc/scenario2/root/etc/libvirt/qemu/networks/autostart/default.xml → bootc/baremetal/root/etc/libvirt/qemu/networks/autostart/default.xml

0
bootc/scenario2/root/etc/libvirt/qemu/networks/default.xml → bootc/baremetal/root/etc/libvirt/qemu/networks/default.xml

7
bootc/scenario3a/root/etc/systemd/system/bootstrap-vm@.service → bootc/baremetal/root/etc/systemd/system/bootstrap-vm@.service

@ -7,13 +7,16 @@ Wants=network-online.target
# Only start if the VM root disk does not exist
ConditionPathExists=!/var/lib/libvirt/images/%i/root.qcow2
# Remain started to avoid race conditions
Persistent=true
# Only start if the VM definition file is present
ConditionPathExists=/etc/default/bootstrap-vm-%i.env
[Service]
Type=oneshot
ExecStart=/usr/local/bin/bootstrap-vm.sh %i
EnvironmentFile=/etc/default/bootstrap-vm-%i.env
# Remain started to avoid race conditions
RemainAfterExit=true
[Install]
WantedBy=multi-user.target

7
bootc/scenario2/root/etc/systemd/system/migrate-vm@.service → bootc/baremetal/root/etc/systemd/system/migrate-vm@.service

@ -7,13 +7,16 @@ Wants=network-online.target
# Only start if the VM root disk does not exist
ConditionPathExists=!/var/lib/libvirt/images/%i/root.qcow2
# Remain started to avoid race conditions
Persistent=true
# Only start if the VM definition file is present
ConditionPathExists=/etc/default/migrate-vm-%i.env
[Service]
Type=oneshot
ExecStart=/usr/local/bin/migrate-vm.sh %i
EnvironmentFile=/etc/default/migrate-vm-%i.env
# Remain started to avoid race conditions
RemainAfterExit=true
[Install]
WantedBy=multi-user.target

0
bootc/scenario3a/root/usr/local/bin/bootstrap-vm.sh → bootc/baremetal/root/usr/local/bin/bootstrap-vm.sh

0
bootc/scenario2/root/usr/local/bin/migrate-vm.sh → bootc/baremetal/root/usr/local/bin/migrate-vm.sh

22
bootc/base/Containerfile

@ -6,15 +6,17 @@ ARG ADMIN_USERNAME=demo \
RUN <<EOF
set -Eeuo pipefail
# Enable EPEL and Ansible AAP repos
dnf config-manager --enable ansible-automation-platform-2.5-for-rhel-9-$(arch)-rpms
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
dnf install -y mkpasswd podman skopeo flightctl-agent cockpit cockpit-machines cockpit-podman \
cockpit-files cockpit-ostree cockpit-pcp cockpit-system libvirt libvirt-daemon-kvm \
virt-install virt-top libguestfs-tools genisoimage greenboot greenboot-default-health-checks \
stress-ng yq podman-compose tmux smartmontools hdparm tcpdump rclone virt-v2v \
virt-v2v-bash-completion libguestfs-winsupport
# Install packages
dnf install -y mkpasswd podman skopeo flightctl-agent cockpit cockpit-podman cockpit-files \
cockpit-ostree cockpit-pcp cockpit-system greenboot greenboot-default-health-checks \
stress-ng yq podman-compose tmux tcpdump htop iptraf-ng
dnf clean all
# Create admin user if specified
if [ -n "$ADMIN_USERNAME" ]; then
useradd -m -G wheel -p "$(echo -n "$ADMIN_PASSWORD" | mkpasswd -m bcrypt --stdin)" "$ADMIN_USERNAME"
fi
@ -24,12 +26,18 @@ ADD --chown=root:root root /
RUN <<EOF
set -Eeuo pipefail
systemctl enable flightctl-agent.service cockpit.socket libvirtd.service libvirt-guests.service
# Enable systemd services and sockets
systemctl enable flightctl-agent.service cockpit.socket
# Make sure the flightctl-agent is the only one that can apply updates
systemctl mask bootc-fetch-apply-updates.timer
# Set proper ownership and SELinux context on SSH authorized keys
if [ -n "$ADMIN_USERNAME" -a -f "/etc/ssh/authorized_keys/$ADMIN_USERNAME.keys" ]; then
chown "$ADMIN_USERNAME:$ADMIN_USERNAME" "/etc/ssh/authorized_keys/$ADMIN_USERNAME.keys"
fi
semanage fcontext -a -t ssh_home_t "/etc/ssh/authorized_keys(/.*)?"
restorecon -Rf /etc/ssh/authorized_keys
install -d -m 0700 -o root -g root /var/lib/private/flightctl
EOF

4
bootc/base/root/etc/flightctl/hooks.d/afterupdating/99_greenboot.yaml

@ -0,0 +1,4 @@
- if:
- path: /etc/greenboot/check/
op: [created, updated, removed]
run: systemctl restart --no-block greenboot-healthcheck.service

8
bootc/scenario1/Containerfile

@ -1,8 +0,0 @@
FROM edge-registry.itix.fr/demo-edge-retail/base:latest
ADD --chown=root:root root /
RUN <<EOF
set -Eeuo pipefail
systemctl enable nextcloud.target
EOF

10
bootc/scenario1/root/etc/flightctl/hooks.d/afterupdating/30-nextcloud.yaml

@ -1,10 +0,0 @@
- if:
- path: /etc/containers/systemd/configs/nextcloud-config.env
op: [created, updated]
run: systemctl restart nextcloud.target
timeout: 5m
- if:
- path: /etc/containers/systemd/configs/nextcloud-config.env
op: [removed]
run: /bin/sh -c 'if [ -f /etc/systemd/system/nextcloud.target ]; then systemctl stop nextcloud.target; fi'
timeout: 5m

8
bootc/scenario2/Containerfile

@ -1,8 +0,0 @@
FROM edge-registry.itix.fr/demo-edge-retail/base:latest
ADD --chown=root:root root /
RUN <<EOF
set -Eeuo pipefail
systemctl enable migrate-vm@printserver.service
EOF

8
bootc/scenario3a/Containerfile

@ -1,8 +0,0 @@
FROM edge-registry.itix.fr/demo-edge-retail/base:latest
ADD --chown=root:root root /
RUN <<EOF
set -Eeuo pipefail
systemctl enable bootstrap-vm@nextcloud.service
EOF

49
bootc/scenario3a/root/etc/libvirt/hooks/qemu

@ -1,49 +0,0 @@
#!/bin/bash
set -Eeuo pipefail
# This script is called by libvirt when a VM is started or stopped.
# It is used to set up and tear down networking for the VM.
# The script takes two arguments: the VM name and the action (start or stop).
VM_NAME="$1"
ACTION="$2"
# Check if the networking configuration file exists for the VM
if [ ! -f "/etc/libvirt/hooks/qemu.d/${VM_NAME}/iptables" ]; then
echo "No networking configuration found for VM '$VM_NAME'. Skipping."
exit 0
fi
if [ "$ACTION" = "started" ] || [ "$ACTION" = "reconnect" ]; then
echo "Setting up networking for VM '$VM_NAME'..."
# Set up iptables rules
while read -r rule; do
if [ -z "$rule" ]; then
continue
fi
iptables $rule
done < "/etc/libvirt/hooks/qemu.d/${VM_NAME}/iptables"
echo "Networking setup complete for VM '$VM_NAME'."
elif [ "$ACTION" = "stopped" ] || [ "$ACTION" = "disconnect" ]; then
echo "Tearing down networking for VM '$VM_NAME'..."
# Tear down iptables rules
while read -r rule; do
if [ -z "$rule" ]; then
continue
fi
# Replace '-A'/'-I' with '-D' to delete the rule
rule="${rule/-A/-D}"
rule="${rule/-I/-D}"
iptables $rule || echo "Warning: Failed to delete iptables rule: iptables $rule"
done < "/etc/libvirt/hooks/qemu.d/${VM_NAME}/iptables"
echo "Networking teardown complete for VM '$VM_NAME'."
else
echo "Unknown action '$ACTION'. Supported actions are 'started', 'stopped', 'reconnect', and 'disconnect'."
echo "Skipping."
fi
exit 0

2
bootc/scenario3a/root/etc/libvirt/hooks/qemu.d/nextcloud/iptables

@ -1,2 +0,0 @@
-t nat -A PREROUTING -p tcp --dport 80 -d 192.168.2.75 -j DNAT --to-destination 192.168.122.2:80
-t filter -I LIBVIRT_FWI -d 192.168.122.2 -p tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT

1
bootc/scenario3a/root/etc/libvirt/qemu/networks/autostart/default.xml

@ -1 +0,0 @@
../default.xml

19
bootc/scenario3a/root/etc/libvirt/qemu/networks/default.xml

@ -1,19 +0,0 @@
<network>
<name>default</name>
<bridge name="virbr0" stp="on" delay="5" />
<forward mode='nat' />
<domain name="libvirt.test" />
<dns>
<host ip='192.168.122.1'>
<hostname>host</hostname>
</host>
</dns>
<ip address="192.168.122.1" netmask="255.255.255.0" localPtr="yes">
<dhcp>
<range start="192.168.122.100" end="192.168.122.200">
<lease expiry='24' unit='hours'/>
</range>
<host mac="04:00:00:00:00:01" name="nextcloud" ip="192.168.122.2" />
</dhcp>
</ip>
</network>

8
bootc/scenario4/Containerfile

@ -1,8 +0,0 @@
FROM edge-registry.itix.fr/demo-edge-retail/base:latest
ADD --chown=root:root root /
RUN <<EOF
set -Eeuo pipefail
systemctl enable odoo.target
EOF

10
bootc/scenario4/root/etc/flightctl/hooks.d/afterupdating/30-odoo.yaml

@ -1,10 +0,0 @@
- if:
- path: /etc/containers/systemd/configs/odoo-config.env
op: [created, updated]
run: systemctl restart odoo.target
timeout: 5m
- if:
- path: /etc/containers/systemd/configs/odoo-config.env
op: [removed]
run: /bin/sh -c 'if [ -f /etc/systemd/system/odoo.target ]; then systemctl stop odoo.target; fi'
timeout: 5m

54
bootc/scripts/build-image.sh

@ -0,0 +1,54 @@
#!/bin/bash
set -Eeuo pipefail
if [[ "$UID" -ne 0 ]]; then
echo "This command must be run as root!"
exit 1
fi
if [ "$#" -lt 1 ]; then
echo "Usage: $0 <bootc-target-image> [qcow2-target-image]"
exit 1
fi
TARGET_IMAGE="$1"
OCI_REGISTRY="${TARGET_IMAGE%%/*}"
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
if [ ! -f "$PROJECT_DIR/signing-key.pass" ]; then
openssl rand -base64 30 > "$PROJECT_DIR/signing-key.pass"
chmod 600 "$PROJECT_DIR/signing-key.pass"
fi
if [ ! -f "$PROJECT_DIR/signing-key.pub" ]; then
skopeo generate-sigstore-key --output-prefix "$PROJECT_DIR/signing-key" --passphrase-file "$PROJECT_DIR/signing-key.pass"
fi
if [ ! -f "/etc/containers/registries.d/${OCI_REGISTRY}.yaml" ]; then
tee "/etc/containers/registries.d/${OCI_REGISTRY}.yaml" > /dev/null <<EOF
docker:
${OCI_REGISTRY}:
use-sigstore-attachments: true
EOF
fi
export REGISTRY_AUTH_FILE="$PROJECT_DIR/auth.json"
if [ ! -f "$REGISTRY_AUTH_FILE" ]; then
echo "Please enter your credentials for ${OCI_REGISTRY}:"
podman login "${OCI_REGISTRY}"
echo "Please enter your credentials for registry.redhat.io:"
podman login registry.redhat.io
fi
if [ -x "$PWD/custom.sh" ]; then
echo "Running custom.sh..."
"$PWD/custom.sh"
fi
echo "Building and pushing image $TARGET_IMAGE..."
podman build --no-cache -t "${TARGET_IMAGE}" .
podman push --sign-by-sigstore-private-key "$PROJECT_DIR/signing-key.private" --sign-passphrase-file "$PROJECT_DIR/signing-key.pass" "${TARGET_IMAGE}"

29
bootc/scripts/build.sh → bootc/scripts/build-qcow2.sh

@ -35,41 +35,12 @@ OCI_REGISTRY="${TARGET_IMAGE%%/*}"
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
if [ ! -f "$PROJECT_DIR/signing-key.pass" ]; then
openssl rand -base64 30 > "$PROJECT_DIR/signing-key.pass"
chmod 600 "$PROJECT_DIR/signing-key.pass"
fi
if [ ! -f "$PROJECT_DIR/signing-key.pub" ]; then
skopeo generate-sigstore-key --output-prefix "$PROJECT_DIR/signing-key" --passphrase-file "$PROJECT_DIR/signing-key.pass"
fi
if [ ! -f "/etc/containers/registries.d/${OCI_REGISTRY}.yaml" ]; then
tee "/etc/containers/registries.d/${OCI_REGISTRY}.yaml" > /dev/null <<EOF
docker:
${OCI_REGISTRY}:
use-sigstore-attachments: true
EOF
fi
export REGISTRY_AUTH_FILE="$PROJECT_DIR/auth.json"
if [ ! -f "$REGISTRY_AUTH_FILE" ]; then
echo "Please enter your credentials for ${OCI_REGISTRY}:"
podman login "${OCI_REGISTRY}"
echo "Please enter your credentials for registry.redhat.io:"
podman login registry.redhat.io
fi
if [ -x "$PWD/custom.sh" ]; then
echo "Running custom.sh..."
"$PWD/custom.sh"
fi
echo "Building and pushing image $TARGET_IMAGE..."
podman build --no-cache -t "${TARGET_IMAGE}" .
podman push --sign-by-sigstore-private-key "$PROJECT_DIR/signing-key.private" --sign-passphrase-file "$PROJECT_DIR/signing-key.pass" "${TARGET_IMAGE}"
echo "Building and pushing image $QCOW2_TARGET_IMAGE..."
temp_dir="$(mktemp -d)"
trap 'rm -rf "$temp_dir"' EXIT

8
bootc/scripts/buildall.sh

@ -12,13 +12,17 @@ PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
. "$PROJECT_DIR/config.env"
for dir in "$PROJECT_DIR"/{base,scenario*}; do
for dir in "$PROJECT_DIR"/{base,baremetal,virtualmachine}; do
if [ -d "$dir" -a -f "$dir/Containerfile" ]; then
export SCENARIO="${dir##*/}"
TARGET_IMAGE="$(echo -n "$TARGET_IMAGE_TEMPLATE" | envsubst)"
echo "Building container image $TARGET_IMAGE from $SCENARIO..."
pushd "$dir" > /dev/null
"$SCRIPT_DIR/build.sh" "$TARGET_IMAGE"
"$SCRIPT_DIR/build-image.sh" "$TARGET_IMAGE"
if [[ "$SCENARIO" == "virtualmachine" ]]; then
echo "Building qcow2 image for $TARGET_IMAGE..."
"$SCRIPT_DIR/build-qcow2.sh" "$TARGET_IMAGE"
fi
popd > /dev/null
fi
done

20
bootc/virtualmachine/Containerfile

@ -0,0 +1,20 @@
FROM edge-registry.itix.fr/demo-edge-retail/base:latest
RUN <<EOF
set -Eeuo pipefail
# Install the Qemu guest agent
dnf install -y qemu-guest-agent
dnf clean all
EOF
ADD --chown=root:root root /
RUN <<EOF
set -Eeuo pipefail
# The flightctl-agent configuration will be injected here by the hypervisor
install -d -m 0700 -o root -g root /var/lib/private/flightctl
EOF

0
bootc/base/root/etc/systemd/system/flightctl-agent.service.d/override.conf → bootc/virtualmachine/root/etc/systemd/system/flightctl-agent.service.d/override.conf

5
flightctl/apps/hyperv-migration/etc/flightctl/hooks.d/afterupdating/30-hyperv-migration.yaml

@ -0,0 +1,5 @@
- if:
- path: /etc/default/migrate-vm-printserver.env
op: [created, updated]
run: /bin/sh -Eeuo pipefail -c 'systemctl enable migrate-vm@printserver.service ; systemctl restart migrate-vm@printserver.service'
timeout: 5m

5
flightctl/apps/hyperv-migration/etc/flightctl/hooks.d/beforeupdating/30-hyperv-migration.yaml

@ -0,0 +1,5 @@
- if:
- path: /etc/default/migrate-vm-printserver.env
op: [removed]
run: /bin/sh -c 'if [ -f /etc/systemd/system/migrate-vm@.service ]; then systemctl stop migrate-vm@printserver.service ; systemctl disable migrate-vm@printserver.service ; fi'
timeout: 5m

6
bootc/scenario2/root/etc/greenboot/check/required.d/30_printserver_check.sh → flightctl/apps/hyperv-migration/etc/greenboot/check/required.d/30_printserver_check.sh

@ -1,6 +1,12 @@
#!/bin/bash
set -Eeuo pipefail
if [ ! -f /etc/default/migrate-vm-printserver.env ]; then
echo "Virtual Machine 'printserver' not configured for this host!"
exit 0
fi
MAX_ATTEMPTS=60
for (( attempt=1; attempt<=MAX_ATTEMPTS; attempt++ )); do

13
bootc/scenario1/root/etc/containers/systemd/nextcloud-app.container → flightctl/apps/nextcloud/etc/containers/systemd/nextcloud-app.container

@ -8,7 +8,10 @@ Requires=nextcloud-db.service nextcloud-redis.service
After=nextcloud-db.service nextcloud-redis.service
# Only start if Nextcloud has been configured
ConditionPathExists=/etc/containers/systemd/configs/nextcloud-config.env
ConditionPathExists=/etc/containers/systemd/nextcloud/nextcloud-config.env
# Start/stop this unit when the target is started/stopped
PartOf=nextcloud.target
[Container]
ContainerName=nextcloud-app
@ -22,8 +25,8 @@ Network=host
AddCapability=CAP_NET_BIND_SERVICE
# Environment variables from secrets and config
EnvironmentFile=/etc/containers/systemd/configs/nextcloud-app.env
EnvironmentFile=/etc/containers/systemd/configs/nextcloud-config.env
EnvironmentFile=/etc/containers/systemd/nextcloud/nextcloud-app.env
EnvironmentFile=/etc/containers/systemd/nextcloud/nextcloud-config.env
# Volume mounts
Volume=/var/lib/nextcloud/data:/var/www/html:z
@ -45,8 +48,8 @@ TimeoutStopSec=30
# Skaffold filesystem + fix permissions
ExecStartPre=/bin/bash -Eeuo pipefail -c 'install -m 0700 -o 82 -g 82 -d /var/lib/nextcloud/data /var/lib/nextcloud/config ; \
install -m 0700 -o 82 -g 82 /etc/containers/systemd/configs/www.conf /var/lib/nextcloud/config/www.conf ; \
install -m 0700 -o 82 -g 82 /etc/containers/systemd/configs/redis-session.ini /var/lib/nextcloud/config/redis-session.ini'
install -m 0700 -o 82 -g 82 /etc/containers/systemd/nextcloud/www.conf /var/lib/nextcloud/config/www.conf ; \
install -m 0700 -o 82 -g 82 /etc/containers/systemd/nextcloud/redis-session.ini /var/lib/nextcloud/config/redis-session.ini'
# Wait for PostgreSQL to be ready
ExecStartPre=/bin/sh -c 'exec 2>/dev/null; for try in $(seq 0 12); do if ! /bin/true 5<> /dev/tcp/127.0.0.1/5432; then echo "Waiting for PostgreSQL to be available..."; sleep 5; else exit 0; fi; done; exit 1'

11
bootc/scenario1/root/etc/containers/systemd/nextcloud-db.container → flightctl/apps/nextcloud/etc/containers/systemd/nextcloud-db.container

@ -4,7 +4,10 @@ Documentation=https://www.postgresql.org/
After=network.target
# Only start if Nextcloud has been configured
ConditionPathExists=/etc/containers/systemd/configs/nextcloud-config.env
ConditionPathExists=/etc/containers/systemd/nextcloud/nextcloud-config.env
# Start/stop this unit when the target is started/stopped
PartOf=nextcloud.target
[Container]
ContainerName=nextcloud-db
@ -14,10 +17,10 @@ Image=docker.io/library/postgres:17-alpine
Network=host
# Environment variables from config
EnvironmentFile=/etc/containers/systemd/configs/nextcloud-db.env
EnvironmentFile=/etc/containers/systemd/nextcloud/nextcloud-db.env
# Volume mounts
Volume=/var/lib/postgresql/data:/var/lib/postgresql/data:Z
Volume=/var/lib/postgresql/data-nextcloud:/var/lib/postgresql/data:Z
# Health check
HealthCmd=pg_isready -U nextcloud -d nextcloud
@ -33,7 +36,7 @@ TimeoutStartSec=120
TimeoutStopSec=30
# Skaffold filesystem + fix permissions
ExecStartPre=install -m 0700 -o 70 -g 70 -d /var/lib/postgresql/data
ExecStartPre=install -m 0700 -o 70 -g 70 -d /var/lib/postgresql/data-nextcloud
[Install]
WantedBy=nextcloud.target

9
bootc/scenario1/root/etc/containers/systemd/nextcloud-nginx.container → flightctl/apps/nextcloud/etc/containers/systemd/nextcloud-nginx.container

@ -4,7 +4,10 @@ Documentation=https://nextcloud.com/
After=network.target
# Only start if Nextcloud has been configured
ConditionPathExists=/etc/containers/systemd/configs/nextcloud-config.env
ConditionPathExists=/etc/containers/systemd/nextcloud/nextcloud-config.env
# Start/stop this unit when the target is started/stopped
PartOf=nextcloud.target
[Container]
ContainerName=nextcloud-nginx
@ -19,10 +22,10 @@ User=82:82
# Volume mounts
Volume=/var/lib/nextcloud/data:/var/www/html:z
Volume=/etc/containers/systemd/configs/nginx.conf:/etc/nginx/nginx.conf:ro
Volume=/etc/containers/systemd/nextcloud/nginx.conf:/etc/nginx/nginx.conf:ro
# Health check (equivalent to readiness probe)
HealthCmd=curl -f http://localhost:80/status.php
HealthCmd=curl -f http://localhost:8080/status.php
HealthInterval=30s
HealthTimeout=10s
HealthStartPeriod=30s

9
bootc/scenario1/root/etc/containers/systemd/nextcloud-redis.container → flightctl/apps/nextcloud/etc/containers/systemd/nextcloud-redis.container

@ -4,7 +4,10 @@ Documentation=https://redis.io/
After=network.target
# Only start if Nextcloud has been configured
ConditionPathExists=/etc/containers/systemd/configs/nextcloud-config.env
ConditionPathExists=/etc/containers/systemd/nextcloud/nextcloud-config.env
# Start/stop this unit when the target is started/stopped
PartOf=nextcloud.target
[Container]
ContainerName=nextcloud-redis
@ -17,11 +20,11 @@ Network=host
Exec=redis-server /usr/local/etc/redis/redis.conf
# Environment variables
EnvironmentFile=/etc/containers/systemd/configs/nextcloud-redis.env
EnvironmentFile=/etc/containers/systemd/nextcloud/nextcloud-redis.env
# Volume mounts for data persistence
Volume=/var/lib/redis:/data:Z
Volume=/etc/containers/systemd/configs/redis.conf:/usr/local/etc/redis/redis.conf:ro
Volume=/etc/containers/systemd/nextcloud/redis.conf:/usr/local/etc/redis/redis.conf:ro
# Health check
HealthCmd=redis-cli ping | grep -q PONG

0
bootc/scenario1/root/etc/containers/systemd/configs/nextcloud-app.env → flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/nextcloud-app.env

0
bootc/scenario1/root/etc/containers/systemd/configs/nextcloud-config.env.tmpl → flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/nextcloud-config.env.tmpl

0
bootc/scenario1/root/etc/containers/systemd/configs/nextcloud-db.env → flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/nextcloud-db.env

0
bootc/scenario1/root/etc/containers/systemd/configs/nextcloud-redis.env → flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/nextcloud-redis.env

2
bootc/scenario1/root/etc/containers/systemd/configs/nginx.conf → flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/nginx.conf

@ -41,7 +41,7 @@ http {
}
server {
listen 80;
listen 8080;
# set max upload size
client_max_body_size 10G;

0
bootc/scenario1/root/etc/containers/systemd/configs/redis-session.ini → flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/redis-session.ini

0
bootc/scenario1/root/etc/containers/systemd/configs/redis.conf → flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/redis.conf

0
bootc/scenario1/root/etc/containers/systemd/configs/www.conf → flightctl/apps/nextcloud/etc/containers/systemd/nextcloud/www.conf

5
flightctl/apps/nextcloud/etc/flightctl/hooks.d/afterupdating/30-nextcloud.yaml

@ -0,0 +1,5 @@
- if:
- path: /etc/containers/systemd/nextcloud/nextcloud-config.env
op: [created, updated]
run: /bin/sh -Eeuo pipefail -c 'systemctl enable nextcloud.target ; systemctl restart nextcloud.target'
timeout: 5m

5
flightctl/apps/nextcloud/etc/flightctl/hooks.d/beforeupdating/30-nextcloud.yaml

@ -0,0 +1,5 @@
- if:
- path: /etc/containers/systemd/nextcloud/nextcloud-config.env
op: [removed]
run: /bin/sh -c 'if [ -f /etc/systemd/system/nextcloud.target ]; then systemctl stop nextcloud.target ; systemctl disable nextcloud.target ; fi'
timeout: 5m

6
bootc/scenario1/root/etc/greenboot/check/required.d/30_nextcloud_check.sh → flightctl/apps/nextcloud/etc/greenboot/check/required.d/30_nextcloud_check.sh

@ -1,6 +1,12 @@
#!/bin/bash
set -Eeuo pipefail
if [ ! -f /etc/containers/systemd/nextcloud/nextcloud-config.env ]; then
echo "Nextcloud not configured for this host!"
exit 0
fi
declare -a container_state=()
MAX_ATTEMPTS=60

0
bootc/scenario1/root/etc/systemd/system/nextcloud.target → flightctl/apps/nextcloud/etc/systemd/system/nextcloud.target

7
bootc/scenario4/root/etc/containers/systemd/odoo-app.container → flightctl/apps/odoo/etc/containers/systemd/odoo-app.container

@ -7,11 +7,14 @@ Requires=odoo-init.service odoo-db.service
After=odoo-init.service odoo-db.service
# Only start if Odoo has been configured
ConditionPathExists=/etc/containers/systemd/configs/odoo-config.env
ConditionPathExists=/etc/containers/systemd/odoo/odoo-config.env
# Only start if initialization has completed
ConditionPathExists=/var/lib/odoo/initialized
# Start/stop this unit when the target is started/stopped
PartOf=odoo.target
[Container]
ContainerName=odoo-app
Image=docker.io/library/odoo:17
@ -40,7 +43,7 @@ TimeoutStartSec=600
TimeoutStopSec=30
# Wait for PostgreSQL to be ready
ExecStartPre=/bin/sh -c 'exec 2>/dev/null; for try in $(seq 0 12); do if ! /bin/true 5<> /dev/tcp/127.0.0.1/5432; then echo "Waiting for PostgreSQL to be available..."; sleep 5; else exit 0; fi; done; exit 1'
ExecStartPre=/bin/sh -c 'exec 2>/dev/null; for try in $(seq 0 12); do if ! /bin/true 5<> /dev/tcp/127.0.0.1/5433; then echo "Waiting for PostgreSQL to be available..."; sleep 5; else exit 0; fi; done; exit 1'
[Install]
WantedBy=odoo.target

13
bootc/scenario4/root/etc/containers/systemd/odoo-db.container → flightctl/apps/odoo/etc/containers/systemd/odoo-db.container

@ -4,7 +4,10 @@ Documentation=https://www.postgresql.org/
After=network.target
# Only start if Odoo has been configured
ConditionPathExists=/etc/containers/systemd/configs/odoo-config.env
ConditionPathExists=/etc/containers/systemd/odoo/odoo-config.env
# Start/stop this unit when the target is started/stopped
PartOf=odoo.target
[Container]
ContainerName=odoo-db
@ -14,13 +17,13 @@ Image=docker.io/library/postgres:17-alpine
Network=host
# Environment variables from config
EnvironmentFile=/etc/containers/systemd/configs/odoo-db.env
EnvironmentFile=/etc/containers/systemd/odoo/odoo-db.env
# Volume mounts
Volume=/var/lib/postgresql/data:/var/lib/postgresql/data:Z
Volume=/var/lib/postgresql/data-odoo:/var/lib/postgresql/data:Z
# Health check
HealthCmd=pg_isready -U odoo -d postgres
HealthCmd=pg_isready -U odoo -d postgres -p 5433
HealthInterval=30s
HealthTimeout=10s
HealthStartPeriod=60s
@ -33,7 +36,7 @@ TimeoutStartSec=120
TimeoutStopSec=30
# Skaffold filesystem + fix permissions
ExecStartPre=install -m 0700 -o 70 -g 70 -d /var/lib/postgresql/data
ExecStartPre=install -m 0700 -o 70 -g 70 -d /var/lib/postgresql/data-odoo
[Install]
WantedBy=odoo.target

9
bootc/scenario4/root/etc/containers/systemd/odoo-init.container → flightctl/apps/odoo/etc/containers/systemd/odoo-init.container

@ -7,11 +7,14 @@ After=odoo-db.service
Before=odoo-app.service
# Only start if Odoo has been configured
ConditionPathExists=/etc/containers/systemd/configs/odoo-config.env
ConditionPathExists=/etc/containers/systemd/odoo/odoo-config.env
# Prevent running if already initialized
ConditionPathExists=!/var/lib/odoo/initialized
# Start/stop this unit when the target is started/stopped
PartOf=odoo.target
[Container]
ContainerName=odoo-init
Image=docker.io/library/odoo:17
@ -21,7 +24,7 @@ Network=host
AddCapability=CAP_NET_BIND_SERVICE
# Environment variables from secrets and config
EnvironmentFile=/etc/containers/systemd/configs/odoo-config.env
EnvironmentFile=/etc/containers/systemd/odoo/odoo-config.env
# Volume mounts
Volume=/etc/odoo:/etc/odoo:ro
@ -45,7 +48,7 @@ ExecStartPost=/bin/touch /var/lib/odoo/initialized
ExecStartPre=install -m 0700 -o 101 -g 101 -d /var/lib/odoo/data /var/lib/odoo/addons /var/log/odoo
# Wait for PostgreSQL to be ready
ExecStartPre=/bin/sh -c 'exec 2>/dev/null; for try in $(seq 0 12); do if ! /bin/true 5<> /dev/tcp/127.0.0.1/5432; then echo "Waiting for PostgreSQL to be available..."; sleep 5; else exit 0; fi; done; exit 1'
ExecStartPre=/bin/sh -c 'exec 2>/dev/null; for try in $(seq 0 12); do if ! /bin/true 5<> /dev/tcp/127.0.0.1/5433; then echo "Waiting for PostgreSQL to be available..."; sleep 5; else exit 0; fi; done; exit 1'
[Install]
WantedBy=odoo.target

0
bootc/scenario4/root/etc/containers/systemd/configs/odoo-config.env.tmpl → flightctl/apps/odoo/etc/containers/systemd/odoo/odoo-config.env.tmpl

1
bootc/scenario4/root/etc/containers/systemd/configs/odoo-db.env → flightctl/apps/odoo/etc/containers/systemd/odoo/odoo-db.env

@ -3,3 +3,4 @@ POSTGRES_PASSWORD=odoo
POSTGRES_DB=postgres
POSTGRES_HOST_AUTH_METHOD=scram-sha-256
POSTGRES_INITDB_ARGS=--auth-host=scram-sha-256
PGPORT=5433

5
flightctl/apps/odoo/etc/flightctl/hooks.d/afterupdating/30-odoo.yaml

@ -0,0 +1,5 @@
- if:
- path: /etc/containers/systemd/odoo/odoo-config.env
op: [created, updated]
run: /bin/sh -Eeuo pipefail -c 'systemctl enable odoo.target ; systemctl restart odoo.target'
timeout: 5m

5
flightctl/apps/odoo/etc/flightctl/hooks.d/beforeupdating/30-odoo.yaml

@ -0,0 +1,5 @@
- if:
- path: /etc/containers/systemd/odoo/odoo-config.env
op: [removed]
run: /bin/sh -c 'if [ -f /etc/systemd/system/odoo.target ]; then systemctl stop odoo.target ; systemctl disable odoo.target ; fi'
timeout: 5m

6
bootc/scenario4/root/etc/greenboot/check/required.d/30_odoo_check.sh → flightctl/apps/odoo/etc/greenboot/check/required.d/30_odoo_check.sh

@ -1,6 +1,12 @@
#!/bin/bash
set -Eeuo pipefail
if [ ! -f /etc/containers/systemd/odoo/odoo-config.env ]; then
echo "Odoo not configured for this host!"
exit 0
fi
declare -a container_state=()
MAX_ATTEMPTS=60

0
bootc/scenario4/root/etc/odoo/init.sh → flightctl/apps/odoo/etc/odoo/init.sh

2
bootc/scenario4/root/etc/odoo/odoo.conf → flightctl/apps/odoo/etc/odoo/odoo.conf

@ -3,7 +3,7 @@ addons_path = /mnt/extra-addons
data_dir = /var/lib/odoo
admin_passwd = $pbkdf2-sha512$600000$G6OU8j7HuBdCyBnDeE/pnQ$rtoycI6N7hJW37qeLLesYPWyfk8HsXD9HnsMtzkkU.pciBgd4bc0kV4Z2mI5cctjRIZf/RTOYAX5BvSjbwMxsA
db_host = localhost
db_port = 5432
db_port = 5433
db_user = odoo
db_password = odoo
logfile = /var/log/odoo/odoo.log

0
bootc/scenario4/root/etc/systemd/system/odoo.target → flightctl/apps/odoo/etc/systemd/system/odoo.target

5
flightctl/apps/vm-nextcloud/etc/flightctl/hooks.d/afterupdating/30-edge-vm.yaml

@ -0,0 +1,5 @@
- if:
- path: /etc/default/bootstrap-vm-nextcloud.env
op: [created, updated]
run: /bin/sh -Eeuo pipefail -c 'systemctl enable bootstrap-vm@nextcloud.service ; systemctl restart bootstrap-vm@nextcloud.service'
timeout: 5m

5
flightctl/apps/vm-nextcloud/etc/flightctl/hooks.d/beforeupdating/30-edge-vm.yaml

@ -0,0 +1,5 @@
- if:
- path: /etc/default/bootstrap-vm-nextcloud.env
op: [removed]
run: /bin/sh -c 'if [ -f /etc/systemd/system/bootstrap-vm@.service ]; then systemctl stop bootstrap-vm@nextcloud.service ; systemctl disable bootstrap-vm@nextcloud.service ; fi'
timeout: 5m

6
bootc/scenario3a/root/etc/greenboot/check/required.d/30_nextcloud_check.sh → flightctl/apps/vm-nextcloud/etc/greenboot/check/required.d/30_nextcloud_check.sh

@ -1,6 +1,12 @@
#!/bin/bash
set -Eeuo pipefail
if [ ! -f /etc/default/bootstrap-vm-nextcloud.env ]; then
echo "Virtual Machine 'nextcloud' not configured for this host!"
exit 0
fi
MAX_ATTEMPTS=60
for (( attempt=1; attempt<=MAX_ATTEMPTS; attempt++ )); do

138
flightctl/fleets.yaml

@ -3,116 +3,104 @@ kind: Fleet
metadata:
annotations: {}
labels:
scenario: 'base'
name: base
fleet: 'store-baremetal'
name: store-baremetal
spec:
selector:
matchLabels:
scenario: 'base'
template:
metadata:
labels:
fleet: base
spec:
applications: []
config: []
os:
image: edge-registry.itix.fr/demo-edge-retail/base:latest
systemd:
matchPatterns:
- greenboot-healthcheck.service
---
apiVersion: flightctl.io/v1alpha1
kind: Fleet
metadata:
annotations: {}
labels:
scenario: 'scenario1'
name: scenario1
spec:
selector:
matchLabels:
scenario: 'scenario1'
type: 'baremetal'
demo: 'retail'
template:
metadata:
labels:
fleet: scenario1
fleet: 'store-baremetal'
spec:
applications: []
os:
image: edge-registry.itix.fr/demo-edge-retail/scenario1:latest
image: edge-registry.itix.fr/demo-edge-retail/baremetal:latest
config:
- name: scenario1-config
- name: baremetal-site-config
configType: GitConfigProviderSpec
gitRef:
path: /flightctl/scenario1/sites/{{ getOrDefault .metadata.labels "site" "default" }}/
path: /flightctl/fleets/baremetal/sites/{{ getOrDefault .metadata.labels "site" "default" }}/
repository: demo-edge-retail
targetRevision: main
- name: nextcloud-container
configType: GitConfigProviderSpec
gitRef:
path: /flightctl/apps/nextcloud/
repository: demo-edge-retail
targetRevision: main
- name: odoo-container
configType: GitConfigProviderSpec
gitRef:
path: /flightctl/apps/odoo/
repository: demo-edge-retail
targetRevision: main
- name: vm-nextcloud
configType: GitConfigProviderSpec
gitRef:
path: /flightctl/apps/vm-nextcloud/
repository: demo-edge-retail
targetRevision: main
- name: hyperv-migration
configType: GitConfigProviderSpec
gitRef:
path: /flightctl/apps/hyperv-migration/
repository: demo-edge-retail
targetRevision: main
systemd:
matchPatterns:
- nextcloud-app.service
- nextcloud-db.service
- nextcloud-nginx.service
- nextcloud-redis.service
- greenboot-healthcheck.service
---
apiVersion: flightctl.io/v1alpha1
kind: Fleet
metadata:
annotations: {}
labels:
scenario: 'scenario3a'
name: scenario3a
spec:
selector:
matchLabels:
scenario: 'scenario3a'
type: 'baremetal'
template:
metadata:
labels:
fleet: scenario3a
spec:
applications: []
config: []
os:
image: edge-registry.itix.fr/demo-edge-retail/scenario3a:latest
systemd:
matchPatterns:
- bootstrap-vm@nextcloud.service
- libvirtd.service
- nftables.service
- greenboot-healthcheck.service
- libvirtd.service
- greenboot-healthcheck.service
- nextcloud-app.service
- nextcloud-db.service
- nextcloud-nginx.service
- nextcloud-redis.service
- odoo-app.service
- odoo-db.service
- odoo-init.service
- bootstrap-vm@nextcloud.service
- migrate-vm@printserver.service
---
apiVersion: flightctl.io/v1alpha1
kind: Fleet
metadata:
annotations: {}
labels:
scenario: 'scenario4'
name: scenario4
fleet: 'store-vm-nextcloud'
name: store-vm-nextcloud
spec:
selector:
matchLabels:
scenario: 'scenario4'
type: 'virtualmachine'
vm.name: 'nextcloud'
demo: 'retail'
template:
metadata:
labels:
fleet: scenario4
fleet: 'store-vm-nextcloud'
spec:
applications: []
os:
image: edge-registry.itix.fr/demo-edge-retail/scenario4:latest
image: edge-registry.itix.fr/demo-edge-retail/virtualmachine:latest
config:
- name: scenario4-config
- name: vm-nextcloud-site-config
configType: GitConfigProviderSpec
gitRef:
path: /flightctl/fleets/vm-nextcloud/sites/{{ getOrDefault .metadata.labels "site" "default" }}/
repository: demo-edge-retail
targetRevision: main
- name: nextcloud-container
configType: GitConfigProviderSpec
gitRef:
path: /flightctl/scenario4/sites/{{ getOrDefault .metadata.labels "site" "default" }}/
path: /flightctl/apps/nextcloud/
repository: demo-edge-retail
targetRevision: main
systemd:
matchPatterns:
- odoo-app.service
- odoo-db.service
- odoo-init.service
- greenboot-healthcheck.service
- greenboot-healthcheck.service
- nextcloud-app.service
- nextcloud-db.service
- nextcloud-nginx.service
- nextcloud-redis.service

0
flightctl/scenario1/sites/default/etc/motd.d/unconfigured → flightctl/fleets/baremetal/sites/default/etc/motd.d/unconfigured

4
flightctl/scenario1/sites/paris-wagram/etc/containers/systemd/configs/nextcloud-config.env → flightctl/fleets/baremetal/sites/paris-wagram/etc/containers/systemd/nextcloud/nextcloud-config.env

@ -4,9 +4,9 @@
# Nextcloud domain configuration
NEXTCLOUD_TRUSTED_DOMAINS=optiplex-7000.itix.fr
OVERWRITEHOST=optiplex-7000.itix.fr
OVERWRITEHOST=optiplex-7000.itix.fr:8080
OVERWRITEPROTOCOL=http
OVERWRITECLIURL=http://optiplex-7000.itix.fr
OVERWRITECLIURL=http://optiplex-7000.itix.fr:8080
# Nextcloud admin credentials
NEXTCLOUD_ADMIN_USER=admin

0
flightctl/scenario3a/sites/paris-wagram/etc/containers/systemd/configs/odoo-config.env → flightctl/fleets/baremetal/sites/paris-wagram/etc/containers/systemd/odoo/odoo-config.env

4
bootc/scenario3a/root/etc/default/bootstrap-vm-nextcloud.env → flightctl/fleets/baremetal/sites/paris-wagram/etc/default/bootstrap-vm-nextcloud.env

@ -3,6 +3,6 @@ DOMAIN_RAM=8192
DOMAIN_DISK_SIZE=100
DOMAIN_OS_VARIANT=rhel9.6
DOMAIN_MAC_ADDRESS=04:00:00:00:00:01
FLIGHTCTL_LABELS_OVERRIDE={ "type": "virtualmachine", "vm.name": "nextcloud", "scenario": "scenario1" }
DOMAIN_DISK_SOURCE=edge-registry.itix.fr/demo-edge-retail/scenario1-qcow2:latest
FLIGHTCTL_LABELS_OVERRIDE={ "type": "virtualmachine", "vm.name": "nextcloud" }
DOMAIN_DISK_SOURCE=edge-registry.itix.fr/demo-edge-retail/virtualmachine-qcow2:latest
REGISTRY_AUTH_FILE=/etc/ostree/auth.json

2
flightctl/fleets/baremetal/sites/paris-wagram/etc/libvirt-hooks/nextcloud/iptables

@ -0,0 +1,2 @@
-t nat -A PREROUTING -p tcp --dport 8080 -d 192.168.2.73 -j DNAT --to-destination 192.168.122.2:8080
-t filter -I LIBVIRT_FWI -d 192.168.122.2 -p tcp --dport 8080 -m conntrack --ctstate NEW -j ACCEPT

0
flightctl/scenario3a/sites/villeneuve-d-ascq/etc/containers/systemd/configs/odoo-config.env → flightctl/fleets/baremetal/sites/villeneuve-d-ascq/etc/containers/systemd/odoo/odoo-config.env

8
flightctl/fleets/baremetal/sites/villeneuve-d-ascq/etc/default/bootstrap-vm-nextcloud.env

@ -0,0 +1,8 @@
DOMAIN_VCPUS=4
DOMAIN_RAM=8192
DOMAIN_DISK_SIZE=100
DOMAIN_OS_VARIANT=rhel9.6
DOMAIN_MAC_ADDRESS=04:00:00:00:00:01
FLIGHTCTL_LABELS_OVERRIDE={ "type": "virtualmachine", "vm.name": "nextcloud" }
DOMAIN_DISK_SOURCE=edge-registry.itix.fr/demo-edge-retail/virtualmachine-qcow2:latest
REGISTRY_AUTH_FILE=/etc/ostree/auth.json

0
bootc/scenario2/root/etc/default/migrate-vm-printserver.env → flightctl/fleets/baremetal/sites/villeneuve-d-ascq/etc/default/migrate-vm-printserver.env

2
flightctl/fleets/baremetal/sites/villeneuve-d-ascq/etc/libvirt-hooks/nextcloud/iptables

@ -0,0 +1,2 @@
-t nat -A PREROUTING -p tcp --dport 8080 -d 192.168.2.75 -j DNAT --to-destination 192.168.122.2:8080
-t filter -I LIBVIRT_FWI -d 192.168.122.2 -p tcp --dport 8080 -m conntrack --ctstate NEW -j ACCEPT

0
flightctl/scenario3a/sites/default/etc/motd.d/unconfigured → flightctl/fleets/vm-nextcloud/sites/default/etc/motd.d/unconfigured

16
flightctl/fleets/vm-nextcloud/sites/paris-wagram/etc/containers/systemd/nextcloud/nextcloud-config.env

@ -0,0 +1,16 @@
##
## Nextcloud Configuration Environment Variables
##
# Nextcloud domain configuration
NEXTCLOUD_TRUSTED_DOMAINS=optiplex-7000.itix.fr
OVERWRITEHOST=optiplex-7000.itix.fr:8080
OVERWRITEPROTOCOL=http
OVERWRITECLIURL=http://optiplex-7000.itix.fr:8080
# Nextcloud admin credentials
NEXTCLOUD_ADMIN_USER=admin
NEXTCLOUD_ADMIN_PASSWORD=nextcloud
# Nextcloud server info token
NEXTCLOUD_SERVERINFO_TOKEN=S3cr3t!

4
flightctl/scenario1/sites/villeneuve-d-ascq/etc/containers/systemd/configs/nextcloud-config.env → flightctl/fleets/vm-nextcloud/sites/villeneuve-d-ascq/etc/containers/systemd/nextcloud/nextcloud-config.env

@ -4,9 +4,9 @@
# Nextcloud domain configuration
NEXTCLOUD_TRUSTED_DOMAINS=adlink-dlap-4001.itix.fr
OVERWRITEHOST=adlink-dlap-4001.itix.fr
OVERWRITEHOST=adlink-dlap-4001.itix.fr:8080
OVERWRITEPROTOCOL=http
OVERWRITECLIURL=http://adlink-dlap-4001.itix.fr
OVERWRITECLIURL=http://adlink-dlap-4001.itix.fr:8080
# Nextcloud admin credentials
NEXTCLOUD_ADMIN_USER=admin

6
flightctl/scenario4/sites/default/etc/motd.d/unconfigured

@ -1,6 +0,0 @@
HEADS UP !!!
This system is not configured !

4
flightctl/scenario4/sites/paris-wagram/etc/containers/systemd/configs/odoo-config.env

@ -1,4 +0,0 @@
DATABASE=redhat
ADMIN_PASSWORD=R3dH4t!
RIBBON_COLOR=rgba(255,0,0,.6)
RIBBON_NAME=Paris Wagram<br/>({db_name})

4
flightctl/scenario4/sites/villeneuve-d-ascq/etc/containers/systemd/configs/odoo-config.env

@ -1,4 +0,0 @@
DATABASE=redhat
ADMIN_PASSWORD=R3dH4t!
RIBBON_COLOR=rgba(0,0,255,.6)
RIBBON_NAME=Villeneuve d'Ascq<br/>({db_name})

24
pxe-boot/install.sh

@ -42,47 +42,41 @@ function install_directories() {
done
}
# This function templates a kickstart file by replacing placeholders with actual values.
# The templates are located in the www/ks directory.
# The output files are written to /var/www/ks.
# The placeholders are in the format expected by envsubst.
# For each template file, eight versions are created: base + scenario{1,2,3a,3b,4,5,6}.
# The output files are named as /var/www/ks/<template>/<scenario>.ks.
# The output files are named as /var/www/ks/<template>/baremetal.ks.
function template_kickstart_files() {
local templates_dir="${SCRIPT_DIR}/www/ks"
local output_dir="/var/www/ks"
local scenarios=("base" "scenario1" "scenario2" "scenario3a" "scenario3b" "scenario4" "scenario5" "scenario6")
for template in "$templates_dir"/*.ks; do
local template_name="$(basename "$template" .ks)"
for scenario in "${scenarios[@]}"; do
install -d -m 0755 -o root -g root -Z "$output_dir/${template_name}"
template_kickstart_file "$template" "$scenario"
done
install -d -m 0755 -o root -g root -Z "$output_dir/${template_name}"
template_kickstart_file "$template" "edge-registry.itix.fr/demo-edge-retail/baremetal:latest"
done
}
# This function templates a single kickstart file.
# It takes two arguments: the path to the template file and the current scenario.
# It takes two arguments: the path to the template file and the bootc image.
# It uses envsubst to replace placeholders with actual values.
function template_kickstart_file () {
local template="$1"
local scenario="$2"
local bootc_image="$2"
local template_name="$(basename "$template" .ks)"
local output_file="$output_dir/${template_name}/${scenario}.ks"
local output_file="$output_dir/${template_name}/baremetal.ks"
echo "Templating $template_name to $output_file"
(
export SCENARIO_NAME="$scenario"
export BOOTC_IMAGE="$bootc_image"
if [ -f "auth.json" ]; then
export AUTH_JSON_CONTENT="$(cat auth.json)"
fi
if [ -f "config.yaml" ]; then
declare -n device_labels=${mac_labels[$template_name]}
local labels_json="{ \"scenario\": \"$scenario\""
local labels_json="{ \"demo\": \"retail\""
for label in "${!device_labels[@]}"; do
labels_json+=", \"$label\": \"${device_labels[$label]}\""
done
@ -90,7 +84,7 @@ function template_kickstart_file () {
export FLIGHTCTL_CONFIG_CONTENT="$(yq e ".default-labels += $labels_json" config.yaml)"
fi
envsubst < "$template" > "/tmp/tmp.$$.ks"
declare +x AUTH_JSON_CONTENT FLIGHTCTL_CONFIG_CONTENT SCENARIO_NAME
declare +x AUTH_JSON_CONTENT FLIGHTCTL_CONFIG_CONTENT BOOTC_IMAGE
)
install -m 0644 -o root -g root "/tmp/tmp.$$.ks" "$output_file"
}

47
pxe-boot/tftpboot/menu.ipxe

@ -4,14 +4,7 @@ isset ${menu_default} || set menu_default rhde
isset ${menu_timeout} || set menu_timeout 30000
menu iPXE Menu
item --key 0 rhde [0] Install Red Hat Device Edge - Base
item --key 1 rhde-scenario1 [1] Install Red Hat Device Edge - Scenario 1
item --key 2 rhde-scenario2 [2] Install Red Hat Device Edge - Scenario 2
item --key 3 rhde-scenario3a [3] Install Red Hat Device Edge - Scenario 3a
item --key 4 rhde-scenario4 [4] Install Red Hat Device Edge - Scenario 4
item --key 5 rhde-scenario5 [5] Install Red Hat Device Edge - Scenario 5
item --key 6 rhde-scenario6 [6] Install Red Hat Device Edge - Scenario 6
item --key 7 rhde-scenario3b [7] Install Red Hat Device Edge - Scenario 3b
item --key 0 rhde-baremetal [0] Install Red Hat Device Edge - Baremetal
item
item --key r reboot [R] Reboot computer
item --key x exit [X] Exit iPXE and continue BIOS boot
@ -24,42 +17,8 @@ reboot
:exit
exit
:rhde
:rhde-baremetal
initrd ${rhel9_url}/images/pxeboot/initrd.img
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/base.ks ${rhde_options}
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/baremetal.ks ${rhde_options}
boot
:rhde-scenario1
initrd ${rhel9_url}/images/pxeboot/initrd.img
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/scenario1.ks ${rhde_options}
boot
:rhde-scenario2
initrd ${rhel9_url}/images/pxeboot/initrd.img
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/scenario2.ks ${rhde_options}
boot
:rhde-scenario3a
initrd ${rhel9_url}/images/pxeboot/initrd.img
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/scenario3a.ks ${rhde_options}
boot
:rhde-scenario3b
initrd ${rhel9_url}/images/pxeboot/initrd.img
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/scenario3b.ks ${rhde_options}
boot
:rhde-scenario4
initrd ${rhel9_url}/images/pxeboot/initrd.img
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/scenario4.ks ${rhde_options}
boot
:rhde-scenario5
initrd ${rhel9_url}/images/pxeboot/initrd.img
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/scenario5.ks ${rhde_options}
boot
:rhde-scenario6
initrd ${rhel9_url}/images/pxeboot/initrd.img
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/scenario6.ks ${rhde_options}
boot

2
pxe-boot/www/ks/mac-00190f440391.ks

@ -61,7 +61,7 @@ chmod 0600 /etc/ostree/auth.json
##
rootpw --lock
ostreecontainer --url="edge-registry.itix.fr/demo-edge-retail/${SCENARIO_NAME}:latest" --transport=registry --no-signature-verification
ostreecontainer --url="${BOOTC_IMAGE}" --transport=registry --no-signature-verification
##
## Post-installation

2
pxe-boot/www/ks/mac-00be43ec5619.ks

@ -61,7 +61,7 @@ chmod 0600 /etc/ostree/auth.json
##
rootpw --lock
ostreecontainer --url="edge-registry.itix.fr/demo-edge-retail/${SCENARIO_NAME}:latest" --transport=registry --no-signature-verification
ostreecontainer --url="${BOOTC_IMAGE}" --transport=registry --no-signature-verification
##
## Post-installation

Loading…
Cancel
Save