Compare commits

...

3 Commits

  1. 1
      .gitignore
  2. 4
      Makefile
  3. 320
      Makefile.common
  4. 3
      base/Makefile
  5. 8
      base/fcos.bu
  6. 43
      base/overlay.bu
  7. 20
      base/rpm-ostree-install-qemu-guest-agent.service
  8. 0
      base/tmpfiles.d/base.conf
  9. 4
      base/var-lib-virtiofs-data.mount
  10. 3
      generate-butane-spec.sh
  11. 101
      nextcloud-aio/examples/config.env
  12. 1
      nextcloud/Makefile
  13. 2
      nextcloud/fcos.bu
  14. 1
      nginx/fcos.bu
  15. 3
      postgresql/Makefile
  16. 2
      postgresql/fcos.bu
  17. 8
      qemu-user-static/Makefile
  18. 9
      qemu-user-static/config/Containerfile
  19. 20
      qemu-user-static/config/container-entrypoint
  20. 9
      qemu-user-static/fcos.bu
  21. 11
      qemu-user-static/qemu-user-static-build.timer
  22. 10
      qemu-user-static/qemu-user-static.build
  23. 26
      qemu-user-static/qemu-user-static.container
  24. 11
      qemu-user-static/qemu-user-static.target
  25. 3
      virtiofs/Makefile
  26. 22
      virtiofs/backup-virtiofs.service
  27. 14
      virtiofs/fcos.bu
  28. 16
      virtiofs/restore-virtiofs.service

1
.gitignore

@ -1,4 +1,5 @@
*.bu *.bu
*.ign *.ign
!fcos.bu !fcos.bu
!overlay.bu
*/butane.blocklist */butane.blocklist

4
Makefile

@ -3,6 +3,8 @@ SUBDIRS := $(dir $(SUBDIRS))
.PHONY: all help butane clean dryrun fcos-vm clean-vm uninstall $(SUBDIRS) .PHONY: all help butane clean dryrun fcos-vm clean-vm uninstall $(SUBDIRS)
export I_KNOW_WHAT_I_AM_DOING ?= no
all: help all: help
help: help:
@echo "Available targets:" @echo "Available targets:"
@ -16,6 +18,8 @@ help:
dryrun: $(SUBDIRS) dryrun: $(SUBDIRS)
butane: $(SUBDIRS) butane: $(SUBDIRS)
clean: $(SUBDIRS) clean: $(SUBDIRS)
rm -f local.ign
fcos-vm: $(SUBDIRS) fcos-vm: $(SUBDIRS)
clean-vm: $(SUBDIRS) clean-vm: $(SUBDIRS)
uninstall: $(SUBDIRS) uninstall: $(SUBDIRS)

320
Makefile.common

