From 41c7c0a8ff2ebc4659a69835179729e777d49306 Mon Sep 17 00:00:00 2001 From: Nicolas MASSE Date: Thu, 18 Dec 2025 13:24:36 +0100 Subject: [PATCH] work in progress --- Makefile | 11 ++---- Makefile.common | 54 ++++++++++---------------- nextcloud/Makefile | 1 + nextcloud/nextcloud-app.container | 1 + nginx/nginx-update.container | 2 +- nginx/nginx-update.timer | 11 ++++++ postgresql/Makefile | 6 ++- postgresql/postgresql-backup.container | 1 + postgresql/tmpfiles.d/postgresql.conf | 2 + virtiofs/Makefile | 3 ++ virtiofs/backup-virtiofs.service | 22 +++++++++++ virtiofs/restore-virtiofs.service | 16 ++++++++ virtiofs/tmpfiles.d/virtiofs.conf | 2 + virtiofs/var-lib-virtiofs-data.mount | 19 +++++++++ 14 files changed, 108 insertions(+), 43 deletions(-) create mode 100644 nginx/nginx-update.timer create mode 100644 virtiofs/Makefile create mode 100644 virtiofs/backup-virtiofs.service create mode 100644 virtiofs/restore-virtiofs.service create mode 100644 virtiofs/tmpfiles.d/virtiofs.conf create mode 100644 virtiofs/var-lib-virtiofs-data.mount diff --git a/Makefile b/Makefile index b97ec36..f3615d8 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ SUBDIRS := $(wildcard */Makefile) SUBDIRS := $(dir $(SUBDIRS)) -.PHONY: all help butane clean dryrun fcos-vm $(SUBDIRS) +.PHONY: all help butane clean dryrun fcos-vm clean-vm uninstall $(SUBDIRS) all: help help: @@ -11,17 +11,14 @@ help: @echo " dryrun - Perform a dry run of the podman systemd generator" @echo " fcos-vm - Launch a Fedora CoreOS VM with the generated Butane spec" @echo " clean-vm - Clean up the Fedora CoreOS VM and its resources" + @echo " uninstall - Uninstall the generated resources" dryrun: $(SUBDIRS) butane: $(SUBDIRS) clean: $(SUBDIRS) fcos-vm: $(SUBDIRS) clean-vm: $(SUBDIRS) +uninstall: $(SUBDIRS) $(SUBDIRS): - @run() { echo $$*; "$$@"; }; \ - if echo $(MAKECMDGOALS) | grep -Eq 'butane|fcos-vm'; then \ - run $(MAKE) -C $@ $(MAKECMDGOALS); \ - else \ - run $(MAKE) -C $@ $(MAKECMDGOALS); \ - fi + $(MAKE) -C $@ $(MAKECMDGOALS) diff --git a/Makefile.common b/Makefile.common index f441ade..54b73e6 100644 --- a/Makefile.common +++ b/Makefile.common @@ -19,8 +19,8 @@ help: TARGET_CHROOT ?= PROJECT_NAME := $(shell basename "$${PWD}") QUADLETS_FILES = $(wildcard *.container *.volume *.network *.pod *.build) -SYSTEMD_FILES = $(wildcard *.service *.target *.timer) -SYSTEMD_UNIT_NAMES := $(wildcard *.service *.target *.timer) +SYSTEMD_FILES = $(wildcard *.service *.target *.timer *.mount) +SYSTEMD_UNIT_NAMES := $(wildcard *.service *.target *.timer *.mount) SYSTEMD_TIMER_NAMES := $(wildcard *.timer) SYSTEMD_MAIN_UNIT_NAMES := $(wildcard *.target) QUADLET_UNIT_NAMES := $(patsubst %.container, %.service, $(wildcard *.container)) \ @@ -69,30 +69,12 @@ $(TARGET_CHROOT)/etc/tmpfiles.d: $(TARGET_CHROOT)/etc/sysctl.d: install -D -d -m 0755 -o root -g root $@ -$(TARGET_CHROOT)/etc/containers/systemd/%.container: %.container $(TARGET_CHROOT)/etc/containers/systemd +$(TARGET_CHROOT)/etc/containers/systemd/%: % $(TARGET_CHROOT)/etc/containers/systemd install -m 0644 -o root -g root $< $@ -$(TARGET_CHROOT)/etc/containers/systemd/%.volume: %.volume $(TARGET_CHROOT)/etc/containers/systemd +$(TARGET_CHROOT)/etc/systemd/system/%: % $(TARGET_CHROOT)/etc/systemd/system install -m 0644 -o root -g root $< $@ -$(TARGET_CHROOT)/etc/containers/systemd/%.network: %.network $(TARGET_CHROOT)/etc/containers/systemd - install -m 0644 -o root -g root $< $@ - -$(TARGET_CHROOT)/etc/containers/systemd/%.pod: %.pod $(TARGET_CHROOT)/etc/containers/systemd - install -m 0644 -o root -g root $< $@ - -$(TARGET_CHROOT)/etc/containers/systemd/%.build: %.build $(TARGET_CHROOT)/etc/containers/systemd - install -m 0644 -o root -g root $< $@ - -$(TARGET_CHROOT)/etc/systemd/system/%.service: %.service $(TARGET_CHROOT)/etc/systemd/system - install -D -m 0644 -o root -g root $< $@ - -$(TARGET_CHROOT)/etc/systemd/system/%.target: %.target $(TARGET_CHROOT)/etc/systemd/system - install -D -m 0644 -o root -g root $< $@ - -$(TARGET_CHROOT)/etc/systemd/system/%.timer: %.timer $(TARGET_CHROOT)/etc/systemd/system - install -D -m 0644 -o root -g root $< $@ - $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME)/%: config/% $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME) @run() { echo $$*; "$$@"; }; \ if [ -x $< ]; then \ @@ -202,27 +184,33 @@ fcos.ign: fcos.bu $(TOP_LEVEL_DIR)/local.ign $(PROJECT_NAME).ign $(DEPENDENCIES_ qcow2=$$(ls -1ctr /var/lib/libvirt/images/library/fedora-coreos-*.qcow2 | tail -n 1) ; \ run mv "$$qcow2" $@ -/var/lib/libvirt/images/$(PROJECT_NAME)/fcos.ign: fcos.ign +/var/lib/libvirt/images/fcos-$(PROJECT_NAME)/fcos.ign: fcos.ign install -D -o root -g root -m 0644 $< $@ -/var/lib/libvirt/images/$(PROJECT_NAME)/root.qcow2: /var/lib/libvirt/images/library/fedora-coreos.qcow2 +/var/lib/libvirt/images/fcos-$(PROJECT_NAME)/root.qcow2: /var/lib/libvirt/images/library/fedora-coreos.qcow2 install -D -o root -g root -m 0644 $< $@ -fcos-vm: pre-requisites clean-vm /var/lib/libvirt/images/$(PROJECT_NAME)/fcos.ign /var/lib/libvirt/images/$(PROJECT_NAME)/root.qcow2 - virt-install --name=$(PROJECT_NAME) --import --noautoconsole \ +/srv/fcos-$(PROJECT_NAME): + install -d -o root -g root -m 0755 $@ + +fcos-vm: pre-requisites clean-vm /var/lib/libvirt/images/fcos-$(PROJECT_NAME)/fcos.ign /var/lib/libvirt/images/fcos-$(PROJECT_NAME)/root.qcow2 /srv/fcos-$(PROJECT_NAME) + virt-install --name=fcos-$(PROJECT_NAME) --import --noautoconsole \ --ram=4096 --vcpus=2 --os-variant=fedora-coreos-stable \ - --disk path=/var/lib/libvirt/images/$(PROJECT_NAME)/root.qcow2,format=qcow2,size=50 \ - --qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=/var/lib/libvirt/images/$(PROJECT_NAME)/fcos.ign" \ + --disk path=/var/lib/libvirt/images/fcos-$(PROJECT_NAME)/root.qcow2,format=qcow2,size=50 \ + --qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=/var/lib/libvirt/images/fcos-$(PROJECT_NAME)/fcos.ign" \ --network network=default,model=virtio \ - --console=pty,target.type=virtio --serial=pty --graphics=none --boot=uefi + --console=pty,target.type=virtio --serial=pty --graphics=none --boot=uefi \ + --memorybacking=access.mode=shared,source.type=memfd \ + --filesystem=type=mount,accessmode=passthrough,driver.type=virtiofs,driver.queue=1024,source.dir=/srv/fcos-$(PROJECT_NAME),target.dir=data clean-vm: pre-requisites - virsh destroy $(PROJECT_NAME) || true - virsh undefine $(PROJECT_NAME) --nvram || true - rm -rf /var/lib/libvirt/images/$(PROJECT_NAME) + virsh destroy fcos-$(PROJECT_NAME) || true + virsh undefine fcos-$(PROJECT_NAME) --nvram || true + rm -rf /var/lib/libvirt/images/fcos-$(PROJECT_NAME) + rm -rf /srv/fcos-$(PROJECT_NAME) console: pre-requisites - @while sleep 2; do virsh console $(PROJECT_NAME); echo -e "Disconnected. Reconnecting in 2 seconds...\nPress Ctrl-C to abort.\n"; done + @while sleep 2; do virsh console fcos-$(PROJECT_NAME); echo -e "Disconnected. Reconnecting in 2 seconds...\nPress Ctrl-C to abort.\n"; done clean-pre:: @run() { echo $$*; "$$@"; }; \ diff --git a/nextcloud/Makefile b/nextcloud/Makefile index 9caab88..a06d381 100644 --- a/nextcloud/Makefile +++ b/nextcloud/Makefile @@ -1,3 +1,4 @@ +# Also depends on virtiofs for data storage but is a transitive dependency via postgresql DEPENDENCIES = postgresql TOP_LEVEL_DIR := .. diff --git a/nextcloud/nextcloud-app.container b/nextcloud/nextcloud-app.container index 4edc3b7..c09423c 100644 --- a/nextcloud/nextcloud-app.container +++ b/nextcloud/nextcloud-app.container @@ -28,6 +28,7 @@ EnvironmentFile=/etc/quadlets/nextcloud/config.env # Volume mounts Volume=/var/lib/quadlets/nextcloud/data:/var/www/html:z +Volume=/var/lib/virtiofs/data/nextcloud:/var/www/html/data:z Volume=/etc/quadlets/nextcloud/www.conf:/usr/local/etc/php-fpm.d/www.conf:Z Volume=/run/quadlets/nextcloud/redis-session.ini:/usr/local/etc/php/conf.d/redis-session.ini:Z Volume=/etc/quadlets/nextcloud/custom-noinit.sh:/docker-entrypoint-hooks.d/pre-installation/custom.sh:z,ro diff --git a/nginx/nginx-update.container b/nginx/nginx-update.container index 4e6941a..6114a6e 100644 --- a/nginx/nginx-update.container +++ b/nginx/nginx-update.container @@ -40,4 +40,4 @@ EnvironmentFile=/etc/quadlets/nginx/config.env Type=oneshot [Install] -WantedBy=nginx.target +WantedBy=nginx.target nginx-update.timer diff --git a/nginx/nginx-update.timer b/nginx/nginx-update.timer new file mode 100644 index 0000000..d76b08e --- /dev/null +++ b/nginx/nginx-update.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Update Nginx root directory from a Git repository - Timer +Documentation=https://hub.docker.com/r/alpine/git +PartOf=nginx.target + +[Timer] +OnActiveSec=15min +RandomizedDelaySec=15s + +[Install] +WantedBy=nginx.target \ No newline at end of file diff --git a/postgresql/Makefile b/postgresql/Makefile index 2f6e3ee..f806f34 100644 --- a/postgresql/Makefile +++ b/postgresql/Makefile @@ -1,3 +1,5 @@ +DEPENDENCIES = virtiofs + TOP_LEVEL_DIR := .. include $(TOP_LEVEL_DIR)/Makefile.common @@ -8,10 +10,10 @@ PG_MAJOR_LAST ?= 18 test-set-pgmajor: sed -i 's/^PG_MAJOR=.*/PG_MAJOR=$(PG_MAJOR_START)/' config/config.env -$(TARGET_CHROOT)/var/lib/quadlets/postgresql/backup $(TARGET_CHROOT)/var/lib/quadlets/postgresql: +$(TARGET_CHROOT)/var/lib/quadlets/postgresql: install -m 0700 -o 70 -g 70 -d $@ -install-var: $(TARGET_CHROOT)/var/lib/quadlets/postgresql/backup +install-var: $(TARGET_CHROOT)/var/lib/quadlets/postgresql test: uninstall clean test-set-pgmajor install @echo "Running PostgreSQL integration tests..."; \ diff --git a/postgresql/postgresql-backup.container b/postgresql/postgresql-backup.container index 0d5860d..6e2f565 100644 --- a/postgresql/postgresql-backup.container +++ b/postgresql/postgresql-backup.container @@ -25,6 +25,7 @@ User=postgres # Volume mounts Volume=/var/lib/quadlets/postgresql:/var/lib/postgresql:z +Volume=/var/lib/virtiofs/data/postgresql/backup:/var/lib/postgresql/backup:z Volume=/etc/quadlets/postgresql/backup.sh:/usr/local/bin/backup.sh:z,ro # Share /run/postgresql/ between containers in the pod for the Unix socket diff --git a/postgresql/tmpfiles.d/postgresql.conf b/postgresql/tmpfiles.d/postgresql.conf index 8bba2ea..344ba16 100644 --- a/postgresql/tmpfiles.d/postgresql.conf +++ b/postgresql/tmpfiles.d/postgresql.conf @@ -1 +1,3 @@ d$ /run/quadlets/postgresql 0700 70 70 - +d$ /var/lib/virtiofs/data/postgresql 0700 70 70 - +d$ /var/lib/virtiofs/data/postgresql/backup 0700 70 70 - diff --git a/virtiofs/Makefile b/virtiofs/Makefile new file mode 100644 index 0000000..9f768d3 --- /dev/null +++ b/virtiofs/Makefile @@ -0,0 +1,3 @@ +TOP_LEVEL_DIR := .. +include $(TOP_LEVEL_DIR)/Makefile.common +SYSTEMD_MAIN_UNIT_NAMES := var-lib-virtiofs-data.mount diff --git a/virtiofs/backup-virtiofs.service b/virtiofs/backup-virtiofs.service new file mode 100644 index 0000000..316d913 --- /dev/null +++ b/virtiofs/backup-virtiofs.service @@ -0,0 +1,22 @@ +[Unit] +Description=Backup the "data" virtio filesystems +Before=var-lib-virtiofs-data.mount +RequiresMountsFor=/var +ConditionPathIsMountPoint=!/var/lib/virtiofs/data + +# Unless DefaultDependencies= is set to false, service units will implicitly +# have dependencies of type Requires= and After= on basic.target as well as +# dependencies of type Conflicts= and Before= on shutdown.target. +# +# So, we need to set DefaultDependencies to "no" to break the ordering cycle. +DefaultDependencies=no + +# Only run on Fedora CoreOS +ConditionOSRelease=ID=fedora +ConditionOSRelease=VARIANT_ID=coreos + +[Service] +Type=oneshot +UMask=077 +ExecStart=/bin/bash -Eeuo pipefail -c 'if grep -q "data /var/lib/virtiofs/data" /proc/mounts; then echo "ERROR: /var/lib/virtiofs/data is mounted!"; exit 1; else tar -cf /var/lib/private/virtiofs.tar -C /var/lib/virtiofs/data .; fi' +RemainAfterExit=yes diff --git a/virtiofs/restore-virtiofs.service b/virtiofs/restore-virtiofs.service new file mode 100644 index 0000000..daaa38c --- /dev/null +++ b/virtiofs/restore-virtiofs.service @@ -0,0 +1,16 @@ +[Unit] +Description=Restore the "data" virtio filesystems +After=var-lib-virtiofs-data.mount +Requires=var-lib-virtiofs-data.mount +RequiresMountsFor=/var +ConditionPathIsMountPoint=/var/lib/virtiofs/data +ConditionPathExists=/var/lib/private/virtiofs.tar + +# Only run on Fedora CoreOS +ConditionOSRelease=ID=fedora +ConditionOSRelease=VARIANT_ID=coreos + +[Service] +Type=oneshot +ExecStart=/bin/bash -Eeuo pipefail -c 'if ! grep -q "data /var/lib/virtiofs/data" /proc/mounts; then echo "ERROR: /var/lib/virtiofs/data is NOT mounted!"; exit 1; else tar -xf /var/lib/private/virtiofs.tar -C /var/lib/virtiofs/data; rm -f /var/lib/private/virtiofs.tar; fi' +RemainAfterExit=yes diff --git a/virtiofs/tmpfiles.d/virtiofs.conf b/virtiofs/tmpfiles.d/virtiofs.conf new file mode 100644 index 0000000..dac5a9d --- /dev/null +++ b/virtiofs/tmpfiles.d/virtiofs.conf @@ -0,0 +1,2 @@ +d /var/lib/virtiofs 0755 0 0 - +d /var/lib/virtiofs/data 0755 0 0 - diff --git a/virtiofs/var-lib-virtiofs-data.mount b/virtiofs/var-lib-virtiofs-data.mount new file mode 100644 index 0000000..9157f16 --- /dev/null +++ b/virtiofs/var-lib-virtiofs-data.mount @@ -0,0 +1,19 @@ +[Unit] +Description=Mount the "data" virtio filesystem +After=backup-virtiofs.service +Requires=backup-virtiofs.service +Before=restore-virtiofs.service +Wants=restore-virtiofs.service + +# Only run on Fedora CoreOS +ConditionOSRelease=ID=fedora +ConditionOSRelease=VARIANT_ID=coreos + +[Mount] +What=data +Where=/var/lib/virtiofs/data +Type=virtiofs +Options=context=system_u:object_r:container_file_t:s0 + +[Install] +WantedBy=local-fs.target