diff --git a/Makefile b/Makefile index f3615d8..09da7bf 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,8 @@ SUBDIRS := $(dir $(SUBDIRS)) .PHONY: all help butane clean dryrun fcos-vm clean-vm uninstall $(SUBDIRS) +export I_KNOW_WHAT_I_AM_DOING ?= no + all: help help: @echo "Available targets:" @@ -16,6 +18,8 @@ help: dryrun: $(SUBDIRS) butane: $(SUBDIRS) clean: $(SUBDIRS) + rm -f local.ign + fcos-vm: $(SUBDIRS) clean-vm: $(SUBDIRS) uninstall: $(SUBDIRS) diff --git a/Makefile.common b/Makefile.common index a5f010d..57a818a 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1,6 +1,19 @@ all: help help: + @echo + @echo "================================================" + @echo " Project '$(PROJECT_NAME)'" + @echo "================================================" + @echo + @echo "Relevant paths and settings:" + @echo + @echo " Configuration directory: /etc/quadlets/$(PROJECT_NAME)" + @echo " Persistent Storage directory: /var/lib/quadlets/$(PROJECT_NAME)" + @echo " UID & GID for project files: $(PROJECT_UID):$(PROJECT_GID)" + @echo " Dependencies: $(if $(DEPENDENCIES),$(DEPENDENCIES),none)" + @echo @echo "Available targets:" + @echo @echo " help - Show this help message" @echo " install - Install quadlets and systemd units" @echo " uninstall - Uninstall quadlets and systemd units" @@ -9,11 +22,35 @@ help: @echo " tail-logs - Tail the logs of the quadlet units" @echo " butane - Build Butane specifications suitable for Fedora CoreOS" @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 " console - Connect to the Fedora CoreOS VM console" - -# Where to install the quadlets and systemd units. If not set, the host system is used. -TARGET_CHROOT ?= + @echo " clean-vm - Clean up the Fedora CoreOS VM but keep its storage resources" + @echo " remove-vm - Remove all resources related to the Fedora CoreOS VM" + @echo " console - Connect to the Fedora CoreOS VM console" + @echo + @echo "Useful commands:" + @echo + @echo " 1. make uninstall install # Replace quadlets and systemd units" + @echo " 2. make uninstall clean install # Same but also remove persistent data and configuration" + @echo " 3. make uninstall install tail-logs # Replace quadlets and systemd units, then tail their logs" + @echo " 4. make I_KNOW_WHAT_I_AM_DOING=yes clean # Remove all persistent data and configuration without confirmation" + @echo " 5. make butane # Build Butane specifications suitable for Fedora CoreOS" + @echo " 6. make fcos-vm console # Launch a fresh Fedora CoreOS VM (while retaining its persistent data) and connect to its console" + @echo " 7. make remove-vm # Remove all resources related to the Fedora CoreOS VM" + @echo + @echo "All-in-one commands:" + @echo + @echo " 1. make I_KNOW_WHAT_I_AM_DOING=yes uninstall clean install tail-logs" + @echo " 2. make fcos-vm console" + @echo + +# Create a temporary directory as target chroot when we detect that we are building Butane specs or launching a Fedora CoreOS VM. +ifneq ($(filter %.ign %.bu butane fcos-vm,$(MAKECMDGOALS)),) +ifeq ($(TARGET_CHROOT),) +export TARGET_CHROOT := $(shell mktemp -d /tmp/butane-chroot-XXXXXX) +endif +ifeq ($(BUTANE_BLOCKLIST),) +export BUTANE_BLOCKLIST := $(shell tmp=$$(mktemp /tmp/butane-blocklist-XXXXXX); cp $(TOP_LEVEL_DIR)/butane.blocklist "$$tmp"; echo "$$tmp") +endif +endif # Name of the current project, derived from the current working directory. # This is used to create subdirectories for configuration and state files. @@ -67,7 +104,8 @@ DEPENDENCIES ?= I_KNOW_WHAT_I_AM_DOING ?= # List of all ignition files corresponding to the dependencies -DEPENDENCIES_IGNITION_FILES = $(shell for dep in $(DEPENDENCIES); do echo $(TOP_LEVEL_DIR)/$$dep/$$dep.ign; done) +# Here, we inject the "base" project as a dependency. It can therefore be assumed to always be embeddable in project's butane specs. +DEPENDENCIES_IGNITION_FILES := $(shell for dep in base $(DEPENDENCIES); do echo $(TOP_LEVEL_DIR)/$$dep/$$dep.ign $(TOP_LEVEL_DIR)/$$dep/$$dep-examples.ign; done) # User and group IDs to own the project files and directories. PROJECT_UID ?= 0 @@ -83,6 +121,13 @@ pre-requisites: echo "This Makefile must be run as root" >&2; \ exit 1; \ fi + @set -Eeuo pipefail; \ + for tool in install systemctl systemd-analyze systemd-tmpfiles sysctl virt-install virsh qemu-img journalctl coreos-installer resize butane yq; do \ + if ! which $$tool &>/dev/null ; then \ + echo "$$tool is not installed. Please install it first." >&2; \ + exit 1; \ + fi ; \ + done # Perform a dry run of the podman systemd generator to validate the quadlet and systemd files. dryrun: @@ -109,6 +154,7 @@ $(TARGET_CONFIG_FILES): $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME)/%: config/ $(TARGET_EXAMPLES_CONFIG_FILES): $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME)/%: config/examples/% $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME) $(filter-out %.env, $(TARGET_CONFIG_FILES) $(TARGET_EXAMPLES_CONFIG_FILES)): @run() { echo $$*; "$$@"; }; \ + set -Eeuo pipefail; \ if [ -x $< ]; then \ run install -D -m 0755 -o $(PROJECT_UID) -g $(PROJECT_GID) $< $@; \ else \ @@ -149,6 +195,7 @@ install-files: install-files-pre install-config install-examples # This target can be extended by Makefiles sourcing this one. install-files-pre:: @run() { echo $$*; "$$@"; }; \ + set -Eeuo pipefail; \ for dep in $(DEPENDENCIES); do \ run $(MAKE) -C $(TOP_LEVEL_DIR)/$$dep install-files; \ done @@ -162,6 +209,7 @@ install-actions: install-actions-pre systemctl daemon-reload systemd-analyze --generators=true verify $(QUADLET_UNIT_NAMES) $(SYSTEMD_UNIT_NAMES) @run() { echo $$*; "$$@"; }; \ + set -Eeuo pipefail; \ if [ -f /etc/tmpfiles.d/$(PROJECT_NAME).conf ]; then \ run systemd-tmpfiles --create /etc/tmpfiles.d/$(PROJECT_NAME).conf; \ fi; \ @@ -176,6 +224,7 @@ install-actions: install-actions-pre # This target can be extended by Makefiles sourcing this one. install-actions-pre:: @run() { echo $$*; "$$@"; }; \ + set -Eeuo pipefail; \ for dep in $(DEPENDENCIES); do \ run $(MAKE) -C $(TOP_LEVEL_DIR)/$$dep install-actions; \ done @@ -203,6 +252,7 @@ uninstall: pre-requisites uninstall-pre systemctl disable $(SYSTEMD_MAIN_UNIT_NAMES) $(SYSTEMD_TIMER_NAMES) || true systemctl stop $(SYSTEMD_UNIT_NAMES) $(QUADLET_UNIT_NAMES) || true @run() { echo $$*; "$$@"; }; \ + set -Eeuo pipefail; \ if [ -f /etc/tmpfiles.d/$(PROJECT_NAME).conf ]; then \ run systemd-tmpfiles --purge /etc/tmpfiles.d/$(PROJECT_NAME).conf; \ fi @@ -218,6 +268,7 @@ uninstall-pre:: # This target can be extended by Makefiles sourcing this one. uninstall-post:: @run() { echo $$*; "$$@"; }; \ + set -Eeuo pipefail; \ for dep in $(DEPENDENCIES); do \ run $(MAKE) -C $(TOP_LEVEL_DIR)/$$dep uninstall; \ done @@ -225,67 +276,68 @@ uninstall-post:: # Tail the logs of all units managed by this project. tail-logs: pre-requisites @run() { echo $$*; "$$@"; }; \ + set -Eeuo pipefail; \ declare -a journalctl_args=( -f ); \ for unit in $$($(MAKE) -s units 2>/dev/null | sort -u); do \ journalctl_args+=( -u "$$unit" ); \ done; \ run journalctl "$${journalctl_args[@]}" -# Generate the current project's Butane spec. -$(PROJECT_NAME).bu: install-config +# Ensure that required variables are set before building Butane specifications. +butane-prerequisites: @if [ -z "$(TARGET_CHROOT)" ]; then \ echo "TARGET_CHROOT is not set!"; exit 1; \ + fi; \ + if [ -z "$(BUTANE_BLOCKLIST)" ]; then \ + echo "BUTANE_BLOCKLIST is not set!"; exit 1; \ fi - $(TOP_LEVEL_DIR)/generate-butane-spec.sh $(TARGET_CHROOT) $(TOP_LEVEL_DIR)/butane.blocklist $(SYSTEMD_MAIN_UNIT_NAMES) $(SYSTEMD_TIMER_NAMES) > $(PROJECT_NAME).bu -# Generate the current project's Butane spec for the example configuration files. -$(PROJECT_NAME)-examples.bu: install-examples - @if [ -z "$(TARGET_CHROOT)" ]; then \ - echo "TARGET_CHROOT is not set!"; exit 1; \ - fi - $(TOP_LEVEL_DIR)/generate-butane-spec.sh $(TARGET_CHROOT) butane.blocklist > $(PROJECT_NAME)-examples.bu +# Build the Butane specifications (configuration files) suitable for Fedora CoreOS. +# In order to avoid duplications in the ignition files, a blocklist is updated, containing file paths as they are added to the chroot. +$(PROJECT_NAME).bu: butane-prerequisites install-config + $(TOP_LEVEL_DIR)/generate-butane-spec.sh $(TARGET_CHROOT) $(BUTANE_BLOCKLIST) $(SYSTEMD_MAIN_UNIT_NAMES) $(SYSTEMD_TIMER_NAMES) > $(PROJECT_NAME).bu + @(cat $(TOP_LEVEL_DIR)/butane.blocklist; echo; for file in $$(find "$$TARGET_CHROOT"); do echo "$${file#$$TARGET_CHROOT}"; done) | sort -u | grep -v -E '^$$' > "$(BUTANE_BLOCKLIST)" -# Generate the current project's Ignition files from the Butane specs. -$(PROJECT_NAME).ign: butane - butane --strict -o $(PROJECT_NAME).ign $(PROJECT_NAME).bu - butane --strict -o $(PROJECT_NAME)-examples.ign $(PROJECT_NAME)-examples.bu +# Build the Butane specifications (example files) suitable for Fedora CoreOS. +# In order to avoid duplications in the ignition files, a blocklist is updated, containing file paths as they are added to the chroot. +$(PROJECT_NAME)-examples.bu: butane-prerequisites install-examples + $(TOP_LEVEL_DIR)/generate-butane-spec.sh $(TARGET_CHROOT) $(BUTANE_BLOCKLIST) > $(PROJECT_NAME)-examples.bu + @(cat $(TOP_LEVEL_DIR)/butane.blocklist; echo; for file in $$(find "$$TARGET_CHROOT"); do echo "$${file#$$TARGET_CHROOT}"; done) | sort -u | grep -v -E '^$$' > "$(BUTANE_BLOCKLIST)" -# Build the Butane specifications suitable for Fedora CoreOS, including those of the dependencies of this project. -# In order to avoid duplications in the ignition files, a blocklist is created containing file paths as they are added to the chroot. -butane: +# Build the Butane specifications + Ignition files suitable for Fedora CoreOS of the dependencies of this project. +butane-pre:: butane-prerequisites @run() { echo $$*; "$$@"; }; \ - init_butane_blocklist() { \ - (cat $(TOP_LEVEL_DIR)/butane.blocklist; echo; for file in $$(find "$$TARGET_CHROOT"); do echo "$${file#$$TARGET_CHROOT}"; done) | sort -u | grep -v -E '^$$' > butane.blocklist; \ - }; \ - if [ -z "$(TARGET_CHROOT)" ]; then \ - TARGET_CHROOT=$$(mktemp -d /tmp/butane-XXXXXX); \ - else \ - TARGET_CHROOT="$(TARGET_CHROOT)"; \ - fi; \ - for dep in $(DEPENDENCIES); do \ - run $(MAKE) -C $(TOP_LEVEL_DIR)/$$dep TARGET_CHROOT="$$TARGET_CHROOT" butane ; \ - done ; \ - run init_butane_blocklist ; \ - run $(MAKE) TARGET_CHROOT="$$TARGET_CHROOT" $(PROJECT_NAME).bu; \ - run init_butane_blocklist ; \ - run $(MAKE) TARGET_CHROOT="$$TARGET_CHROOT" $(PROJECT_NAME)-examples.bu; \ - if [ -z "$(TARGET_CHROOT)" ]; then \ - run rm -rf "$$TARGET_CHROOT"; \ - fi + set -Eeuo pipefail; \ + for dep in base $(DEPENDENCIES); do \ + if [[ "$$dep" == "$(PROJECT_NAME)" ]]; then \ + # Avoid building the current project as its own dependency. \ + continue; \ + fi ; \ + run $(MAKE) -C $(TOP_LEVEL_DIR)/$$dep $$dep.ign $$dep-examples.ign ; \ + done + +# Generate the current project's Ignition files from the Butane specs. +$(PROJECT_NAME).ign $(PROJECT_NAME)-examples.ign: butane-pre +$(PROJECT_NAME).ign $(PROJECT_NAME)-examples.ign: %.ign: %.bu + butane --strict -o $@ $< -# Generate the local Butane spec (the one containing local customizations). +# Build the Butane specifications + Ignition files suitable for Fedora CoreOS, including those of the dependencies of this project. +butane: fcos.ign + +# Generate the local Butane spec + Ignition file (the one containing local customizations). $(TOP_LEVEL_DIR)/local.ign: $(TOP_LEVEL_DIR)/local.bu butane --strict -o $@ $< # Build the ignition files of the dependencies of this project. $(DEPENDENCIES_IGNITION_FILES): $(MAKE) -C $(dir $@) $(notdir $@) -# Because we don't know how to build this file, it is safer to declare it as phony and let the Makefile of the dependency handle it. +# The file might exist already, declare it as phony and let the child Makefile handle it. .PHONY: $(DEPENDENCIES_IGNITION_FILES) # Generate the final Fedora CoreOS ignition file by merging the Butane spec with the local and project-specific ignition files, as well as those of the dependencies. -fcos.ign: fcos.bu $(TOP_LEVEL_DIR)/local.ign $(PROJECT_NAME).ign $(DEPENDENCIES_IGNITION_FILES) +fcos.ign: fcos.bu $(TOP_LEVEL_DIR)/local.ign $(PROJECT_NAME).ign $(PROJECT_NAME)-examples.ign $(DEPENDENCIES_IGNITION_FILES) @run() { echo $$*; "$$@"; }; \ + set -Eeuo pipefail; \ tmp=$$(mktemp -d /tmp/butane-XXXXXX); \ run cp $(filter %.ign,$^) $$tmp; \ run butane --strict -d $$tmp -o $@ fcos.bu; \ @@ -294,6 +346,7 @@ fcos.ign: fcos.bu $(TOP_LEVEL_DIR)/local.ign $(PROJECT_NAME).ign $(DEPENDENCIES_ # Fetch the latest version of the Fedora CoreOS QCOW2 image. /var/lib/libvirt/images/library/fedora-coreos.qcow2: @run() { echo $$*; "$$@"; }; \ + set -Eeuo pipefail; \ run mkdir -p /var/lib/libvirt/images/library/ ; \ if ! run coreos-installer download -p qemu -f qcow2.xz -d -C /var/lib/libvirt/images/library/ ; then \ echo "CoreOS QCOW2 image could not be downloaded." >&2; \ @@ -310,31 +363,50 @@ fcos.ign: fcos.bu $(TOP_LEVEL_DIR)/local.ign $(PROJECT_NAME).ign $(DEPENDENCIES_ /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 $< $@ +# Create an empty QCOW2 image for the /var filesystem of the VM. +/var/lib/libvirt/images/fcos-$(PROJECT_NAME)/var.qcow2: + qemu-img create -f qcow2 $@ 100G + # Create the directory to be shared with the Fedora CoreOS VM through virtiofs. /srv/fcos-$(PROJECT_NAME): install -d -o root -g root -m 0755 $@ # Launch a Fedora CoreOS VM with the generated Butane spec. -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) +fcos-vm: pre-requisites clean-vm /var/lib/libvirt/images/fcos-$(PROJECT_NAME)/fcos.ign /var/lib/libvirt/images/fcos-$(PROJECT_NAME)/root.qcow2 /var/lib/libvirt/images/fcos-$(PROJECT_NAME)/var.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/fcos-$(PROJECT_NAME)/root.qcow2,format=qcow2,size=50 \ + --disk path=/var/lib/libvirt/images/fcos-$(PROJECT_NAME)/var.qcow2,format=qcow2 \ --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 \ --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 up the Fedora CoreOS VM and its resources. +# Clean up the Fedora CoreOS VM but keep its storage resources. clean-vm: pre-requisites virsh destroy fcos-$(PROJECT_NAME) || true virsh undefine fcos-$(PROJECT_NAME) --nvram || true + rm -f /var/lib/libvirt/images/fcos-$(PROJECT_NAME)/root.qcow2 /var/lib/libvirt/images/fcos-$(PROJECT_NAME)/fcos.ign + +# Remove all resources related to the Fedora CoreOS VM. +remove-vm: clean-vm rm -rf /var/lib/libvirt/images/fcos-$(PROJECT_NAME) rm -rf /srv/fcos-$(PROJECT_NAME) # Connect to the console of the Fedora CoreOS VM. console: pre-requisites - @while sleep 2; do virsh console fcos-$(PROJECT_NAME); echo -e "Disconnected. Reconnecting in 2 seconds...\nPress Ctrl-C to abort.\n"; done + @set -Eeuo pipefail; \ + # Save the current terminal size to restore it after disconnecting from the VM console. \ + term_size=$$(stty size); \ + while sleep 2; do \ + virsh console fcos-$(PROJECT_NAME); \ + # Restore the terminal size after disconnecting from the VM console. \ + # This avoids issues with the terminal being stuck in an incorrect size because \ + # of the UEFI / Grub TUI messed with the terminal size during a VM reboot. \ + eval $$(resize -s $$term_size); \ + echo -e "Disconnected. Reconnecting in 2 seconds...\nPress Ctrl-C to abort.\n"; \ + done # List all systemd and quadlet unit names provided by the dependencies of this project. units-pre:: @@ -350,6 +422,7 @@ units: units-pre # This target can be extended by Makefiles sourcing this one. clean-pre:: @run() { echo $$*; "$$@"; }; \ + set -Eeuo pipefail; \ for dep in $(DEPENDENCIES); do \ run $(MAKE) -C $(TOP_LEVEL_DIR)/$$dep clean; \ done @@ -360,8 +433,9 @@ clean-post:: # Remove all persistent data and configuration files clean: clean-pre pre-requisites - rm -f *.butane + rm -f *.bu *.ign butane.blocklist @run() { echo $$*; "$$@"; }; \ + set -Eeuo pipefail; \ if [ "$(I_KNOW_WHAT_I_AM_DOING)" != "yes" ]; then \ read -p "This will remove all data of '$(PROJECT_NAME)'. Are you sure? (only 'yes' is accepted) " ans; \ if [ "$$ans" != "yes" ] && [ "$$ans" != "YES" ]; then \ @@ -373,7 +447,7 @@ clean: clean-pre pre-requisites # All phony targets .PHONY: all install install-config install-examples uninstall pre-requisites clean dryrun -.PHONY: tail-logs butane help fcos-vm clean-vm console units units-pre +.PHONY: tail-logs butane help fcos-vm clean-vm console units units-pre remove-vm .PHONY: clean-pre clean-post install-pre install-post uninstall-pre uninstall-post .PHONY: install-files install-files-pre install-files-post install-actions -.PHONY: install-actions-pre install-actions-post +.PHONY: install-actions-pre install-actions-post butane-prerequisites butane-pre diff --git a/base/Makefile b/base/Makefile new file mode 100644 index 0000000..8c4e548 --- /dev/null +++ b/base/Makefile @@ -0,0 +1,3 @@ +TOP_LEVEL_DIR := .. +include $(TOP_LEVEL_DIR)/Makefile.common +SYSTEMD_MAIN_UNIT_NAMES := var-lib-virtiofs-data.mount rpm-ostree-install-qemu-guest-agent.service diff --git a/base/rpm-ostree-install-qemu-guest-agent.service b/base/rpm-ostree-install-qemu-guest-agent.service new file mode 100644 index 0000000..c8e8c37 --- /dev/null +++ b/base/rpm-ostree-install-qemu-guest-agent.service @@ -0,0 +1,20 @@ +[Unit] +Description=Install qemu-guest-agent +Wants=network-online.target +After=network-online.target +Before=zincati.service +ConditionPathExists=!/usr/bin/qemu-ga + +# Only run on Fedora CoreOS +ConditionOSRelease=ID=fedora +ConditionOSRelease=VARIANT_ID=coreos + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/bin/rpm-ostree install -y --allow-inactive qemu-guest-agent +ExecStart=/usr/bin/rpm-ostree apply-live +ExecStart=/usr/bin/systemctl enable --now qemu-guest-agent.service + +[Install] +WantedBy=multi-user.target diff --git a/virtiofs/tmpfiles.d/virtiofs.conf b/base/tmpfiles.d/base.conf similarity index 100% rename from virtiofs/tmpfiles.d/virtiofs.conf rename to base/tmpfiles.d/base.conf diff --git a/virtiofs/var-lib-virtiofs-data.mount b/base/var-lib-virtiofs-data.mount similarity index 70% rename from virtiofs/var-lib-virtiofs-data.mount rename to base/var-lib-virtiofs-data.mount index 9157f16..d0d129c 100644 --- a/virtiofs/var-lib-virtiofs-data.mount +++ b/base/var-lib-virtiofs-data.mount @@ -1,9 +1,5 @@ [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 diff --git a/local.bu.template b/local.bu.template index 6414590..d70277c 100644 --- a/local.bu.template +++ b/local.bu.template @@ -1,5 +1,46 @@ variant: fcos version: 1.4.0 +storage: + disks: + - device: /dev/vdb + wipe_table: false + partitions: + # Specify the partition number so that FCOS do not try to create a new + # partition at each VM redeployment. + - number: 1 + size_mib: 0 + start_mib: 0 + label: var + filesystems: + - path: /var + device: /dev/disk/by-partlabel/var + format: xfs + with_mount_unit: true + directories: + - path: /var/lib/private/sshd + mode: 0700 + files: + - path: /etc/resolv.conf + overwrite: true + contents: + inline: "" # will be updated by NetworkManager + - path: /etc/NetworkManager/conf.d/itix.conf + contents: + inline: | + [main] + # test + rc-manager=file +systemd: + units: + - name: systemd-resolved.service + enabled: false + mask: true + - name: sshd-keygen@.service + dropins: + - name: backup-restore.conf + contents: | + [Service] + ExecStartPost=/bin/bash -c 'if [ -f /var/lib/private/sshd/ssh_host_%i_key ]; then cp -Z /var/lib/private/sshd/ssh_host_%i_key{,.pub} /etc/ssh/; elif [ -f /etc/ssh/ssh_host_%i_key ]; then cp -a /etc/ssh/ssh_host_%i_key{,.pub} /var/lib/private/sshd/; fi' passwd: users: - name: core diff --git a/nextcloud/Makefile b/nextcloud/Makefile index e248266..832dcfa 100644 --- a/nextcloud/Makefile +++ b/nextcloud/Makefile @@ -2,7 +2,6 @@ ## Makefile for PostgreSQL quadlet ## -# Project dependencies: Nextcloud also depends on virtiofs for data storage but is a transitive dependency via postgresql DEPENDENCIES = postgresql # Nextcloud quadlet is mapped to the 10008 user (nextcloud) and 10000 group (itix-svc) diff --git a/nextcloud/fcos.bu b/nextcloud/fcos.bu deleted file mode 100644 index 903b3d8..0000000 --- a/nextcloud/fcos.bu +++ /dev/null @@ -1,11 +0,0 @@ -variant: fcos -version: 1.4.0 -ignition: - config: - merge: - - local: virtiofs.ign - - local: nextcloud.ign - - local: nextcloud-examples.ign - - local: postgresql.ign - - local: postgresql-examples.ign - - local: local.ign diff --git a/nginx/fcos.bu b/nginx/fcos.bu deleted file mode 100644 index b355767..0000000 --- a/nginx/fcos.bu +++ /dev/null @@ -1,8 +0,0 @@ -variant: fcos -version: 1.4.0 -ignition: - config: - merge: - - local: nginx.ign - - local: nginx-examples.ign - - local: local.ign diff --git a/postgresql/Makefile b/postgresql/Makefile index 0ea1c16..df4d24b 100644 --- a/postgresql/Makefile +++ b/postgresql/Makefile @@ -2,9 +2,6 @@ ## Makefile for PostgreSQL quadlet ## -# Project dependencies -DEPENDENCIES = virtiofs - # PostgreSQL quadlet is mapped to the 10004 user (postgres) and 10000 group (itix-svc) PROJECT_UID = 10004 PROJECT_GID = 10000 diff --git a/postgresql/fcos.bu b/postgresql/fcos.bu deleted file mode 100644 index 384b686..0000000 --- a/postgresql/fcos.bu +++ /dev/null @@ -1,9 +0,0 @@ -variant: fcos -version: 1.4.0 -ignition: - config: - merge: - - local: virtiofs.ign - - local: postgresql.ign - - local: postgresql-examples.ign - - local: local.ign diff --git a/qemu-user-static/Makefile b/qemu-user-static/Makefile new file mode 100644 index 0000000..94ff525 --- /dev/null +++ b/qemu-user-static/Makefile @@ -0,0 +1,8 @@ +TOP_LEVEL_DIR := .. +include $(TOP_LEVEL_DIR)/Makefile.common + +.PHONY: test + +test: uninstall clean install + @echo "Running $(PROJECT_NAME) tests..." + curl -sSfL -I http://localhost/ diff --git a/qemu-user-static/config/Containerfile b/qemu-user-static/config/Containerfile new file mode 100644 index 0000000..da63203 --- /dev/null +++ b/qemu-user-static/config/Containerfile @@ -0,0 +1,9 @@ +FROM quay.io/fedora/fedora:42 + +RUN dnf install -y qemu-user-static \ + && dnf clean all + +ADD container-entrypoint / + +ENTRYPOINT ["/container-entrypoint"] +CMD [] diff --git a/qemu-user-static/config/container-entrypoint b/qemu-user-static/config/container-entrypoint new file mode 100755 index 0000000..05ab3ea --- /dev/null +++ b/qemu-user-static/config/container-entrypoint @@ -0,0 +1,20 @@ +#!/bin/sh + +set -Eeuo pipefail + +if [ ! -d /proc/sys/fs/binfmt_misc ]; then + echo "No binfmt support in the kernel." + echo " Try: '/sbin/modprobe binfmt_misc' from the host" + exit 1 +fi + +if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then + echo "Mounting /proc/sys/fs/binfmt_misc..." + mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc +fi + +echo "Cleaning up..." +find /proc/sys/fs/binfmt_misc -type f -name 'qemu-*' -exec sh -c 'echo -1 > {}' \; + +echo "Registering..." +exec /usr/lib/systemd/systemd-binfmt diff --git a/qemu-user-static/qemu-user-static-build.timer b/qemu-user-static/qemu-user-static-build.timer new file mode 100644 index 0000000..de4c322 --- /dev/null +++ b/qemu-user-static/qemu-user-static-build.timer @@ -0,0 +1,11 @@ +[Unit] +Description=multiarch /usr/bin/qemu-*-static +Documentation=https://github.com/multiarch/qemu-user-static +PartOf=qemu-user-static.target + +[Timer] +OnCalendar=weekly +Persistent=true + +[Install] +WantedBy=qemu-user-static.target diff --git a/qemu-user-static/qemu-user-static.build b/qemu-user-static/qemu-user-static.build new file mode 100644 index 0000000..8fb20be --- /dev/null +++ b/qemu-user-static/qemu-user-static.build @@ -0,0 +1,10 @@ +[Unit] +Description=multiarch /usr/bin/qemu-*-static +Documentation=https://github.com/multiarch/qemu-user-static +Wants=network-online.target +After=network-online.target + +[Build] +File=/etc/quadlets/qemu-user-static/Containerfile +ImageTag=localhost/qemu-user-static:latest +SetWorkingDirectory=/etc/quadlets/qemu-user-static diff --git a/qemu-user-static/qemu-user-static.container b/qemu-user-static/qemu-user-static.container new file mode 100644 index 0000000..5a635fc --- /dev/null +++ b/qemu-user-static/qemu-user-static.container @@ -0,0 +1,26 @@ +[Unit] +Description=multiarch /usr/bin/qemu-*-static +Documentation=https://github.com/multiarch/qemu-user-static +Wants=qemu-user-static-build.service +After=qemu-user-static-build.service +PartOf=qemu-user-static.target + +[Service] +Type=oneshot +RemainAfterExit=yes + +[Container] +ContainerName=qemu-user-static + +# Image +Image=localhost/qemu-user-static:latest +AutoUpdate=local + +# Security +PodmanArgs=--privileged +SecurityLabelFileType=container_file_t +SecurityLabelType=spc_t +SecurityLabelLevel=s0 + +[Install] +WantedBy=qemu-user-static.target diff --git a/qemu-user-static/qemu-user-static.target b/qemu-user-static/qemu-user-static.target new file mode 100644 index 0000000..3273507 --- /dev/null +++ b/qemu-user-static/qemu-user-static.target @@ -0,0 +1,11 @@ +[Unit] +Description=qemu-user-static Service Target +Documentation=man:systemd.target(5) +Requires=qemu-user-static.service qemu-user-static-build.timer +After=qemu-user-static.service qemu-user-static-build.timer + +# Allow isolation - can stop/start this target independently +AllowIsolate=yes + +[Install] +WantedBy=multi-user.target diff --git a/virtiofs/Makefile b/virtiofs/Makefile deleted file mode 100644 index 9f768d3..0000000 --- a/virtiofs/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -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 deleted file mode 100644 index 316d913..0000000 --- a/virtiofs/backup-virtiofs.service +++ /dev/null @@ -1,22 +0,0 @@ -[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/fcos.bu b/virtiofs/fcos.bu deleted file mode 100644 index c3c9691..0000000 --- a/virtiofs/fcos.bu +++ /dev/null @@ -1,14 +0,0 @@ -variant: fcos -version: 1.4.0 -ignition: - config: - merge: - - local: virtiofs.ign - - local: local.ign -storage: - files: - - path: "/var/lib/virtiofs/data/witness.txt" - mode: 0644 - contents: - inline: | - Hello, World! diff --git a/virtiofs/restore-virtiofs.service b/virtiofs/restore-virtiofs.service deleted file mode 100644 index daaa38c..0000000 --- a/virtiofs/restore-virtiofs.service +++ /dev/null @@ -1,16 +0,0 @@ -[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