@ -1,12 +1,19 @@
.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: 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
all: help all: help
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 "Available targets:"
@echo
@echo " help - Show this help message" @echo " help - Show this help message"
@echo " install - Install quadlets and systemd units" @echo " install - Install quadlets and systemd units"
@echo " uninstall - Uninstall quadlets and systemd units" @echo " uninstall - Uninstall quadlets and systemd units"
@ -15,43 +22,96 @@ help:
@echo " tail-logs - Tail the logs of the quadlet units" @echo " tail-logs - Tail the logs of the quadlet units"
@echo " butane - Build Butane specifications suitable for Fedora CoreOS" @echo " butane - Build Butane specifications suitable for Fedora CoreOS"
@echo " fcos-vm - Launch a Fedora CoreOS VM with the generated Butane spec" @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 " 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 " console - Connect to the Fedora CoreOS VM console"
@echo
TARGET_CHROOT ?= @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.
PROJECT_NAME := $(shell basename "$${PWD}") PROJECT_NAME := $(shell basename "$${PWD}")
# Quadlets files and their corresponding systemd unit names
QUADLETS_FILES = $(wildcard *.container *.volume *.network *.pod *.build) QUADLETS_FILES = $(wildcard *.container *.volume *.network *.pod *.build)
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)) \ QUADLET_UNIT_NAMES := $(patsubst %.container, %.service, $(wildcard *.container)) \
$(patsubst %.volume, %-volume.service, $(wildcard *.volume)) \ $(patsubst %.volume, %-volume.service, $(wildcard *.volume)) \
$(patsubst %.network, %-network.service, $(wildcard *.network)) \ $(patsubst %.network, %-network.service, $(wildcard *.network)) \
$(patsubst %.pod, %-pod.service, $(wildcard *.pod)) \ $(patsubst %.pod, %-pod.service, $(wildcard *.pod)) \
$(patsubst %.build, %-build.service, $(wildcard *.build)) $(patsubst %.build, %-build.service, $(wildcard *.build))
# Wellknown systemd unit file types
SYSTEMD_FILES = $(wildcard *.service *.target *.timer *.mount)
SYSTEMD_UNIT_NAMES := $(wildcard *.service *.target *.timer *.mount)
SYSTEMD_TIMER_NAMES := $(wildcard *.timer)
# The main systemd units will be enabled and started after installation.
SYSTEMD_MAIN_UNIT_NAMES := $(wildcard *.target)
# Configuration files
CONFIG_FILES = $(filter-out %/examples, $(wildcard config/*)) CONFIG_FILES = $(filter-out %/examples, $(wildcard config/*))
TMPFILESD_FILES = $(filter-out %/examples, $(wildcard tmpfiles.d/*)) TMPFILESD_FILES = $(filter-out %/examples, $(wildcard tmpfiles.d/*))
SYSCTLD_FILES = $(filter-out %/examples, $(wildcard sysctl.d/*)) SYSCTLD_FILES = $(filter-out %/examples, $(wildcard sysctl.d/*))
EXAMPLES_CONFIG_FILES = $(wildcard config/examples/*)
EXAMPLES_TMPFILESD_FILES = $(wildcard tmpfiles.d/examples/*)
EXAMPLES_SYSCTLD_FILES = $(wildcard sysctl.d/examples/*)
TARGET_CONFIG_FILES = $(patsubst config/%, $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME)/%, $(CONFIG_FILES)) TARGET_CONFIG_FILES = $(patsubst config/%, $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME)/%, $(CONFIG_FILES))
TARGET_TMPFILESD_FILES = $(patsubst tmpfiles.d/%, $(TARGET_CHROOT)/etc/tmpfiles.d/%, $(TMPFILESD_FILES)) TARGET_TMPFILESD_FILES = $(patsubst tmpfiles.d/%, $(TARGET_CHROOT)/etc/tmpfiles.d/%, $(TMPFILESD_FILES))
TARGET_SYSCTLD_FILES = $(patsubst sysctl.d/%, $(TARGET_CHROOT)/etc/sysctl.d/%, $(SYSCTLD_FILES)) TARGET_SYSCTLD_FILES = $(patsubst sysctl.d/%, $(TARGET_CHROOT)/etc/sysctl.d/%, $(SYSCTLD_FILES))
# Example configuration files
EXAMPLES_CONFIG_FILES = $(wildcard config/examples/*)
EXAMPLES_TMPFILESD_FILES = $(wildcard tmpfiles.d/examples/*)
EXAMPLES_SYSCTLD_FILES = $(wildcard sysctl.d/examples/*)
TARGET_EXAMPLES_CONFIG_FILES = $(patsubst config/examples/%, $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME)/%, $(EXAMPLES_CONFIG_FILES)) TARGET_EXAMPLES_CONFIG_FILES = $(patsubst config/examples/%, $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME)/%, $(EXAMPLES_CONFIG_FILES))
TARGET_EXAMPLES_TMPFILESD_FILES = $(patsubst tmpfiles.d/examples/%, $(TARGET_CHROOT)/etc/tmpfiles.d/%, $(EXAMPLES_TMPFILESD_FILES)) TARGET_EXAMPLES_TMPFILESD_FILES = $(patsubst tmpfiles.d/examples/%, $(TARGET_CHROOT)/etc/tmpfiles.d/%, $(EXAMPLES_TMPFILESD_FILES))
TARGET_EXAMPLES_SYSCTLD_FILES = $(patsubst sysctl.d/examples/%, $(TARGET_CHROOT)/etc/sysctl.d/%, $(EXAMPLES_SYSCTLD_FILES)) TARGET_EXAMPLES_SYSCTLD_FILES = $(patsubst sysctl.d/examples/%, $(TARGET_CHROOT)/etc/sysctl.d/%, $(EXAMPLES_SYSCTLD_FILES))
TARGET_EXAMPLE_FILES = $(TARGET_EXAMPLES_CONFIG_FILES) $(TARGET_EXAMPLES_TMPFILESD_FILES) $(TARGET_EXAMPLES_SYSCTLD_FILES)
# All configuration files to be installed
TARGET_FILES = $(addprefix $(TARGET_CHROOT)/etc/containers/systemd/, $(QUADLETS_FILES)) \ TARGET_FILES = $(addprefix $(TARGET_CHROOT)/etc/containers/systemd/, $(QUADLETS_FILES)) \
$(addprefix $(TARGET_CHROOT)/etc/systemd/system/, $(SYSTEMD_FILES)) \ $(addprefix $(TARGET_CHROOT)/etc/systemd/system/, $(SYSTEMD_FILES)) \
$(TARGET_CONFIG_FILES) $(TARGET_TMPFILESD_FILES) $(TARGET_SYSCTLD_FILES) $(TARGET_CONFIG_FILES) $(TARGET_TMPFILESD_FILES) $(TARGET_SYSCTLD_FILES)
# All example configuration files to be installed
TARGET_EXAMPLE_FILES = $(TARGET_EXAMPLES_CONFIG_FILES) $(TARGET_EXAMPLES_TMPFILESD_FILES) $(TARGET_EXAMPLES_SYSCTLD_FILES)
# Dependencies on other projects
# List here the names of other projects (directories at the top-level) that this project depends on.
DEPENDENCIES ?= DEPENDENCIES ?=
# Set this variable to "yes" to skip the confirmation prompt when running "make clean".
I_KNOW_WHAT_I_AM_DOING ?= I_KNOW_WHAT_I_AM_DOING ?=
DEPENDENCIES_IGNITION_FILES = $(shell for dep in $(DEPENDENCIES); do echo $(TOP_LEVEL_DIR)/$$dep/$$dep.ign; done)
# List of all ignition files corresponding to the dependencies
# 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 PROJECT_UID ?= 0
PROJECT_GID ?= 0 PROJECT_GID ?= 0
# Ensure that the Makefile is not run from the top-level directory and that it is run as root.
pre-requisites: pre-requisites:
@if [ -z "$(TOP_LEVEL_DIR)" ]; then \ @if [ -z "$(TOP_LEVEL_DIR)" ]; then \
echo "Do not run this Makefile from the top-level directory!" >&2; \ echo "Do not run this Makefile from the top-level directory!" >&2; \
@ -61,78 +121,95 @@ pre-requisites:
echo "This Makefile must be run as root" >&2; \ echo "This Makefile must be run as root" >&2; \
exit 1; \ exit 1; \
fi 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: dryrun:
QUADLET_UNIT_DIRS="$$PWD" /usr/lib/systemd/system-generators/podman-system-generator -dryrun > /dev/null QUADLET_UNIT_DIRS="$$PWD" /usr/lib/systemd/system-generators/podman-system-generator -dryrun > /dev/null
$(TARGET_CHROOT)/etc/containers/systemd: # Create the base directories needed for installation.
install -D -d -m 0755 -o root -g root $@ $(TARGET_CHROOT)/etc/containers/systemd $(TARGET_CHROOT)/etc/systemd/system $(TARGET_CHROOT)/etc/tmpfiles.d $(TARGET_CHROOT)/etc/sysctl.d:
$(TARGET_CHROOT)/etc/systemd/system:
install -D -d -m 0755 -o root -g root $@ install -D -d -m 0755 -o root -g root $@
# Create the directory to store quadlet configuration files.
$(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME): $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME):
install -D -d -m 0755 -o $(PROJECT_UID) -g $(PROJECT_GID) $@ install -D -d -m 0755 -o $(PROJECT_UID) -g $(PROJECT_GID) $@
$(TARGET_CHROOT)/etc/tmpfiles.d: # Copy quadlet files
install -D -d -m 0755 -o root -g root $@
$(TARGET_CHROOT)/etc/sysctl.d:
install -D -d -m 0755 -o root -g root $@
$(TARGET_CHROOT)/etc/containers/systemd/%: % $(TARGET_CHROOT)/etc/containers/systemd $(TARGET_CHROOT)/etc/containers/systemd/%: % $(TARGET_CHROOT)/etc/containers/systemd
install -m 0644 -o root -g root $< $@ install -m 0644 -o root -g root $< $@
# Copy systemd unit files
$(TARGET_CHROOT)/etc/systemd/system/%: % $(TARGET_CHROOT)/etc/systemd/system $(TARGET_CHROOT)/etc/systemd/system/%: % $(TARGET_CHROOT)/etc/systemd/system
install -m 0644 -o root -g root $< $@ install -m 0644 -o root -g root $< $@
# Copy configuration files, handling executable and non-executable files differently.
$(TARGET_CONFIG_FILES): $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME)/%: config/% $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME) $(TARGET_CONFIG_FILES): $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME)/%: config/% $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME)
$(TARGET_EXAMPLES_CONFIG_FILES): $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME)/%: config/examples/% $(TARGET_CHROOT)/etc/quadlets/$(PROJECT_NAME) $(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)): $(filter-out %.env, $(TARGET_CONFIG_FILES) $(TARGET_EXAMPLES_CONFIG_FILES)):
@run() { echo $$*; "$$@"; }; \ @run() { echo $$*; "$$@"; }; \
set -Eeuo pipefail; \
if [ -x $< ]; then \ if [ -x $< ]; then \
run install -D -m 0755 -o $(PROJECT_UID) -g $(PROJECT_GID) $< $@; \ run install -D -m 0755 -o $(PROJECT_UID) -g $(PROJECT_GID) $< $@; \
else \ else \
run install -D -m 0644 -o $(PROJECT_UID) -g $(PROJECT_GID) $< $@; \ run install -D -m 0644 -o $(PROJECT_UID) -g $(PROJECT_GID) $< $@; \
fi fi
# Handle .env files separately to set more restrictive permissions
$(filter %.env, $(TARGET_CONFIG_FILES) $(TARGET_EXAMPLES_CONFIG_FILES)): $(filter %.env, $(TARGET_CONFIG_FILES) $(TARGET_EXAMPLES_CONFIG_FILES)):
install -m 0600 -o root -g root -D $< $@ install -m 0600 -o root -g root -D $< $@
# Copy tmpfiles.d files
$(TARGET_TMPFILESD_FILES): $(TARGET_CHROOT)/etc/tmpfiles.d/%: tmpfiles.d/% $(TARGET_CHROOT)/etc/tmpfiles.d $(TARGET_TMPFILESD_FILES): $(TARGET_CHROOT)/etc/tmpfiles.d/%: tmpfiles.d/% $(TARGET_CHROOT)/etc/tmpfiles.d
$(TARGET_EXAMPLES_TMPFILESD_FILES): $(TARGET_CHROOT)/etc/tmpfiles.d/%: tmpfiles.d/examples/% $(TARGET_CHROOT)/etc/tmpfiles.d $(TARGET_EXAMPLES_TMPFILESD_FILES): $(TARGET_CHROOT)/etc/tmpfiles.d/%: tmpfiles.d/examples/% $(TARGET_CHROOT)/etc/tmpfiles.d
$(TARGET_TMPFILESD_FILES) $(TARGET_EXAMPLES_TMPFILESD_FILES): $(TARGET_TMPFILESD_FILES) $(TARGET_EXAMPLES_TMPFILESD_FILES):
install -D -m 0644 -o root -g root $< $@ install -D -m 0644 -o root -g root $< $@
# Copy sysctl.d files
$(TARGET_SYSCTLD_FILES): $(TARGET_CHROOT)/etc/sysctl.d/%: sysctl.d/% $(TARGET_CHROOT)/etc/sysctl.d $(TARGET_SYSCTLD_FILES): $(TARGET_CHROOT)/etc/sysctl.d/%: sysctl.d/% $(TARGET_CHROOT)/etc/sysctl.d
$(TARGET_EXAMPLES_SYSCTLD_FILES): $(TARGET_CHROOT)/etc/sysctl.d/%: sysctl.d/examples/% $(TARGET_CHROOT)/etc/sysctl.d $(TARGET_EXAMPLES_SYSCTLD_FILES): $(TARGET_CHROOT)/etc/sysctl.d/%: sysctl.d/examples/% $(TARGET_CHROOT)/etc/sysctl.d
$(TARGET_SYSCTLD_FILES) $(TARGET_EXAMPLES_SYSCTLD_FILES): $(TARGET_SYSCTLD_FILES) $(TARGET_EXAMPLES_SYSCTLD_FILES):
install -D -m 0644 -o root -g root $< $@ install -D -m 0644 -o root -g root $< $@
# Create the directory to store quadlet state and data.
$(TARGET_CHROOT)/var/lib/quadlets/$(PROJECT_NAME): $(TARGET_CHROOT)/var/lib/quadlets/$(PROJECT_NAME):
install -d -m 0755 -o $(PROJECT_UID) -g $(PROJECT_GID) $@ install -d -m 0755 -o $(PROJECT_UID) -g $(PROJECT_GID) $@
# Copy all configuration files provided by this project.
install-config: $(TARGET_FILES) $(TARGET_CHROOT)/var/lib/quadlets/$(PROJECT_NAME) install-config: $(TARGET_FILES) $(TARGET_CHROOT)/var/lib/quadlets/$(PROJECT_NAME)
# Copy all example configuration files provided by this project.
install-examples: $(TARGET_EXAMPLE_FILES) $(TARGET_CHROOT)/var/lib/quadlets/$(PROJECT_NAME) install-examples: $(TARGET_EXAMPLE_FILES) $(TARGET_CHROOT)/var/lib/quadlets/$(PROJECT_NAME)
# Copy all quadlets and systemd files provided by this project.
install-files: install-files-pre install-config install-examples
$(MAKE) install-files-post
# Custom commands to be run before copying quadlets and systemd files.
# This target can be extended by Makefiles sourcing this one.
install-files-pre:: install-files-pre::
@run() { echo $$*; "$$@"; }; \ @run() { echo $$*; "$$@"; }; \
set -Eeuo pipefail; \
for dep in $(DEPENDENCIES); do \ for dep in $(DEPENDENCIES); do \
run $(MAKE) -C $(TOP_LEVEL_DIR)/$$dep install-files; \ run $(MAKE) -C $(TOP_LEVEL_DIR)/$$dep install-files; \
done done
install-files: install-files-pre install-config install-examples
$(MAKE) install-files-post # Custom commands to be run after copying quadlets and systemd files.
# This target can be extended by Makefiles sourcing this one.
install-files-post:: install-files-post::
install-actions-pre:: # Perform post-installation actions such as enabling and starting units.
@run() { echo $$*; "$$@"; }; \
for dep in $(DEPENDENCIES); do \
run $(MAKE) -C $(TOP_LEVEL_DIR)/$$dep install-actions; \
done
install-actions: install-actions-pre install-actions: install-actions-pre
systemctl daemon-reload systemctl daemon-reload
systemd-analyze --generators=true verify $(QUADLET_UNIT_NAMES) $(SYSTEMD_UNIT_NAMES) systemd-analyze --generators=true verify $(QUADLET_UNIT_NAMES) $(SYSTEMD_UNIT_NAMES)
@run() { echo $$*; "$$@"; }; \ @run() { echo $$*; "$$@"; }; \
set -Eeuo pipefail; \
if [ -f /etc/tmpfiles.d/$(PROJECT_NAME).conf ]; then \ if [ -f /etc/tmpfiles.d/$(PROJECT_NAME).conf ]; then \
run systemd-tmpfiles --create /etc/tmpfiles.d/$(PROJECT_NAME).conf; \ run systemd-tmpfiles --create /etc/tmpfiles.d/$(PROJECT_NAME).conf; \
fi; \ fi; \
@ -143,24 +220,39 @@ install-actions: install-actions-pre
systemctl start $(SYSTEMD_MAIN_UNIT_NAMES) systemctl start $(SYSTEMD_MAIN_UNIT_NAMES)
$(MAKE) install-actions-post $(MAKE) install-actions-post
install-pre:: # Custom commands to be run before performing post-installation actions.
install-post:: # 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
# Custom commands to be run after performing post-installation actions.
# This target can be extended by Makefiles sourcing this one.
install-actions-post::
# Install all quadlets and systemd units provided by this project.
install: pre-requisites dryrun install-pre install: pre-requisites dryrun install-pre
$(MAKE) install-files $(MAKE) install-files
$(MAKE) install-actions $(MAKE) install-actions
$(MAKE) install-post $(MAKE) install-post
uninstall-pre:: # Custom commands to be run before installing quadlets and systemd units.
uninstall-post:: # This target can be extended by Makefiles sourcing this one.
@run() { echo $$*; "$$@"; }; \ install-pre::
for dep in $(DEPENDENCIES); do \
run $(MAKE) -C $(TOP_LEVEL_DIR)/$$dep uninstall; \
done
# Custom commands to be run after installing quadlets and systemd units.
# This target can be extended by Makefiles sourcing this one.
install-post::
# Uninstall all quadlets and systemd units installed by this project.
uninstall: pre-requisites uninstall-pre uninstall: pre-requisites uninstall-pre
systemctl disable $(SYSTEMD_MAIN_UNIT_NAMES) $(SYSTEMD_TIMER_NAMES) || true systemctl disable $(SYSTEMD_MAIN_UNIT_NAMES) $(SYSTEMD_TIMER_NAMES) || true
systemctl stop $(SYSTEMD_UNIT_NAMES) $(QUADLET_UNIT_NAMES) || true systemctl stop $(SYSTEMD_UNIT_NAMES) $(QUADLET_UNIT_NAMES) || true
@run() { echo $$*; "$$@"; }; \ @run() { echo $$*; "$$@"; }; \
set -Eeuo pipefail; \
if [ -f /etc/tmpfiles.d/$(PROJECT_NAME).conf ]; then \ if [ -f /etc/tmpfiles.d/$(PROJECT_NAME).conf ]; then \
run systemd-tmpfiles --purge /etc/tmpfiles.d/$(PROJECT_NAME).conf; \ run systemd-tmpfiles --purge /etc/tmpfiles.d/$(PROJECT_NAME).conf; \
fi fi
@ -168,68 +260,94 @@ uninstall: pre-requisites uninstall-pre
systemctl daemon-reload systemctl daemon-reload
$(MAKE) uninstall-post $(MAKE) uninstall-post
# Custom commands to be run before uninstalling quadlets and systemd units.
# This target can be extended by Makefiles sourcing this one.
uninstall-pre::
# Custom commands to be run after uninstalling quadlets and systemd units.
# 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
# Tail the logs of all units managed by this project.
tail-logs: pre-requisites tail-logs: pre-requisites
@run() { echo $$*; "$$@"; }; \ @run() { echo $$*; "$$@"; }; \
set -Eeuo pipefail; \
declare -a journalctl_args=( -f ); \ declare -a journalctl_args=( -f ); \
for unit in $$($(MAKE) -s units 2>/dev/null | sort -u); do \ for unit in $$($(MAKE) -s units 2>/dev/null | sort -u); do \
journalctl_args+=( -u "$$unit" ); \ journalctl_args+=( -u "$$unit" ); \
done; \ done; \
run journalctl "$${journalctl_args[@]}" run journalctl "$${journalctl_args[@]}"
$(PROJECT_NAME).bu: install-config # Ensure that required variables are set before building Butane specifications.
@if [ -z "$(TARGET_CHROOT)" ]; then \ butane-prerequisites:
echo "TARGET_CHROOT 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
$(PROJECT_NAME)-examples.bu: install-examples
@if [ -z "$(TARGET_CHROOT)" ]; then \ @if [ -z "$(TARGET_CHROOT)" ]; then \
echo "TARGET_CHROOT is not set!"; exit 1; \ echo "TARGET_CHROOT is not set!"; exit 1; \
fi; \
if [ -z "$(BUTANE_BLOCKLIST)" ]; then \
echo "BUTANE_BLOCKLIST is not set!"; exit 1; \
fi fi
$(TOP_LEVEL_DIR)/generate-butane-spec.sh $(TARGET_CHROOT) butane.blocklist > $(PROJECT_NAME)-examples.bu
$(PROJECT_NAME).ign: butane
butane --strict -o $(PROJECT_NAME).ign $(PROJECT_NAME).bu
butane --strict -o $(PROJECT_NAME)-examples.ign $(PROJECT_NAME)-examples.bu
butane: # 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: YQ_FILES := $(shell if [ -f "overlay.bu" ]; then echo "- overlay.bu"; else echo "-"; fi)
$(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) | yq eval-all '. as $$item ireduce ({}; . *+ $$item)' $(YQ_FILES) > $(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)"
# 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 + Ignition files suitable for Fedora CoreOS of the dependencies of this project.
butane-pre:: butane-prerequisites
@run() { echo $$*; "$$@"; }; \ @run() { echo $$*; "$$@"; }; \
init_butane_blocklist() { \ set -Eeuo pipefail; \
(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; \ for dep in base $(DEPENDENCIES); do \
}; \ if [[ "$$dep" == "$(PROJECT_NAME)" ]]; then \
if [ -z "$(TARGET_CHROOT)" ]; then \ # Avoid building the current project as its own dependency. \
TARGET_CHROOT=$$(mktemp -d /tmp/butane-XXXXXX); \ continue; \
else \
TARGET_CHROOT="$(TARGET_CHROOT)"; \
fi ; \ fi ; \
for dep in $(DEPENDENCIES); do \ run $(MAKE) -C $(TOP_LEVEL_DIR)/$$dep $$dep.ign $$dep-examples.ign ; \
run $(MAKE) -C $(TOP_LEVEL_DIR)/$$dep TARGET_CHROOT="$$TARGET_CHROOT" butane ; \ done
done ; \
run init_butane_blocklist ; \ # Generate the current project's Ignition files from the Butane specs.
run $(MAKE) TARGET_CHROOT="$$TARGET_CHROOT" $(PROJECT_NAME).bu; \ $(PROJECT_NAME).ign $(PROJECT_NAME)-examples.ign: butane-pre
run init_butane_blocklist ; \ $(PROJECT_NAME).ign $(PROJECT_NAME)-examples.ign: %.ign: %.bu
run $(MAKE) TARGET_CHROOT="$$TARGET_CHROOT" $(PROJECT_NAME)-examples.bu; \ butane --strict -o $@ $<
if [ -z "$(TARGET_CHROOT)" ]; then \
run rm -rf "$$TARGET_CHROOT"; \
fi
# 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 $(TOP_LEVEL_DIR)/local.ign: $(TOP_LEVEL_DIR)/local.bu
butane --strict -o $@ $< butane --strict -o $@ $<
# 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. # Build the ignition files of the dependencies of this project.
.PHONY: $(DEPENDENCIES_IGNITION_FILES)
$(DEPENDENCIES_IGNITION_FILES): $(DEPENDENCIES_IGNITION_FILES):
$(MAKE) -C $(dir $@) $(notdir $@) $(MAKE) -C $(dir $@) $(notdir $@)
# The file might exist already, declare it as phony and let the child Makefile handle it.
.PHONY: $(DEPENDENCIES_IGNITION_FILES)
fcos.ign: fcos.bu $(TOP_LEVEL_DIR)/local.ign $(PROJECT_NAME).ign $(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 $(PROJECT_NAME)-examples.ign $(DEPENDENCIES_IGNITION_FILES)
@run() { echo $$*; "$$@"; }; \ @run() { echo $$*; "$$@"; }; \
set -Eeuo pipefail; \
tmp=$$(mktemp -d /tmp/butane-XXXXXX); \ tmp=$$(mktemp -d /tmp/butane-XXXXXX); \
run cp $(filter %.ign,$^) $$tmp; \ run cp $(filter %.ign,$^) $$tmp; \
run butane --strict -d $$tmp -o $@ fcos.bu; \ run butane --strict -d $$tmp -o $@ fcos.bu; \
run rm -rf $$tmp run rm -rf $$tmp
# Fetch the latest version of the Fedora CoreOS QCOW2 image.
/var/lib/libvirt/images/library/fedora-coreos.qcow2: /var/lib/libvirt/images/library/fedora-coreos.qcow2:
@run() { echo $$*; "$$@"; }; \ @run() { echo $$*; "$$@"; }; \
set -Eeuo pipefail; \
run mkdir -p /var/lib/libvirt/images/library/ ; \ 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 \ 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; \ echo "CoreOS QCOW2 image could not be downloaded." >&2; \
@ -238,52 +356,87 @@ 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) ; \ qcow2=$$(ls -1ctr /var/lib/libvirt/images/library/fedora-coreos-*.qcow2 | tail -n 1) ; \
run mv "$$qcow2" $@ run mv "$$qcow2" $@
# Copy the ignition file.
/var/lib/libvirt/images/fcos-$(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 $< $@ install -D -o root -g root -m 0644 $< $@
# Copy the Fedora CoreOS base image to create a new QCOW2 image for the VM.
/var/lib/libvirt/images/fcos-$(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 $< $@ 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): /srv/fcos-$(PROJECT_NAME):
install -d -o root -g root -m 0755 $@ 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) # 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 /var/lib/libvirt/images/fcos-$(PROJECT_NAME)/var.qcow2 /srv/fcos-$(PROJECT_NAME)
virt-install --name=fcos-$(PROJECT_NAME) --import --noautoconsole \ virt-install --name=fcos-$(PROJECT_NAME) --import --noautoconsole \
--ram=4096 --vcpus=2 --os-variant=fedora-coreos-stable \ --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)/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" \ --qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=/var/lib/libvirt/images/fcos-$(PROJECT_NAME)/fcos.ign" \
--network network=default,model=virtio \ --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 \ --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 --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 but keep its storage resources.
clean-vm: pre-requisites clean-vm: pre-requisites
virsh destroy fcos-$(PROJECT_NAME) || true virsh destroy fcos-$(PROJECT_NAME) || true
virsh undefine fcos-$(PROJECT_NAME) --nvram || 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 /var/lib/libvirt/images/fcos-$(PROJECT_NAME)
rm -rf /srv/fcos-$(PROJECT_NAME) rm -rf /srv/fcos-$(PROJECT_NAME)
# Connect to the console of the Fedora CoreOS VM.
console: pre-requisites 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 \
# 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:: units-pre::
@for dep in $(DEPENDENCIES); do \ @for dep in $(DEPENDENCIES); do \
$(MAKE) -s -C $(TOP_LEVEL_DIR)/$$dep units 2>/dev/null; \ $(MAKE) -s -C $(TOP_LEVEL_DIR)/$$dep units 2>/dev/null; \
done done
# List all systemd and quadlet unit names provided by this project and, through "units-pre", also its dependencies.
units: units-pre units: units-pre
@for unit in $(SYSTEMD_UNIT_NAMES) $(QUADLET_UNIT_NAMES); do echo "$$unit"; done @for unit in $(SYSTEMD_UNIT_NAMES) $(QUADLET_UNIT_NAMES); do echo "$$unit"; done
# Custom commands to be run before cleaning persistent data and configuration files.
# This target can be extended by Makefiles sourcing this one.
clean-pre:: clean-pre::
@run() { echo $$*; "$$@"; }; \ @run() { echo $$*; "$$@"; }; \
set -Eeuo pipefail; \
for dep in $(DEPENDENCIES); do \ for dep in $(DEPENDENCIES); do \
run $(MAKE) -C $(TOP_LEVEL_DIR)/$$dep clean; \ run $(MAKE) -C $(TOP_LEVEL_DIR)/$$dep clean; \
done done
# Custom commands to be run after cleaning persistent data and configuration files.
# This target can be extended by Makefiles sourcing this one.
clean-post:: clean-post::
# Remove all persistent data and configuration files
clean: clean-pre pre-requisites clean: clean-pre pre-requisites
rm -f *.butane rm -f $(PROJECT_NAME){,-examples}.bu *.ign butane.blocklist
@run() { echo $$*; "$$@"; }; \ @run() { echo $$*; "$$@"; }; \
set -Eeuo pipefail; \
if [ "$(I_KNOW_WHAT_I_AM_DOING)" != "yes" ]; then \ 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; \ read -p "This will remove all data of '$(PROJECT_NAME)'. Are you sure? (only 'yes' is accepted) " ans; \
if [ "$$ans" != "yes" ] && [ "$$ans" != "YES" ]; then \ if [ "$$ans" != "yes" ] && [ "$$ans" != "YES" ]; then \
@ -292,3 +445,10 @@ clean: clean-pre pre-requisites
fi fi
rm -rf /var/lib/quadlets/$(PROJECT_NAME)/ /var/run/quadlets/$(PROJECT_NAME)/ /etc/quadlets/$(PROJECT_NAME)/ rm -rf /var/lib/quadlets/$(PROJECT_NAME)/ /var/run/quadlets/$(PROJECT_NAME)/ /etc/quadlets/$(PROJECT_NAME)/
$(MAKE) clean-post $(MAKE) clean-post
# 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 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 butane-prerequisites butane-pre

3
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

8
base/fcos.bu

@ -0,0 +1,8 @@
variant: fcos
version: 1.4.0
ignition:
config:
merge:
- local: base.ign
- local: base-examples.ign
- local: local.ign

43
base/overlay.bu

@ -0,0 +1,43 @@
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'

20
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

0
virtiofs/tmpfiles.d/virtiofs.conf → base/tmpfiles.d/base.conf

4
virtiofs/var-lib-virtiofs-data.mount → base/var-lib-virtiofs-data.mount

@ -1,9 +1,5 @@
[Unit] [Unit]
Description=Mount the "data" virtio filesystem 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 # Only run on Fedora CoreOS
ConditionOSRelease=ID=fedora ConditionOSRelease=ID=fedora

3
generate-butane-spec.sh

@ -9,6 +9,9 @@
# It takes the following parameters: # It takes the following parameters:
# - The target chroot directory where the quadlets and systemd units # - The target chroot directory where the quadlets and systemd units
# have been installed. # have been installed.
# - The path to a file containing a list of files and directories
# (one per line) to ignore (i.e., files and directories that are
# already part of the CoreOS default installation).
# - The list of systemd main unit names to enable. # - The list of systemd main unit names to enable.
# #
# It outputs the butane config file to stdout. # It outputs the butane config file to stdout.

101
nextcloud-aio/examples/config.env

@ -1,101 +0,0 @@
# Setting this to true allows to hide the backup section in the AIO interface.
# See https://github.com/nextcloud/all-in-one#how-to-disable-the-backup-section
#AIO_DISABLE_BACKUP_SECTION=false
# Is needed when running behind a web server or reverse proxy (like Apache, Nginx, Caddy, Cloudflare Tunnel and else).
# See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
#APACHE_PORT=11000
# Should be set when running behind a web server or reverse proxy (like Apache, Nginx, Caddy, Cloudflare Tunnel and else) that is running on the same host.
# See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
#APACHE_IP_BINDING=127.0.0.1
# (Optional) Connect the apache container to an additional docker network.
# Needed when behind a web server or reverse proxy (like Apache, Nginx, Caddy, Cloudflare Tunnel and else) running in a different docker network on same server.
# See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
#APACHE_ADDITIONAL_NETWORK=frontend_net
# Allows to adjust borgs retention policy.
# See https://github.com/nextcloud/all-in-one#how-to-adjust-borgs-retention-policy
#BORG_RETENTION_POLICY=--keep-within=7d --keep-weekly=4 --keep-monthly=6
# Setting this to true allows to disable Collabora's Seccomp feature.
# See https://github.com/nextcloud/all-in-one#how-to-disable-collaboras-seccomp-feature
#COLLABORA_SECCOMP_DISABLED=false
# You can adjust the internally used docker api version with this variable.
# ⚠️⚠️⚠️ Warning: please note that only the default api version (unset this variable) is supported and tested by the maintainers of Nextcloud AIO.
# So use this on your own risk and things might break without warning.
# See https://github.com/nextcloud/all-in-one#how-to-adjust-the-internally-used-docker-api-version
#DOCKER_API_VERSION=1.44
# Allows to adjust the fulltextsearch java options.
# See https://github.com/nextcloud/all-in-one#how-to-adjust-the-fulltextsearch-java-options
#FULLTEXTSEARCH_JAVA_OPTIONS=-Xms1024M -Xmx1024M
# Allows to set the host directory for Nextcloud's datadir.
# ⚠️⚠️⚠️ Warning: do not set or adjust this value after the initial Nextcloud installation is done!
# See https://github.com/nextcloud/all-in-one#how-to-change-the-default-location-of-nextclouds-datadir
NEXTCLOUD_DATADIR=/var/lib/quadlets/nextcloud-aio/data
# Allows the Nextcloud container to access the chosen directory on the host.
# See https://github.com/nextcloud/all-in-one#how-to-allow-the-nextcloud-container-to-access-directories-on-the-host
#NEXTCLOUD_MOUNT=/mnt/
# Can be adjusted if you need more.
# See https://github.com/nextcloud/all-in-one#how-to-adjust-the-upload-limit-for-nextcloud
#NEXTCLOUD_UPLOAD_LIMIT=16G
# Can be adjusted if you need more.
# See https://github.com/nextcloud/all-in-one#how-to-adjust-the-max-execution-time-for-nextcloud
#NEXTCLOUD_MAX_TIME=3600
# Can be adjusted if you need more.
# See https://github.com/nextcloud/all-in-one#how-to-adjust-the-php-memory-limit-for-nextcloud
#NEXTCLOUD_MEMORY_LIMIT=512M
# CA certificates in this directory will be trusted by the OS of the nextcloud container (Useful e.g. for LDAPS).
# See https://github.com/nextcloud/all-in-one#how-to-trust-user-defined-certification-authorities-ca
#NEXTCLOUD_TRUSTED_CACERTS_DIR=/path/to/my/cacerts
# Allows to modify the Nextcloud apps that are installed on starting AIO the first time.
# See https://github.com/nextcloud/all-in-one#how-to-change-the-nextcloud-apps-that-are-installed-on-the-first-startup
#NEXTCLOUD_STARTUP_APPS=deck twofactor_totp tasks calendar contacts notes
# This allows to add additional packages to the Nextcloud container permanently.
# Default is imagemagick but can be overwritten by modifying this value.
# See https://github.com/nextcloud/all-in-one#how-to-add-os-packages-permanently-to-the-nextcloud-container
#NEXTCLOUD_ADDITIONAL_APKS=imagemagick
# This allows to add additional php extensions to the Nextcloud container permanently.
# Default is imagick but can be overwritten by modifying this value.
# See https://github.com/nextcloud/all-in-one#how-to-add-php-extensions-permanently-to-the-nextcloud-container
#NEXTCLOUD_ADDITIONAL_PHP_EXTENSIONS=imagick
# This allows to enable the /dev/dri device for containers that profit from it.
# ⚠️⚠️⚠️ Warning: this only works if the '/dev/dri' device is present on the host!
# If it should not exist on your host, don't set this to true as otherwise the Nextcloud container will fail to start!
# See https://github.com/nextcloud/all-in-one#how-to-enable-hardware-acceleration-for-nextcloud
#NEXTCLOUD_ENABLE_DRI_DEVICE=true
# This allows to enable the NVIDIA runtime and GPU access for containers that profit from it.
# ⚠️⚠️⚠️ Warning: this only works if an NVIDIA gpu is installed on the server.
# See https://github.com/nextcloud/all-in-one#how-to-enable-hardware-acceleration-for-nextcloud.
#NEXTCLOUD_ENABLE_NVIDIA_GPU=true
# Setting this to true will keep Nextcloud apps that are disabled in the AIO interface and not uninstall them if they should be installed.
# See https://github.com/nextcloud/all-in-one#how-to-keep-disabled-apps
#NEXTCLOUD_KEEP_DISABLED_APPS=false
# This should only be set to true if things are correctly configured.
# See https://github.com/nextcloud/all-in-one#how-to-skip-the-domain-validation
#SKIP_DOMAIN_VALIDATION=false
# This allows to adjust the port that the talk container is using which is exposed on the host.
# See https://github.com/nextcloud/all-in-one#how-to-adjust-the-talk-port
#TALK_PORT=3478
# Needs to be specified if the docker socket on the host is not located in the default '/var/run/docker.sock'.
# Otherwise mastercontainer updates will fail.
# For macos it needs to be '/var/run/docker.sock'
#WATCHTOWER_DOCKER_SOCKET_PATH=/var/run/docker.sock

1
nextcloud/Makefile

@ -2,7 +2,6 @@
## Makefile for PostgreSQL quadlet ## Makefile for PostgreSQL quadlet
## ##
# Project dependencies: Nextcloud also depends on virtiofs for data storage but is a transitive dependency via postgresql
DEPENDENCIES = postgresql DEPENDENCIES = postgresql
# Nextcloud quadlet is mapped to the 10008 user (nextcloud) and 10000 group (itix-svc) # Nextcloud quadlet is mapped to the 10008 user (nextcloud) and 10000 group (itix-svc)

2
nextcloud/fcos.bu

@ -3,7 +3,7 @@ version: 1.4.0
ignition: ignition:
config: config:
merge: merge:
- local: virtiofs.ign - local: base.ign
- local: nextcloud.ign - local: nextcloud.ign
- local: nextcloud-examples.ign - local: nextcloud-examples.ign
- local: postgresql.ign - local: postgresql.ign

1
nginx/fcos.bu

@ -3,6 +3,7 @@ version: 1.4.0
ignition: ignition:
config: config:
merge: merge:
- local: base.ign
- local: nginx.ign - local: nginx.ign
- local: nginx-examples.ign - local: nginx-examples.ign
- local: local.ign - local: local.ign

3
postgresql/Makefile

@ -2,9 +2,6 @@
## Makefile for PostgreSQL quadlet ## Makefile for PostgreSQL quadlet
## ##
# Project dependencies
DEPENDENCIES = virtiofs
# PostgreSQL quadlet is mapped to the 10004 user (postgres) and 10000 group (itix-svc) # PostgreSQL quadlet is mapped to the 10004 user (postgres) and 10000 group (itix-svc)
PROJECT_UID = 10004 PROJECT_UID = 10004
PROJECT_GID = 10000 PROJECT_GID = 10000

2
postgresql/fcos.bu

@ -3,7 +3,7 @@ version: 1.4.0
ignition: ignition:
config: config:
merge: merge:
- local: virtiofs.ign - local: base.ign
- local: postgresql.ign - local: postgresql.ign
- local: postgresql-examples.ign - local: postgresql-examples.ign
- local: local.ign - local: local.ign

8
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/

9
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 []

20
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

9
qemu-user-static/fcos.bu

@ -0,0 +1,9 @@
variant: fcos
version: 1.4.0
ignition:
config:
merge:
- local: base.ign
- local: qemu-user-static.ign
- local: qemu-user-static-examples.ign
- local: local.ign

11
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

10
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

26
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

11
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

3
virtiofs/Makefile

@ -1,3 +0,0 @@
TOP_LEVEL_DIR := ..
include $(TOP_LEVEL_DIR)/Makefile.common
SYSTEMD_MAIN_UNIT_NAMES := var-lib-virtiofs-data.mount

22
virtiofs/backup-virtiofs.service

@ -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

14
virtiofs/fcos.bu

@ -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!

16
virtiofs/restore-virtiofs.service

@ -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
Loading…
Cancel
Save