├── fuse2 ├── .ignore ├── Containerfile ├── justfile └── README.md ├── docs ├── .bundle │ └── config ├── justfile ├── _config_local.yml ├── Gemfile ├── index.md ├── _config.yml └── Gemfile.lock ├── kubernetes-1.31 ├── usr │ └── libexec │ │ └── kubernetes │ │ └── kubelet-plugins │ │ └── volume │ │ └── exec │ │ └── .keep ├── Containerfile ├── README.md └── justfile ├── kubernetes-1.32 ├── usr │ └── libexec │ │ └── kubernetes │ │ └── kubelet-plugins │ │ └── volume │ │ └── exec │ │ └── .keep ├── Containerfile ├── README.md └── justfile ├── kubernetes-1.33 ├── usr │ └── libexec │ │ └── kubernetes │ │ └── kubelet-plugins │ │ └── volume │ │ └── exec │ │ └── .keep ├── Containerfile ├── README.md └── justfile ├── kubernetes-1.34 ├── usr │ └── libexec │ │ └── kubernetes │ │ └── kubelet-plugins │ │ └── volume │ │ └── exec │ │ └── .keep ├── Containerfile ├── README.md └── justfile ├── kubernetes-cri-o-1.31 ├── usr │ └── libexec │ │ └── kubernetes │ │ └── kubelet-plugins │ │ └── volume │ │ └── exec │ │ └── .keep ├── README.md ├── Containerfile └── justfile ├── kubernetes-cri-o-1.32 ├── usr │ └── libexec │ │ └── kubernetes │ │ └── kubelet-plugins │ │ └── volume │ │ └── exec │ │ └── .keep ├── README.md ├── Containerfile └── justfile ├── kubernetes-cri-o-1.33 ├── usr │ └── libexec │ │ └── kubernetes │ │ └── kubelet-plugins │ │ └── volume │ │ └── exec │ │ └── .keep ├── README.md ├── Containerfile └── justfile ├── kubernetes-cri-o-1.34 ├── usr │ └── libexec │ │ └── kubernetes │ │ └── kubelet-plugins │ │ └── volume │ │ └── exec │ │ └── .keep ├── README.md ├── Containerfile └── justfile ├── iwd ├── usr │ └── lib │ │ └── NetworkManager │ │ └── conf.d │ │ └── wifi_backend.conf ├── justfile ├── Containerfile └── README.md ├── gh ├── justfile ├── Containerfile └── README.md ├── vim ├── justfile ├── README.md └── Containerfile ├── zsh ├── justfile ├── Containerfile └── README.md ├── fish ├── justfile ├── Containerfile └── README.md ├── foot ├── justfile ├── Containerfile └── README.md ├── gdb ├── README.md ├── Containerfile └── justfile ├── helix ├── justfile ├── Containerfile └── README.md ├── htop ├── justfile ├── Containerfile └── README.md ├── iotop ├── justfile ├── Containerfile └── README.md ├── just ├── justfile ├── Containerfile └── README.md ├── kitty ├── justfile ├── README.md └── Containerfile ├── mosh ├── justfile ├── Containerfile └── README.md ├── tmux ├── justfile └── README.md ├── tree ├── justfile ├── Containerfile └── README.md ├── bwm-ng ├── justfile ├── Containerfile └── README.md ├── nebula ├── justfile ├── Containerfile └── README.md ├── strace ├── justfile ├── Containerfile └── README.md ├── zoxide ├── justfile ├── Containerfile └── README.md ├── .github ├── docs-templates │ ├── header.md │ └── body.md ├── workflow-templates │ ├── 15_sysexts_build │ ├── systemd-sysupdate.conf │ ├── containers_logincosign │ ├── 10_sysexts_build_header │ ├── 00_sysexts_header │ ├── containers_pushsign │ ├── containers_build │ ├── 20_sysexts_gather │ ├── containers_header │ └── container_workflows.sh ├── dependabot.yml ├── workflows │ ├── reuse-lint.yml │ └── pages.yml ├── cleanup_docs.sh ├── list_sysexts.sh ├── generate_docs.sh └── actions │ ├── gather │ └── action.yml │ └── build │ └── action.yml ├── fd-find ├── justfile ├── Containerfile └── README.md ├── git-lfs ├── justfile ├── Containerfile └── README.md ├── ripgrep ├── justfile ├── Containerfile └── README.md ├── distrobox ├── justfile ├── Containerfile └── README.md ├── fastfetch ├── justfile ├── Containerfile └── README.md ├── git-absorb ├── justfile ├── Containerfile └── README.md ├── git-delta ├── justfile ├── Containerfile └── README.md ├── keepassxc ├── justfile ├── Containerfile └── README.md ├── erofs-utils ├── justfile ├── Containerfile └── README.md ├── git-email ├── justfile ├── README.md └── Containerfile ├── igt-gpu-tools ├── justfile ├── Containerfile └── README.md ├── qemu-guest-agent ├── README.md ├── usr │ └── lib │ │ └── systemd │ │ └── system │ │ └── qemu-guest-agent.service.d │ │ └── override.conf └── justfile ├── steam-devices ├── justfile ├── Containerfile └── README.md ├── btop ├── justfile ├── Containerfile └── README.md ├── chromium ├── Containerfile ├── README.md └── justfile ├── python3 ├── Containerfile ├── README.md └── justfile ├── inxi ├── README.md └── justfile ├── krb5-workstation ├── justfile ├── Containerfile └── README.md ├── moby-engine ├── Containerfile ├── justfile └── README.md ├── emacs ├── README.md ├── Containerfile └── justfile ├── neovim ├── README.md ├── justfile └── Containerfile ├── libgda ├── justfile ├── Containerfile └── README.md ├── source-foundry-hack-fonts ├── README.md ├── justfile └── Containerfile ├── adobe-source-code-pro-fonts ├── README.md ├── justfile └── Containerfile ├── firefox ├── justfile └── README.md ├── libratbag ├── Containerfile ├── justfile └── README.md ├── semanage ├── Containerfile ├── README.md └── justfile ├── arm-image-installer ├── Containerfile ├── justfile └── README.md ├── incus ├── Containerfile ├── justfile └── README.md ├── WALinuxAgent ├── README.md └── justfile ├── amazon-ec2-utils ├── README.md └── justfile ├── google-guest-agent ├── README.md └── justfile ├── .gitignore ├── libvirtd-desktop ├── Containerfile ├── README.md └── justfile ├── wireshark-kinoite ├── justfile └── README.md ├── wireshark-silverblue ├── justfile └── README.md ├── REUSE.toml ├── libvirtd ├── Containerfile ├── README.md └── justfile ├── LICENSES ├── MIT.txt └── CC0-1.0.txt ├── CONTRIBUTING.md ├── README.containers.md ├── README.md ├── update_workflows.sh └── sysext.just /fuse2/.ignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.bundle/config: -------------------------------------------------------------------------------- 1 | --- 2 | BUNDLE_PATH: "./vendor/gems/" 3 | -------------------------------------------------------------------------------- /kubernetes-1.31/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /kubernetes-1.32/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /kubernetes-1.33/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /kubernetes-1.34/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /kubernetes-cri-o-1.31/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /kubernetes-cri-o-1.32/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /kubernetes-cri-o-1.33/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /kubernetes-cri-o-1.34/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /iwd/usr/lib/NetworkManager/conf.d/wifi_backend.conf: -------------------------------------------------------------------------------- 1 | [device] 2 | wifi.backend=iwd 3 | -------------------------------------------------------------------------------- /gh/justfile: -------------------------------------------------------------------------------- 1 | name := "gh" 2 | packages := "gh" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /vim/justfile: -------------------------------------------------------------------------------- 1 | name := "vim" 2 | packages := "vim" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /zsh/justfile: -------------------------------------------------------------------------------- 1 | name := "zsh" 2 | packages := "zsh" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /fish/justfile: -------------------------------------------------------------------------------- 1 | name := "fish" 2 | packages := "fish" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /foot/justfile: -------------------------------------------------------------------------------- 1 | name := "foot" 2 | packages := "foot" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /gdb/README.md: -------------------------------------------------------------------------------- 1 | # gdb 2 | 3 | ## Compatibility 4 | 5 | This sysext is compatible with Fedora CoreOS only. 6 | -------------------------------------------------------------------------------- /helix/justfile: -------------------------------------------------------------------------------- 1 | name := "helix" 2 | packages := "helix" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /htop/justfile: -------------------------------------------------------------------------------- 1 | name := "htop" 2 | packages := "htop" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /iotop/justfile: -------------------------------------------------------------------------------- 1 | name := "iotop" 2 | packages := "iotop" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /just/justfile: -------------------------------------------------------------------------------- 1 | name := "just" 2 | packages := "just" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /kitty/justfile: -------------------------------------------------------------------------------- 1 | name := "kitty" 2 | packages := "kitty" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /mosh/justfile: -------------------------------------------------------------------------------- 1 | name := "mosh" 2 | packages := "mosh" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /tmux/justfile: -------------------------------------------------------------------------------- 1 | name := "tmux" 2 | packages := "tmux" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /tree/justfile: -------------------------------------------------------------------------------- 1 | name := "tree" 2 | packages := "tree" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /vim/README.md: -------------------------------------------------------------------------------- 1 | # vim 2 | 3 | ## Compatibility 4 | 5 | This sysext is compatible with Fedora Atomic Desktops. 6 | -------------------------------------------------------------------------------- /bwm-ng/justfile: -------------------------------------------------------------------------------- 1 | name := "bwm-ng" 2 | packages := "bwm-ng" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /kitty/README.md: -------------------------------------------------------------------------------- 1 | # kitty 2 | 3 | ## Compatibility 4 | 5 | This sysext is compatible with Fedora Atomic Desktops. 6 | -------------------------------------------------------------------------------- /nebula/justfile: -------------------------------------------------------------------------------- 1 | name := "nebula" 2 | packages := "nebula" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /strace/justfile: -------------------------------------------------------------------------------- 1 | name := "strace" 2 | packages := "strace" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /zoxide/justfile: -------------------------------------------------------------------------------- 1 | name := "zoxide" 2 | packages := "zoxide" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /.github/docs-templates/header.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: %%SYSEXT%% 3 | nav_order: %%NAVORDER%% 4 | --- 5 | 6 | # %%SYSEXT%% 7 | -------------------------------------------------------------------------------- /fd-find/justfile: -------------------------------------------------------------------------------- 1 | name := "fd-find" 2 | packages := "fd-find" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /git-lfs/justfile: -------------------------------------------------------------------------------- 1 | name := "git-lfs" 2 | packages := "git-lfs" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /ripgrep/justfile: -------------------------------------------------------------------------------- 1 | name := "ripgrep" 2 | packages := "ripgrep" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /distrobox/justfile: -------------------------------------------------------------------------------- 1 | name := "distrobox" 2 | packages := "distrobox" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /fastfetch/justfile: -------------------------------------------------------------------------------- 1 | name := "fastfetch" 2 | packages := "fastfetch" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /git-absorb/justfile: -------------------------------------------------------------------------------- 1 | name := "git-absorb" 2 | packages := "git-absorb" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /git-delta/justfile: -------------------------------------------------------------------------------- 1 | name := "git-delta" 2 | packages := "git-delta" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /iwd/justfile: -------------------------------------------------------------------------------- 1 | name := "iwd" 2 | packages := "iwd" 3 | files := "usr" 4 | 5 | import '../sysext.just' 6 | 7 | all: default 8 | -------------------------------------------------------------------------------- /keepassxc/justfile: -------------------------------------------------------------------------------- 1 | name := "keepassxc" 2 | packages := "keepassxc" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /erofs-utils/justfile: -------------------------------------------------------------------------------- 1 | name := "erofs-utils" 2 | packages := "erofs-utils" 3 | 4 | import '../sysext.just' 5 | 6 | all: default 7 | -------------------------------------------------------------------------------- /fish/Containerfile: -------------------------------------------------------------------------------- 1 | FROM baseimage 2 | 3 | RUN < 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | url: "http://127.0.0.1:4000" 5 | -------------------------------------------------------------------------------- /erofs-utils/README.md: -------------------------------------------------------------------------------- 1 | # erofs-utils 2 | 3 | ## Compatibility 4 | 5 | This sysext is compatible with all Fedora variants (CoreOS, Atomic Desktops, 6 | etc.). 7 | -------------------------------------------------------------------------------- /firefox/justfile: -------------------------------------------------------------------------------- 1 | name := "firefox" 2 | packages := " 3 | firefox 4 | firefox-langpacks 5 | " 6 | 7 | import '../sysext.just' 8 | 9 | all: default 10 | -------------------------------------------------------------------------------- /git-absorb/README.md: -------------------------------------------------------------------------------- 1 | # git-absorb 2 | 3 | ## Compatibility 4 | 5 | This sysext is compatible with all Fedora variants (CoreOS, Atomic Desktops, 6 | etc.). 7 | -------------------------------------------------------------------------------- /iwd/Containerfile: -------------------------------------------------------------------------------- 1 | FROM baseimage 2 | 3 | COPY usr usr 4 | 5 | RUN < 4 | 5 | ## Compatibility 6 | 7 | This sysext is compatible with all Fedora variants (CoreOS, Atomic Desktops, 8 | etc.). 9 | -------------------------------------------------------------------------------- /python3/justfile: -------------------------------------------------------------------------------- 1 | name := "python3" 2 | packages := "python3" 3 | base_images := " 4 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 5 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 6 | " 7 | 8 | import '../sysext.just' 9 | 10 | all: default 11 | -------------------------------------------------------------------------------- /google-guest-agent/README.md: -------------------------------------------------------------------------------- 1 | # google-guest-agent 2 | 3 | `google-compute-engine-guest-configs`, `google-compute-engine-oslogin` and 4 | `google-guest-agent` for integration in GCP. 5 | 6 | ## Compatibility 7 | 8 | This sysext is compatible with Fedora CoreOS only. 9 | -------------------------------------------------------------------------------- /iwd/README.md: -------------------------------------------------------------------------------- 1 | # iwd 2 | 3 | Better WiFi daemon and config for NetworkManager to use it by default. 4 | 5 | ## Compatibility 6 | 7 | This sysext should be compatible with all Fedora variants (CoreOS, Atomic 8 | Desktops, etc.) but has only been tested on Atomic Desktops. 9 | -------------------------------------------------------------------------------- /keepassxc/README.md: -------------------------------------------------------------------------------- 1 | # keepassxc 2 | 3 | Alternative to the Flatpak which has known limitations. 4 | 5 | ## Compatibility 6 | 7 | This sysext should be compatible with all Fedora variants (CoreOS, Atomic 8 | Desktops, etc.) but has only been tested on Atomic Desktops. 9 | -------------------------------------------------------------------------------- /semanage/justfile: -------------------------------------------------------------------------------- 1 | name := "semanage" 2 | packages := "policycoreutils-python-utils" 3 | base_images := " 4 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 5 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 6 | " 7 | 8 | import '../sysext.just' 9 | 10 | all: default 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Timothée Ravier 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | rootfs/ 5 | binaries/ 6 | *.erofs 7 | *.raw 8 | *.rpm 9 | version 10 | version_id 11 | inputs 12 | digest 13 | scripts 14 | json 15 | /.dnf-cache/ 16 | /docs/*/ 17 | -------------------------------------------------------------------------------- /kubernetes-cri-o-1.31/README.md: -------------------------------------------------------------------------------- 1 | # kubernetes-cri-o-1.31 2 | 3 | Kubernetes and CRI-O packages in a single system extension. 4 | 5 | For Kubernetes only, see the `kubernetes-` ones. 6 | 7 | ## Compatibility 8 | 9 | This sysext is compatible with Fedora CoreOS only. 10 | -------------------------------------------------------------------------------- /kubernetes-cri-o-1.32/README.md: -------------------------------------------------------------------------------- 1 | # kubernetes-cri-o-1.32 2 | 3 | Kubernetes and CRI-O packages in a single system extension. 4 | 5 | For Kubernetes only, see the `kubernetes-` ones. 6 | 7 | ## Compatibility 8 | 9 | This sysext is compatible with Fedora CoreOS only. 10 | -------------------------------------------------------------------------------- /kubernetes-cri-o-1.33/README.md: -------------------------------------------------------------------------------- 1 | # kubernetes-cri-o-1.33 2 | 3 | Kubernetes and CRI-O packages in a single system extension. 4 | 5 | For Kubernetes only, see the `kubernetes-` ones. 6 | 7 | ## Compatibility 8 | 9 | This sysext is compatible with Fedora CoreOS only. 10 | -------------------------------------------------------------------------------- /kubernetes-cri-o-1.34/README.md: -------------------------------------------------------------------------------- 1 | # kubernetes-cri-o-1.34 2 | 3 | Kubernetes and CRI-O packages in a single system extension. 4 | 5 | For Kubernetes only, see the `kubernetes-` ones. 6 | 7 | ## Compatibility 8 | 9 | This sysext is compatible with Fedora CoreOS only. 10 | -------------------------------------------------------------------------------- /firefox/README.md: -------------------------------------------------------------------------------- 1 | # firefox 2 | 3 | Enables use on dowstream images such as Bazzite and Bluefin which remove Firefox. 4 | 5 | ## Compatibility 6 | 7 | This sysext should be compatible with all Fedora Atomic Desktops but mainly 8 | targets Universal Blue images that remove Firefox from the image. 9 | -------------------------------------------------------------------------------- /nebula/README.md: -------------------------------------------------------------------------------- 1 | # nebula 2 | 3 | `nebula` is a scalable overlay networking tool with a focus on performance, simplicity and security. 4 | 5 | ## Compatibility 6 | 7 | This sysext should be compatible with all Fedora variants (CoreOS, Atomic 8 | Desktops, etc.) but has only been tested on Atomic Desktops. 9 | -------------------------------------------------------------------------------- /WALinuxAgent/justfile: -------------------------------------------------------------------------------- 1 | name := "WALinuxAgent" 2 | packages := " 3 | WALinuxAgent 4 | azure-vm-utils 5 | hyperv-daemons 6 | " 7 | base_images := " 8 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 9 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 10 | " 11 | 12 | import '../sysext.just' 13 | 14 | all: default 15 | -------------------------------------------------------------------------------- /incus/README.md: -------------------------------------------------------------------------------- 1 | # incus 2 | 3 | See: 4 | - 5 | - 6 | 7 | ## Compatibility 8 | 9 | This sysext should be compatible with all Fedora variants (CoreOS, Atomic 10 | Desktops, etc.). 11 | -------------------------------------------------------------------------------- /amazon-ec2-utils/justfile: -------------------------------------------------------------------------------- 1 | name := "amazon-ec2-utils" 2 | packages := " 3 | amazon-ec2-utils 4 | awscli2 5 | ec2-instance-connect 6 | " 7 | base_images := " 8 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 9 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 10 | " 11 | 12 | import '../sysext.just' 13 | 14 | all: default 15 | -------------------------------------------------------------------------------- /kubernetes-1.31/Containerfile: -------------------------------------------------------------------------------- 1 | FROM baseimage 2 | 3 | ARG VERSION=1.31 4 | 5 | RUN < 6 | 7 | ## Compatibility 8 | 9 | Note that this sysext is currently not needed as the Fedora Atomic Desktops 10 | still include the `fuse2` libraries and binaries by default. 11 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Timothée Ravier 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | version: 2 5 | updates: 6 | - package-ecosystem: "github-actions" 7 | directory: "/" 8 | schedule: 9 | interval: "weekly" 10 | groups: 11 | actions: 12 | patterns: 13 | - "*" 14 | -------------------------------------------------------------------------------- /qemu-guest-agent/justfile: -------------------------------------------------------------------------------- 1 | name := "qemu-guest-agent" 2 | packages := "qemu-guest-agent" 3 | upholds := " 4 | qemu-guest-agent.service 5 | " 6 | files := "usr" 7 | base_images := " 8 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 9 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 10 | " 11 | 12 | import '../sysext.just' 13 | 14 | all: default 15 | -------------------------------------------------------------------------------- /kubernetes-cri-o-1.31/Containerfile: -------------------------------------------------------------------------------- 1 | FROM baseimage 2 | 3 | ARG VERSION=1.31 4 | 5 | RUN < 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | source 'https://rubygems.org' 5 | 6 | gem "jekyll", "~> 4.3" 7 | gem "just-the-docs" 8 | gem "webrick", "~> 1.8" 9 | 10 | gem 'jekyll-remote-theme', '~> 0.4.3' 11 | 12 | # Silence warnings 13 | gem "logger" 14 | gem "csv" 15 | gem "ostruct" 16 | gem "base64" 17 | -------------------------------------------------------------------------------- /.github/workflow-templates/systemd-sysupdate.conf: -------------------------------------------------------------------------------- 1 | [Transfer] 2 | Verify=false 3 | 4 | [Source] 5 | Type=url-file 6 | Path=https://extensions.fcos.fr/fedora/%%SYSEXT%%/ 7 | MatchPattern=%%SYSEXT%%-@v-%w-%a.raw 8 | 9 | [Target] 10 | InstancesMax=2 11 | Type=regular-file 12 | Path=/var/lib/extensions.d/ 13 | MatchPattern=%%SYSEXT%%-@v-%w-%a.raw 14 | CurrentSymlink=/var/lib/extensions/%%SYSEXT%%.raw 15 | -------------------------------------------------------------------------------- /google-guest-agent/justfile: -------------------------------------------------------------------------------- 1 | name := "google-guest-agent" 2 | packages := " 3 | google-compute-engine-guest-configs 4 | google-compute-engine-oslogin 5 | google-guest-agent 6 | " 7 | upholds := " 8 | google-guest-agent.service 9 | " 10 | base_images := " 11 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 12 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 13 | " 14 | 15 | import '../sysext.just' 16 | 17 | all: default 18 | -------------------------------------------------------------------------------- /kubernetes-1.31/README.md: -------------------------------------------------------------------------------- 1 | # kubernetes-1.31 2 | 3 | Kubernetes packages and direct dependencies only. Needs to be combined with a 4 | container runtime such as `containerd`, either from Fedora's packages or the 5 | `docker-ce` sysext. 6 | 7 | For Kubernetes and CRI-O in a single system extension, see `kubernetes-cri-o-` ones. 8 | 9 | ## Compatibility 10 | 11 | This sysext is compatible with Fedora CoreOS only. 12 | -------------------------------------------------------------------------------- /kubernetes-1.32/README.md: -------------------------------------------------------------------------------- 1 | # kubernetes-1.32 2 | 3 | Kubernetes packages and direct dependencies only. Needs to be combined with a 4 | container runtime such as `containerd`, either from Fedora's packages or the 5 | `docker-ce` sysext. 6 | 7 | For Kubernetes and CRI-O in a single system extension, see `kubernetes-cri-o-` ones. 8 | 9 | ## Compatibility 10 | 11 | This sysext is compatible with Fedora CoreOS only. 12 | -------------------------------------------------------------------------------- /kubernetes-1.33/README.md: -------------------------------------------------------------------------------- 1 | # kubernetes-1.33 2 | 3 | Kubernetes packages and direct dependencies only. Needs to be combined with a 4 | container runtime such as `containerd`, either from Fedora's packages or the 5 | `docker-ce` sysext. 6 | 7 | For Kubernetes and CRI-O in a single system extension, see `kubernetes-cri-o-` ones. 8 | 9 | ## Compatibility 10 | 11 | This sysext is compatible with Fedora CoreOS only. 12 | -------------------------------------------------------------------------------- /kubernetes-1.34/README.md: -------------------------------------------------------------------------------- 1 | # kubernetes-1.34 2 | 3 | Kubernetes packages and direct dependencies only. Needs to be combined with a 4 | container runtime such as `containerd`, either from Fedora's packages or the 5 | `docker-ce` sysext. 6 | 7 | For Kubernetes and CRI-O in a single system extension, see `kubernetes-cri-o-` ones. 8 | 9 | ## Compatibility 10 | 11 | This sysext is compatible with Fedora CoreOS only. 12 | -------------------------------------------------------------------------------- /moby-engine/README.md: -------------------------------------------------------------------------------- 1 | # moby-engine 2 | 3 | moby-engine (Docker) from the Fedora repos. 4 | 5 | ## How to use 6 | 7 | - Install the sysext 8 | - Create the `docker` group: 9 | ``` 10 | $ sudo groupadd --system docker 11 | ``` 12 | - Restart the socket: 13 | ``` 14 | $ sudo systemctl enable --now docker.socket 15 | ``` 16 | 17 | ## Compatibility 18 | 19 | This sysext is compatible with Fedora Atomic Desktops. 20 | -------------------------------------------------------------------------------- /emacs/Containerfile: -------------------------------------------------------------------------------- 1 | FROM baseimage 2 | 3 | RUN < 2 | # SPDX-License-Identifier: CC0-1.0 3 | --- 4 | name: REUSE Compliance Check 5 | 6 | on: [push, pull_request] 7 | 8 | permissions: 9 | contents: read 10 | 11 | jobs: 12 | reuse-compliance-check: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v6 17 | 18 | - name: REUSE Compliance Check 19 | uses: fsfe/reuse-action@v6 20 | -------------------------------------------------------------------------------- /libratbag/README.md: -------------------------------------------------------------------------------- 1 | # libratbag 2 | 3 | `libratbag` is a daemon that allows users to configure special features in certain input devices, such as extra buttons in gaming mice and keyboards. 4 | The full list of supported devices is available at the [project repository](https://github.com/libratbag/libratbag). 5 | 6 | Once installed, the user can use [Piper](https://flathub.org/apps/org.freedesktop.Piper) or other apps as frontends to `ratbagd`. 7 | 8 | ## Compatibility 9 | 10 | This sysext should be compatible with Fedora Atomic Desktops. -------------------------------------------------------------------------------- /steam-devices/README.md: -------------------------------------------------------------------------------- 1 | # steam-devices 2 | 3 | `steam-devices` package only, for Steam Input support. Use this if you are 4 | using the Steam Flatpak and want better game controller suport and input 5 | remapping. 6 | 7 | If you don't want to use the Steam Flatpak and instead have Steam on the system 8 | directly, look at the `steam-silverblue` and `steam-kinoite` sysexts. 9 | 10 | ## Compatibility 11 | 12 | This sysext is a work in progress. It targets the Fedora Atomic Desktops. 13 | 14 | Please report success or failure with this sysext in an issue. 15 | -------------------------------------------------------------------------------- /.github/cleanup_docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-FileCopyrightText: Timothée Ravier 4 | # SPDX-License-Identifier: CC0-1.0 5 | 6 | # Clean up the docs folder from generated markdown pages. 7 | 8 | set -euo pipefail 9 | # set -x 10 | 11 | main() { 12 | if [[ ! -d .github ]] || [[ ! -d .git ]]; then 13 | echo "This script must be run at the root of the repo" 14 | exit 1 15 | fi 16 | 17 | for s in $(git ls-tree -d --name-only HEAD | grep -Ev ".github|docs|LICENSES"); do 18 | rm -rf "./docs/${s}" 19 | done 20 | } 21 | 22 | main "${@}" 23 | -------------------------------------------------------------------------------- /gdb/justfile: -------------------------------------------------------------------------------- 1 | name := "gdb" 2 | packages := "gdb" 3 | base_images := " 4 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 5 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 6 | " 7 | 8 | import '../sysext.just' 9 | 10 | all: default 11 | 12 | install-manual: 13 | #!/bin/bash 14 | set -euo pipefail 15 | if [[ -n "{{debug}}" ]]; then 16 | set -x 17 | fi 18 | 19 | if [[ "${UID}" == "0" ]]; then 20 | SUDO="" 21 | else 22 | SUDO="sudo" 23 | fi 24 | 25 | cd rootfs 26 | 27 | # Not needed in Fedora 43 anymore 28 | ${SUDO} rm -f ./var/lib/unbound/root.key 29 | -------------------------------------------------------------------------------- /.github/workflow-templates/containers_logincosign: -------------------------------------------------------------------------------- 1 | - name: Login to Container Registry 2 | uses: redhat-actions/podman-login@v1 3 | if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main' 4 | with: 5 | registry: ${{ env.REGISTRY }} 6 | username: ${{ secrets.BOT_USERNAME }} 7 | password: ${{ secrets.BOT_SECRET }} 8 | 9 | - uses: sigstore/cosign-installer@v3.8.0 10 | if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main' 11 | -------------------------------------------------------------------------------- /libvirtd-desktop/Containerfile: -------------------------------------------------------------------------------- 1 | FROM baseimage 2 | 3 | RUN < 4 | # SPDX-License-Identifier: CC0-1.0 5 | 6 | # Dynamically generate the list of sysexts to publish. Mainly used for the 7 | # gather action in CI. 8 | 9 | set -euo pipefail 10 | # set -x 11 | 12 | main() { 13 | if [[ ! -d .github ]] || [[ ! -d .git ]]; then 14 | echo "This script must be run at the root of the repo" 15 | exit 1 16 | fi 17 | 18 | # Get the list of sysexts 19 | sysexts=() 20 | for s in $(git ls-tree -d --name-only HEAD | grep -Ev ".github|docs|LICENSES"); do 21 | if [[ -f ./${s}/.ignore ]]; then 22 | continue 23 | fi 24 | sysexts+=("${s}") 25 | done 26 | echo "${sysexts[@]}" 27 | } 28 | 29 | main "${@}" 30 | -------------------------------------------------------------------------------- /wireshark-kinoite/justfile: -------------------------------------------------------------------------------- 1 | name := "wireshark-kinoite" 2 | packages := " 3 | tcpdump 4 | wireshark 5 | " 6 | version_package := "wireshark" 7 | base_images := " 8 | quay.io/fedora-ostree-desktops/kinoite:42 x86_64,aarch64 9 | quay.io/fedora-ostree-desktops/kinoite:43 x86_64,aarch64 10 | " 11 | 12 | import '../sysext.just' 13 | 14 | all: default 15 | 16 | install-manual: 17 | #!/bin/bash 18 | set -euo pipefail 19 | if [[ -n "{{debug}}" ]]; then 20 | set -x 21 | fi 22 | 23 | if [[ "${UID}" == "0" ]]; then 24 | SUDO="" 25 | else 26 | SUDO="sudo" 27 | fi 28 | 29 | cd rootfs 30 | 31 | # 72 is the UID for tcpdump on Atomic Desktops 32 | ${SUDO} chown 0:72 usr/bin/dumpcap 33 | ${SUDO} setcap 'cap_net_raw,cap_net_admin=ep' usr/bin/dumpcap 34 | -------------------------------------------------------------------------------- /.github/workflow-templates/10_sysexts_build_header: -------------------------------------------------------------------------------- 1 | build-%%JOBNAME%%: 2 | runs-on: "%%RUNSON%%" 3 | container: 4 | image: "ghcr.io/fedora-sysexts/buildroot:latest" 5 | options: "--privileged --security-opt label=disable --user 0:0" 6 | env: 7 | IMAGE: "%%IMAGE%%" 8 | FORCE_REBUILD: ${{ inputs.force-rebuild }} 9 | steps: 10 | - name: "Checkout repo" 11 | uses: actions/checkout@v6 12 | 13 | - name: "Setup artifacts and dnf cache directories" 14 | run: | 15 | mkdir -p artifacts .dnf-cache 16 | 17 | - name: "Mark directory as safe" 18 | run: | 19 | git config --global --add safe.directory "$GITHUB_WORKSPACE" 20 | git fetch --no-tags --prune --depth=1 origin +refs/heads/main:refs/remotes/origin/main 21 | -------------------------------------------------------------------------------- /wireshark-silverblue/justfile: -------------------------------------------------------------------------------- 1 | name := "wireshark-silverblue" 2 | packages := " 3 | tcpdump 4 | wireshark 5 | " 6 | version_package := "wireshark" 7 | base_images := " 8 | quay.io/fedora-ostree-desktops/silverblue:42 x86_64,aarch64 9 | quay.io/fedora-ostree-desktops/silverblue:43 x86_64,aarch64 10 | " 11 | 12 | import '../sysext.just' 13 | 14 | all: default 15 | 16 | install-manual: 17 | #!/bin/bash 18 | set -euo pipefail 19 | if [[ -n "{{debug}}" ]]; then 20 | set -x 21 | fi 22 | 23 | if [[ "${UID}" == "0" ]]; then 24 | SUDO="" 25 | else 26 | SUDO="sudo" 27 | fi 28 | 29 | cd rootfs 30 | 31 | # 72 is the UID for tcpdump on Atomic Desktops 32 | ${SUDO} chown 0:72 usr/bin/dumpcap 33 | ${SUDO} setcap 'cap_net_raw,cap_net_admin=ep' usr/bin/dumpcap 34 | -------------------------------------------------------------------------------- /kubernetes-1.31/justfile: -------------------------------------------------------------------------------- 1 | kube_version := "1.31" 2 | name := "kubernetes-" + kube_version 3 | packages := " 4 | cri-tools" + kube_version + " 5 | kubernetes" + kube_version + " 6 | kubernetes" + kube_version + "-client 7 | kubernetes" + kube_version + "-kubeadm 8 | " 9 | exclude_packages := " 10 | cri-o 11 | cri-tools 12 | " 13 | upholds := " 14 | kubelet.service 15 | " 16 | version_package := "kubernetes" + kube_version 17 | # Setup folder that is expected by Kubernetes 18 | files := "usr" 19 | # Cleanup file needed by git as this is an empty directory 20 | cleanup_files := "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep" 21 | base_images := " 22 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 23 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 24 | " 25 | 26 | import '../sysext.just' 27 | 28 | all: default 29 | -------------------------------------------------------------------------------- /kubernetes-1.32/justfile: -------------------------------------------------------------------------------- 1 | kube_version := "1.32" 2 | name := "kubernetes-" + kube_version 3 | packages := " 4 | cri-tools" + kube_version + " 5 | kubernetes" + kube_version + " 6 | kubernetes" + kube_version + "-client 7 | kubernetes" + kube_version + "-kubeadm 8 | " 9 | exclude_packages := " 10 | cri-o 11 | cri-tools 12 | " 13 | upholds := " 14 | kubelet.service 15 | " 16 | version_package := "kubernetes" + kube_version 17 | # Setup folder that is expected by Kubernetes 18 | files := "usr" 19 | # Cleanup file needed by git as this is an empty directory 20 | cleanup_files := "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep" 21 | base_images := " 22 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 23 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 24 | " 25 | 26 | import '../sysext.just' 27 | 28 | all: default 29 | -------------------------------------------------------------------------------- /kubernetes-1.33/justfile: -------------------------------------------------------------------------------- 1 | kube_version := "1.33" 2 | name := "kubernetes-" + kube_version 3 | packages := " 4 | cri-tools" + kube_version + " 5 | kubernetes" + kube_version + " 6 | kubernetes" + kube_version + "-client 7 | kubernetes" + kube_version + "-kubeadm 8 | " 9 | exclude_packages := " 10 | cri-o 11 | cri-tools 12 | " 13 | upholds := " 14 | kubelet.service 15 | " 16 | version_package := "kubernetes" + kube_version 17 | # Setup folder that is expected by Kubernetes 18 | files := "usr" 19 | # Cleanup file needed by git as this is an empty directory 20 | cleanup_files := "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep" 21 | base_images := " 22 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 23 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 24 | " 25 | 26 | import '../sysext.just' 27 | 28 | all: default 29 | -------------------------------------------------------------------------------- /kubernetes-1.34/justfile: -------------------------------------------------------------------------------- 1 | kube_version := "1.34" 2 | name := "kubernetes-" + kube_version 3 | packages := " 4 | cri-tools" + kube_version + " 5 | kubernetes" + kube_version + " 6 | kubernetes" + kube_version + "-client 7 | kubernetes" + kube_version + "-kubeadm 8 | " 9 | exclude_packages := " 10 | cri-o 11 | cri-tools 12 | " 13 | upholds := " 14 | kubelet.service 15 | " 16 | version_package := "kubernetes" + kube_version 17 | # Setup folder that is expected by Kubernetes 18 | files := "usr" 19 | # Cleanup file needed by git as this is an empty directory 20 | cleanup_files := "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep" 21 | base_images := " 22 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 23 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 24 | " 25 | 26 | import '../sysext.just' 27 | 28 | all: default 29 | -------------------------------------------------------------------------------- /REUSE.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | 3 | [[annotations]] 4 | path = [ 5 | ".github/docs-templates/body.md", 6 | ".github/docs-templates/header.md", 7 | ".github/workflow-templates/**", 8 | "CONTRIBUTING.md", 9 | "README.containers.md", 10 | "README.md", 11 | "docs/.bundle/config", 12 | "docs/Gemfile.lock", 13 | "docs/index.md", 14 | ] 15 | SPDX-FileCopyrightText = [ 16 | "Timothée Ravier " 17 | ] 18 | SPDX-License-Identifier = "CC0-1.0" 19 | 20 | [[annotations]] 21 | path = [ 22 | "*/Containerfile", 23 | "*/README.md", 24 | "*/justfile", 25 | "iwd/usr/lib/NetworkManager/conf.d/wifi_backend.conf", 26 | "qemu-guest-agent/usr/lib/systemd/system/qemu-guest-agent.service.d/override.conf", 27 | ] 28 | SPDX-FileCopyrightText = [ 29 | "Fedora sysexts contributors" 30 | ] 31 | SPDX-License-Identifier = "MIT" 32 | -------------------------------------------------------------------------------- /kubernetes-cri-o-1.31/justfile: -------------------------------------------------------------------------------- 1 | kube_version := "1.31" 2 | name := "kubernetes-cri-o-" + kube_version 3 | packages := " 4 | cri-o" + kube_version + " 5 | cri-tools" + kube_version + " 6 | kubernetes" + kube_version + " 7 | kubernetes" + kube_version + "-client 8 | kubernetes" + kube_version + "-kubeadm 9 | " 10 | exclude_packages := " 11 | cri-o 12 | cri-tools 13 | " 14 | upholds := " 15 | crio.service 16 | kubelet.service 17 | " 18 | version_package := "kubernetes" + kube_version 19 | # Setup folder that is expected by Kubernetes 20 | files := "usr" 21 | # Cleanup file needed by git as this is an empty directory 22 | cleanup_files := "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep" 23 | base_images := " 24 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 25 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 26 | " 27 | 28 | import '../sysext.just' 29 | 30 | all: default 31 | -------------------------------------------------------------------------------- /kubernetes-cri-o-1.32/justfile: -------------------------------------------------------------------------------- 1 | kube_version := "1.32" 2 | name := "kubernetes-cri-o-" + kube_version 3 | packages := " 4 | cri-o" + kube_version + " 5 | cri-tools" + kube_version + " 6 | kubernetes" + kube_version + " 7 | kubernetes" + kube_version + "-client 8 | kubernetes" + kube_version + "-kubeadm 9 | " 10 | exclude_packages := " 11 | cri-o 12 | cri-tools 13 | " 14 | upholds := " 15 | crio.service 16 | kubelet.service 17 | " 18 | version_package := "kubernetes" + kube_version 19 | # Setup folder that is expected by Kubernetes 20 | files := "usr" 21 | # Cleanup file needed by git as this is an empty directory 22 | cleanup_files := "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep" 23 | base_images := " 24 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 25 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 26 | " 27 | 28 | import '../sysext.just' 29 | 30 | all: default 31 | -------------------------------------------------------------------------------- /kubernetes-cri-o-1.33/justfile: -------------------------------------------------------------------------------- 1 | kube_version := "1.33" 2 | name := "kubernetes-cri-o-" + kube_version 3 | packages := " 4 | cri-o" + kube_version + " 5 | cri-tools" + kube_version + " 6 | kubernetes" + kube_version + " 7 | kubernetes" + kube_version + "-client 8 | kubernetes" + kube_version + "-kubeadm 9 | " 10 | exclude_packages := " 11 | cri-o 12 | cri-tools 13 | " 14 | upholds := " 15 | crio.service 16 | kubelet.service 17 | " 18 | version_package := "kubernetes" + kube_version 19 | # Setup folder that is expected by Kubernetes 20 | files := "usr" 21 | # Cleanup file needed by git as this is an empty directory 22 | cleanup_files := "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep" 23 | base_images := " 24 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 25 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 26 | " 27 | 28 | import '../sysext.just' 29 | 30 | all: default 31 | -------------------------------------------------------------------------------- /kubernetes-cri-o-1.34/justfile: -------------------------------------------------------------------------------- 1 | kube_version := "1.34" 2 | name := "kubernetes-cri-o-" + kube_version 3 | packages := " 4 | cri-o" + kube_version + " 5 | cri-tools" + kube_version + " 6 | kubernetes" + kube_version + " 7 | kubernetes" + kube_version + "-client 8 | kubernetes" + kube_version + "-kubeadm 9 | " 10 | exclude_packages := " 11 | cri-o 12 | cri-tools 13 | " 14 | upholds := " 15 | crio.service 16 | kubelet.service 17 | " 18 | version_package := "kubernetes" + kube_version 19 | # Setup folder that is expected by Kubernetes 20 | files := "usr" 21 | # Cleanup file needed by git as this is an empty directory 22 | cleanup_files := "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/.keep" 23 | base_images := " 24 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 25 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 26 | " 27 | 28 | import '../sysext.just' 29 | 30 | all: default 31 | -------------------------------------------------------------------------------- /libvirtd/Containerfile: -------------------------------------------------------------------------------- 1 | FROM baseimage 2 | 3 | RUN < 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | name: "Build sysexts for Fedora" 5 | 6 | env: 7 | GH_TOKEN: ${{ github.token }} 8 | RELEASEURL: "%%RELEASEURL%%" 9 | 10 | on: 11 | pull_request: 12 | branches: 13 | - "main" 14 | push: 15 | branches: 16 | - "main" 17 | schedule: 18 | - cron: '0 0 * * *' 19 | workflow_dispatch: 20 | inputs: 21 | force-rebuild: 22 | description: 'Force rebuild of all sysexts' 23 | required: true 24 | default: false 25 | type: boolean 26 | 27 | # Needed to allow creating a release 28 | permissions: 29 | contents: write 30 | 31 | # Prevent multiple workflow runs from racing to ensure that pushes are made 32 | # sequentialy for the main branch. Also cancel in progress workflow runs. 33 | concurrency: 34 | group: ${{ github.workflow }}-${{ github.ref || github.run_id }} 35 | cancel-in-progress: ${{ github.event_name == 'pull_request' }} 36 | 37 | jobs: 38 | -------------------------------------------------------------------------------- /.github/workflow-templates/containers_pushsign: -------------------------------------------------------------------------------- 1 | - name: "Push container: %%SYSEXT%%" 2 | uses: redhat-actions/push-to-registry@v2 3 | id: push-%%SYSEXT_NODOT%% 4 | if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main' 5 | with: 6 | username: ${{ secrets.BOT_USERNAME }} 7 | password: ${{ secrets.BOT_SECRET }} 8 | image: ${{ env.DESTINATION }} 9 | registry: ${{ env.REGISTRY }} 10 | tags: ${{ env.RELEASE }}.%%SYSEXT%% 11 | 12 | - name: "Sign container: %%SYSEXT%%" 13 | if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main' 14 | run: | 15 | cosign sign -y --key env://COSIGN_PRIVATE_KEY ${{ env.REGISTRY }}/${{ env.DESTINATION }}@${{ steps.push-%%SYSEXT_NODOT%%.outputs.digest }} 16 | env: 17 | COSIGN_EXPERIMENTAL: false 18 | COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} 19 | -------------------------------------------------------------------------------- /wireshark-kinoite/README.md: -------------------------------------------------------------------------------- 1 | # wireshark-kinoite 2 | 3 | This sysext is for Fedora Kinoite only. If you are using Fedora Silverblue, use 4 | `wireshark-silverblue` instead. 5 | 6 | ## How to use 7 | 8 | - Install the system extension 9 | - Add users to the `tcpdump` group: 10 | ``` 11 | $ grep -E '^tcpdump:' /usr/lib/group | sudo tee -a /etc/group 12 | $ sudo usermod --append --groups=tcpdump $USER 13 | ``` 14 | 15 | ## Why not use the Flatpak? 16 | 17 | It should currently be possible to use the Wireshark Flatpak and connect to the 18 | local system via SSH to a rootful container that has tcpdump installed. 19 | 20 | See: https://discussion.fedoraproject.org/t/silverblue-wireshark-does-not-see-network-interfaces/88916/11 21 | 22 | This requires some manual setup thus in some cases, using this sysext should be 23 | easier. 24 | 25 | ## Why not use layering? 26 | 27 | See: 28 | 29 | ## Compatibility 30 | 31 | This sysext is compatible with Fedora Kinoite only. If you are using 32 | Fedora Silverblue, use `wireshark-silverblue` instead. 33 | -------------------------------------------------------------------------------- /wireshark-silverblue/README.md: -------------------------------------------------------------------------------- 1 | # wireshark-silverblue 2 | 3 | This sysext is for Fedora Silverblue only. If you are using Fedora Kinoite, use 4 | `wireshark-kinoite` instead. 5 | 6 | ## How to use 7 | 8 | - Install the system extension 9 | - Add users to the `tcpdump` group: 10 | ``` 11 | $ grep -E '^tcpdump:' /usr/lib/group | sudo tee -a /etc/group 12 | $ sudo usermod --append --groups=tcpdump $USER 13 | ``` 14 | 15 | ## Why not use the Flatpak? 16 | 17 | It should currently be possible to use the Wireshark Flatpak and connect to the 18 | local system via SSH to a rootful container that has tcpdump installed. 19 | 20 | See: https://discussion.fedoraproject.org/t/silverblue-wireshark-does-not-see-network-interfaces/88916/11 21 | 22 | This requires some manual setup thus in some cases, using this sysext should be 23 | easier. 24 | 25 | ## Why not use layering? 26 | 27 | See: 28 | 29 | ## Compatibility 30 | 31 | This sysext is compatible with Fedora Silverblue only. If you are using Fedora 32 | Kinoite, use `wireshark-kinoite` instead. 33 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | nav_order: 1 3 | --- 4 | 5 | # Fedora RPM based sysexts for Fedora image based systems 6 | 7 | **NOTE: This project is a work in progress. Make sure to read the [known 8 | limitations section](https://extensions.fcos.fr/known-issues). Use at your own 9 | risk.** 10 | 11 | This sub project gathers systemd system extensions (sysexts) made exclusively 12 | from official Fedora packages. 13 | 14 | The goal of this repo is to eventually become the source of official Fedora 15 | sysexts built in the Fedora infrastructure. 16 | 17 | For sysexts built from community sources, see 18 | [extensions.fcos.fr/community](https://extensions.fcos.fr/community). 19 | 20 | For general explainations about systemd system extensions (sysexts) and how to 21 | use them, see the documentation from the parent page: 22 | [extensions.fcos.fr](https://extensions.fcos.fr). 23 | 24 | ## Compatibility 25 | 26 | See [extensions.fcos.fr/compatibility](https://extensions.fcos.fr/compatibility). 27 | 28 | ## Building, contributing and licenses 29 | 30 | See the project's [README](https://github.com/fedora-sysexts/fedora). 31 | -------------------------------------------------------------------------------- /LICENSES/MIT.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 6 | associated documentation files (the "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the 9 | following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial 12 | portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 15 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO 16 | EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 18 | USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to this repo 2 | 3 | ## Adding a new sysext 4 | 5 | - Create a new folder 6 | - Add a `justfile` and `Containerfile` 7 | - See `sysext.just` for all options and other sysexts for examples 8 | - Add a README.md with any notes about the sysext, its setup, etc. 9 | - Commit your changes 10 | - Then see the CI setup section below 11 | 12 | ## CI setup 13 | 14 | To ensure that the dependencies are in sync, the sysexts are built from the 15 | base images that they are targetting. Thus to reduce the number of times each 16 | base OS container images have to be pulled and make the CI faster in general, 17 | the GitHub workflows use manual templating instead of the classic matrix 18 | feature. 19 | 20 | When making changes to the base image list for a sysext (in the justfile only 21 | for now), adding a new sysext, renaming or removing one, you need to also 22 | re-generate the workflows using the `update_workflows.sh` script. 23 | 24 | Note that this script only takes into account commited files thus when adding a 25 | new sysext, you should commit the content first, then run the script and 26 | finally amend the commit with the updated workflows. 27 | -------------------------------------------------------------------------------- /.github/workflow-templates/containers_build: -------------------------------------------------------------------------------- 1 | - name: "Checking if we need to build container: %%SYSEXT%%" 2 | id: check-%%SYSEXT_NODOT%% 3 | env: 4 | SYSEXT: %%SYSEXT%% 5 | run: | 6 | cd "${SYSEXT}" 7 | if [[ "${PR}" == "true" ]]; then 8 | diff="$(git diff origin/main HEAD --stat -- .)" 9 | if [[ -z "${diff}" ]]; then 10 | echo "Skipping: No changes for this sysext in this PR" 11 | echo "BUILD=false" >> "$GITHUB_OUTPUT" 12 | exit 0 13 | fi 14 | fi 15 | echo "BUILD=true" >> "$GITHUB_OUTPUT" 16 | 17 | - name: "Build container: %%SYSEXT%%" 18 | uses: redhat-actions/buildah-build@v2 19 | if: (steps.check-%%SYSEXT_NODOT%%.outputs.BUILD == 'true') 20 | with: 21 | context: '%%SYSEXT%%' 22 | image: ${{ env.DESTINATION }} 23 | tags: ${{ env.RELEASE }}.%%SYSEXT%% 24 | containerfiles: '%%SYSEXT%%/Containerfile' 25 | layers: false 26 | oci: true 27 | extra-args: 28 | --from 29 | ${{ env.IMAGE }}:${{ env.RELEASE }} 30 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Timothée Ravier 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | title: "extensions.fcos.fr (Fedora)" 5 | description: "Fedora RPM based sysexts for Fedora" 6 | baseurl: "/fedora" 7 | url: "https://fedora-sysexts.github.io" 8 | permalink: "/:title/" 9 | markdown: "kramdown" 10 | kramdown: 11 | typographic_symbols: 12 | ndash: "--" 13 | mdash: "---" 14 | 15 | remote_theme: just-the-docs/just-the-docs@v0.8.1 16 | plugins: 17 | - jekyll-remote-theme 18 | 19 | # Exclude from processing. 20 | exclude: 21 | - justfile 22 | - Gemfile 23 | - Gemfile.lock 24 | - vendor 25 | 26 | # Aux links for the upper right navigation 27 | aux_links: 28 | "Sources on GitHub": 29 | - "https://github.com/fedora-sysexts/fedora" 30 | 31 | # Footer last edited timestamp 32 | last_edit_timestamp: true 33 | last_edit_time_format: "%b %e %Y at %I:%M %p" 34 | 35 | # Footer "Edit this page on GitHub" link text 36 | gh_edit_link: true 37 | gh_edit_link_text: "Edit this page on GitHub" 38 | gh_edit_repository: "https://github.com/fedora-sysexts/fedora" 39 | gh_edit_branch: "main" 40 | gh_edit_source: "docs" 41 | gh_edit_view_mode: "tree" 42 | 43 | compress_html: 44 | clippings: all 45 | comments: all 46 | endings: all 47 | startings: [] 48 | blanklines: false 49 | profile: false 50 | -------------------------------------------------------------------------------- /libvirtd-desktop/README.md: -------------------------------------------------------------------------------- 1 | # libvirtd-desktop 2 | 3 | `libvirtd`, `qemu`, `swtpm`, `virt-install` and `guestfs-tools` for desktop 4 | usage. 5 | 6 | For server usage, see the 7 | [`libvirtd` sysext](https://travier.github.io/fedora-sysexts/libvirtd/) 8 | instead. 9 | 10 | See the [Virtual Machine Manager Flatpak](https://flathub.org/apps/org.virt_manager.virt-manager). 11 | 12 | ## How to use 13 | 14 | - Install the sysext 15 | - Create the `qemu` user: 16 | ``` 17 | $ sudo systemd-sysusers /usr/lib/sysusers.d/libvirt-qemu.conf 18 | ``` 19 | - Copy the some default config: 20 | ``` 21 | $ sudo cp -a /usr/etc/mdevctl.d /etc/ 22 | ``` 23 | - Optional: Copy the default libvirtd config (note that it won't be updated automatically): 24 | ``` 25 | $ sudo cp -a /usr/etc/libvirt /etc/ 26 | ``` 27 | - Optional: Setup auth via polkit (example): 28 | ``` 29 | $ sudo cat /etc/polkit-1/rules.d/50-libvirt.rules 30 | polkit.addRule(function(action, subject) { 31 | if (action.id == "org.libvirt.unix.manage" && 32 | subject.isInGroup("wheel")) { 33 | return polkit.Result.YES; 34 | } 35 | }); 36 | ``` 37 | - Restart libvirtd (via virtqemud, virtnetworkd & virtstoraged): 38 | ``` 39 | $ sudo systemctl restart virtqemud.socket virtnetworkd.socket virtstoraged.socket 40 | ``` 41 | 42 | ## Compatibility 43 | 44 | This sysext is compatible with Fedora Atomic Desktops. 45 | -------------------------------------------------------------------------------- /libvirtd/README.md: -------------------------------------------------------------------------------- 1 | # libvirtd 2 | 3 | `libvirtd`, `qemu-kvm`, `swtpm`, `virt-install` and `guestfs-tools` for server 4 | usage (no GUI support). 5 | 6 | For desktop usage, see the 7 | [`libvirtd-desktop` sysext](https://travier.github.io/fedora-sysexts/libvirtd-desktop/) 8 | instead. 9 | 10 | See the [Virtual Machine Manager Flatpak](https://flathub.org/apps/org.virt_manager.virt-manager). 11 | 12 | ## How to use 13 | 14 | - Install the sysext 15 | - Create the `qemu` user: 16 | ``` 17 | $ sudo systemd-sysusers /usr/lib/sysusers.d/libvirt-qemu.conf 18 | ``` 19 | - Copy the some default config: 20 | ``` 21 | $ sudo cp -a /usr/etc/mdevctl.d /etc/ 22 | ``` 23 | - Optional: Copy the default libvirtd config (note that it won't be updated automatically): 24 | ``` 25 | $ sudo cp -a /usr/etc/libvirt /etc/ 26 | ``` 27 | - Optional: Setup auth via polkit (example): 28 | ``` 29 | $ sudo cat /etc/polkit-1/rules.d/50-libvirt.rules 30 | polkit.addRule(function(action, subject) { 31 | if (action.id == "org.libvirt.unix.manage" && 32 | subject.isInGroup("wheel")) { 33 | return polkit.Result.YES; 34 | } 35 | }); 36 | ``` 37 | - Restart libvirtd (via virtqemud, virtnetworkd & virtstoraged): 38 | ``` 39 | $ sudo systemctl restart virtqemud.socket virtnetworkd.socket virtstoraged.socket 40 | ``` 41 | 42 | ## Compatibility 43 | 44 | This sysext is compatible with Fedora CoreOS only. 45 | -------------------------------------------------------------------------------- /.github/workflow-templates/20_sysexts_gather: -------------------------------------------------------------------------------- 1 | publish-sysexts: 2 | runs-on: "ubuntu-24.04" 3 | container: 4 | image: "ghcr.io/fedora-sysexts/buildroot:latest" 5 | options: "--privileged --security-opt label=disable --user 0:0" 6 | # Run after the builds and versionned release 7 | needs: 8 | - build-fedora-42-x86_64 9 | - build-fedora-42-aarch64 10 | - build-fedora-43-x86_64 11 | - build-fedora-43-aarch64 12 | - build-fedora-silverblue-42-x86_64 13 | - build-fedora-silverblue-42-aarch64 14 | - build-fedora-silverblue-43-x86_64 15 | - build-fedora-silverblue-43-aarch64 16 | - build-fedora-kinoite-42-x86_64 17 | - build-fedora-kinoite-42-aarch64 18 | - build-fedora-kinoite-43-x86_64 19 | - build-fedora-kinoite-43-aarch64 20 | - build-fedora-coreos-stable-x86_64 21 | - build-fedora-coreos-stable-aarch64 22 | - build-fedora-coreos-next-x86_64 23 | - build-fedora-coreos-next-aarch64 24 | # Use `always()` to still run if any dependent job fails 25 | if: ${{ always() && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main' }} 26 | steps: 27 | - name: "Checkout repo" 28 | uses: actions/checkout@v6 29 | 30 | - name: "Mark directory as safe" 31 | run: | 32 | git config --global --add safe.directory "$GITHUB_WORKSPACE" 33 | git fetch --no-tags --prune --depth=1 origin +refs/heads/main:refs/remotes/origin/main 34 | 35 | - name: "Gather all sysexts releases" 36 | uses: ./.github/actions/gather 37 | -------------------------------------------------------------------------------- /libvirtd-desktop/justfile: -------------------------------------------------------------------------------- 1 | name := "libvirtd-desktop" 2 | packages := " 3 | guestfs-tools 4 | libguestfs 5 | libguestfs-xfs 6 | libosinfo 7 | libvirt-client 8 | libvirt-daemon 9 | libvirt-daemon-config-network 10 | libvirt-daemon-driver-interface 11 | libvirt-daemon-driver-network 12 | libvirt-daemon-driver-nodedev 13 | libvirt-daemon-driver-nwfilter 14 | libvirt-daemon-driver-qemu 15 | libvirt-daemon-driver-secret 16 | libvirt-daemon-driver-storage-core 17 | libvirt-dbus 18 | osinfo-db 19 | osinfo-db-tools 20 | netcat 21 | qemu-kvm 22 | qemu-img 23 | swtpm 24 | virt-install 25 | " 26 | upholds := " 27 | virtlockd-admin.socket 28 | virtlockd.socket 29 | virtlogd-admin.socket 30 | virtlogd.socket 31 | virtnetworkd-admin.socket 32 | virtnetworkd-ro.socket 33 | virtnetworkd.socket 34 | virtqemud-admin.socket 35 | virtqemud-ro.socket 36 | virtqemud.socket 37 | virtstoraged-admin.socket 38 | virtstoraged-ro.socket 39 | virtstoraged.socket 40 | " 41 | version_package := "libvirt-client" 42 | 43 | import '../sysext.just' 44 | 45 | all: default 46 | 47 | install-manual: 48 | #!/bin/bash 49 | set -euo pipefail 50 | if [[ -n "{{debug}}" ]]; then 51 | set -x 52 | fi 53 | 54 | if [[ "${UID}" == "0" ]]; then 55 | SUDO="" 56 | else 57 | SUDO="sudo" 58 | fi 59 | 60 | cd rootfs 61 | 62 | # Fixup netcat/nc as we don't run the alternatives command from scriplets 63 | ${SUDO} ln -snf netcat usr/bin/nc 64 | 65 | # Move extlinux to /usr/bin as needed 66 | if [[ -f sbin/extlinux ]]; then 67 | ${SUDO} mv sbin/extlinux usr/bin/extlinux 68 | ${SUDO} rmdir sbin 69 | fi 70 | 71 | # Empty out /var & /boot 72 | ${SUDO} rm -rf ./var ./boot 73 | -------------------------------------------------------------------------------- /.github/workflows/pages.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Timothée Ravier 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | name: "Deploy website to GitHub Pages" 5 | 6 | on: 7 | push: 8 | branches: 9 | - "main" 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: "read" 15 | pages: "write" 16 | id-token: "write" 17 | 18 | # Allow only one concurrent deployment, skipping runs queued between the run 19 | # in-progress and latest queued.However, do NOT cancel in-progress runs as we 20 | # want to allow these production deployments to complete. 21 | concurrency: 22 | group: "pages" 23 | cancel-in-progress: false 24 | 25 | jobs: 26 | build: 27 | runs-on: "ubuntu-latest" 28 | steps: 29 | - name: "Checkout" 30 | uses: "actions/checkout@v6" 31 | 32 | - name: "Setup Pages" 33 | uses: "actions/configure-pages@v5" 34 | 35 | - name: "Generate docs" 36 | run: | 37 | ./.github/generate_docs.sh 38 | 39 | - name: "Build with Jekyll" 40 | uses: "actions/jekyll-build-pages@v1" 41 | with: 42 | source: "./docs" 43 | destination: "./_site" 44 | 45 | - name: "Upload artifact" 46 | uses: "actions/upload-pages-artifact@v4" 47 | 48 | deploy: 49 | environment: 50 | name: "github-pages" 51 | url: ${{ steps.deployment.outputs.page_url }} 52 | runs-on: "ubuntu-latest" 53 | needs: "build" 54 | if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main' 55 | steps: 56 | - name: "Deploy to GitHub Pages" 57 | id: "deployment" 58 | uses: "actions/deploy-pages@v4" 59 | -------------------------------------------------------------------------------- /.github/workflow-templates/containers_header: -------------------------------------------------------------------------------- 1 | name: "Build containers: %%NAME%% (%%RELEASE%%, %%ARCH%%)" 2 | 3 | env: 4 | IMAGE: '%%IMAGE%%' 5 | RELEASE: '%%RELEASE%%' 6 | NAME: '%%NAME%%' 7 | REGISTRY: '%%REGISTRY%%' 8 | DESTINATION: '%%DESTINATION%%' 9 | PR: ${{ github.event_name == 'pull_request' }} 10 | ARCH: '%%ARCH%%' 11 | 12 | on: 13 | pull_request: 14 | branches: 15 | - main 16 | push: 17 | branches: 18 | - main 19 | schedule: 20 | - cron: '0 0 * * MON' 21 | workflow_dispatch: 22 | 23 | permissions: read-all 24 | 25 | # Prevent multiple workflow runs from racing to ensure that pushes are made 26 | # sequentialy for the main branch. Also cancel in progress workflow runs. 27 | concurrency: 28 | group: ${{ github.workflow }}-${{ github.ref || github.run_id }}-${{ inputs.sysext }} 29 | cancel-in-progress: ${{ github.event_name == 'pull_request' }} 30 | 31 | jobs: 32 | build: 33 | runs-on: ubuntu-24.04 34 | steps: 35 | - name: Reclaim disk space 36 | run: | 37 | sudo docker image prune --all --force 38 | sudo rm -rf "/usr/local/lib/android" 39 | 40 | - name: Get latest podman (and skopeo) for heredocs support 41 | run: | 42 | set -eux 43 | echo 'deb [trusted=yes] https://deb.debian.org/debian/ testing main' | sudo tee /etc/apt/sources.list.d/testing.list 44 | sudo apt update 45 | sudo apt install -y crun/testing podman/testing skopeo/testing buildah/testing 46 | # Something is confused in latest GHA here 47 | sudo rm /var/lib/containers -rf 48 | 49 | - name: Checkout repo 50 | uses: actions/checkout@v6 51 | 52 | - name: "Mark directory as safe" 53 | run: | 54 | git config --global --add safe.directory "$GITHUB_WORKSPACE" 55 | git fetch --no-tags --prune --depth=1 origin +refs/heads/main:refs/remotes/origin/main 56 | -------------------------------------------------------------------------------- /libvirtd/justfile: -------------------------------------------------------------------------------- 1 | name := "libvirtd" 2 | packages := " 3 | guestfs-tools 4 | libguestfs 5 | libguestfs-xfs 6 | libvirt-client 7 | libvirt-daemon 8 | libvirt-daemon-config-network 9 | libvirt-daemon-driver-interface 10 | libvirt-daemon-driver-network 11 | libvirt-daemon-driver-nodedev 12 | libvirt-daemon-driver-nwfilter 13 | libvirt-daemon-driver-qemu 14 | libvirt-daemon-driver-secret 15 | libvirt-daemon-driver-storage-core 16 | libvirt-daemon-driver-storage-disk 17 | libvirt-daemon-driver-storage-iscsi 18 | libvirt-daemon-driver-storage-iscsi-direct 19 | libvirt-daemon-driver-storage-logical 20 | libvirt-daemon-driver-storage-mpath 21 | libvirt-daemon-driver-storage-rbd 22 | libvirt-daemon-driver-storage-scsi 23 | libvirt-dbus 24 | netcat 25 | qemu-img 26 | qemu-kvm 27 | swtpm 28 | virt-install 29 | " 30 | upholds := " 31 | virtlockd-admin.socket 32 | virtlockd.socket 33 | virtlogd-admin.socket 34 | virtlogd.socket 35 | virtnetworkd-admin.socket 36 | virtnetworkd-ro.socket 37 | virtnetworkd.socket 38 | virtqemud-admin.socket 39 | virtqemud-ro.socket 40 | virtqemud.socket 41 | virtstoraged-admin.socket 42 | virtstoraged-ro.socket 43 | virtstoraged.socket 44 | " 45 | version_package := "libvirt-client" 46 | base_images := " 47 | quay.io/fedora/fedora-coreos:stable x86_64,aarch64 48 | quay.io/fedora/fedora-coreos:next x86_64,aarch64 49 | " 50 | # Pending nfs-utils packaging rework 51 | # Fixed in Fedora 44 52 | pre_commands := "dnf remove -y nfs-utils-coreos" 53 | 54 | import '../sysext.just' 55 | 56 | all: default 57 | 58 | install-manual: 59 | #!/bin/bash 60 | set -euo pipefail 61 | if [[ -n "{{debug}}" ]]; then 62 | set -x 63 | fi 64 | 65 | if [[ "${UID}" == "0" ]]; then 66 | SUDO="" 67 | else 68 | SUDO="sudo" 69 | fi 70 | 71 | cd rootfs 72 | 73 | # Fixup netcat/nc as we don't run the alternatives command from scriplets 74 | ${SUDO} ln -snf netcat usr/bin/nc 75 | 76 | # Move extlinux to /usr/bin as needed 77 | if [[ -f sbin/extlinux ]]; then 78 | ${SUDO} mv sbin/extlinux usr/bin/extlinux 79 | ${SUDO} rmdir sbin 80 | fi 81 | 82 | # Empty out /var & /boot 83 | ${SUDO} rm -rf ./var ./boot 84 | -------------------------------------------------------------------------------- /.github/generate_docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-FileCopyrightText: Timothée Ravier 4 | # SPDX-License-Identifier: CC0-1.0 5 | 6 | # Re-generate the docs for the GitHub Pages workflow. 7 | # TODO: Note somewhere for which images the sysext is for? 8 | 9 | set -euo pipefail 10 | # set -x 11 | 12 | main() { 13 | if [[ ! -d .github ]] || [[ ! -d .git ]]; then 14 | echo "This script must be run at the root of the repo" 15 | exit 1 16 | fi 17 | 18 | local -r extensionsurl="https://extensions.fcos.fr/fedora" 19 | local -r releaseurl="https://github.com/fedora-sysexts/fedora/releases/tag" 20 | 21 | local -r tmpl=".github/docs-templates" 22 | 23 | if [[ ! -d "${tmpl}" ]]; then 24 | echo "Could not find the templates. Is this script run from the root of the repo?" 25 | exit 1 26 | fi 27 | 28 | navorder=1 29 | 30 | for s in $(git ls-tree -d --name-only HEAD | grep -Ev ".github|docs|LICENSES"); do 31 | if [[ -f ./${s}/.ignore ]]; then 32 | continue 33 | fi 34 | navorder=$((navorder+1)) 35 | mkdir -p "docs/${s}" 36 | { 37 | sed -e "s|%%SYSEXT%%|${s}|g" \ 38 | -e "s|%%NAVORDER%%|${navorder}|g" \ 39 | "${tmpl}/header.md" 40 | pushd "${s}" > /dev/null 41 | if [[ -f "README.md" ]]; then 42 | tail -n +2 README.md 43 | fi 44 | popd > /dev/null 45 | echo "" 46 | sed -e "s|%%SYSEXT%%|${s}|g" \ 47 | -e "s|%%RELEASEURL%%|${releaseurl}|g" \ 48 | -e "s|%%EXTENSIONSURL%%|${extensionsurl}|g" \ 49 | "${tmpl}/body.md" 50 | } > "docs/${s}/index.md" 51 | done 52 | 53 | pushd docs > /dev/null 54 | docs_dir="$(ls -d ./*/ | grep -vE "_site|vendor")" 55 | popd > /dev/null 56 | sysexts_dirs="$(ls -d ./*/ | grep -vE "docs")" 57 | 58 | diff="$(diff -u <(echo "${docs_dir}") <(echo "${sysexts_dirs}") || true)" 59 | if [[ -n "${diff}" ]]; then 60 | echo "Diff between current sysexts and docs is not empty. Cleanup needed following a sysext removal?" 61 | echo "" 62 | echo "${diff}" 63 | fi 64 | } 65 | 66 | main "${@}" 67 | -------------------------------------------------------------------------------- /README.containers.md: -------------------------------------------------------------------------------- 1 | # Experimental sysexts builds as container layers 2 | 3 | In each sysext sub directory, there is also a Containerfile that is used to 4 | build a layer that is pushed to a container registry and that can be later 5 | converted into a sysext. 6 | 7 | In the end, this could be converted to a plain EROFS or a composefs EROFS using 8 | bootc. 9 | 10 | ## How to get just the layer 11 | 12 | We will use the [deprecated `skopeo layers` command](https://github.com/containers/skopeo/issues/481): 13 | 14 | ``` 15 | # Pick the sysext for the image that you are targeting 16 | $ SYSEXT=iwd 17 | $ IMAGE=quay.io/travier/fedora-kinoite/sysexts:41 18 | 19 | # Pull down just thus layer 20 | $ layerhash="$(skopeo inspect docker://${IMAGE}.${SYSEXT} | jq -r '.Layers[-1] | sub ("^sha256:"; "")')" 21 | $ skopeo layers docker://${IMAGE}.${SYSEXT} ${layerhash} 22 | 23 | # Extract just the parts that we want / can actually use from the layer 24 | $ cd layers-... 25 | $ tar xvf 0e68a7d3d7i... usr 26 | ``` 27 | 28 | ## How to use that? 29 | 30 | The next steps would then be to: 31 | - Cleanup the files that we don't need: 32 | - We can not include the updated RPM database for example as that would not 33 | make sense (there can only be one so if you have multiple sysexts, the last 34 | one mounted will win). 35 | - Running `dnf install` will create local state in `/etc` that we don't want 36 | and would have to cleanup. 37 | - We then need to move the added default configs from `/etc` to `/usr/etc`. 38 | - Relabel the files with the SELinux policy (would have to run from the context 39 | of the container to use the SELinux policy from the layered image). 40 | - We will also have to make sure that the SELinux policy is rebuilt and 41 | reloaded after the sysexts are set up on the system. Ideally this should 42 | probably happen every time we refresh the sysexts. 43 | - Package that into an EROFS image / composefs EROFS. 44 | 45 | ## Example container layers for sysexts in this repo 46 | 47 | - Fedora Kinoite 41: 48 | - Fedora CoreOS next: 49 | 50 | The images are signed with cosign with the public key in 51 | `quay.io-travier-fedora-sysexts.pub` in this repo. 52 | -------------------------------------------------------------------------------- /.github/docs-templates/body.md: -------------------------------------------------------------------------------- 1 | ## Versions available 2 | 3 | See the [%%SYSEXT%% versions](%%RELEASEURL%%/%%SYSEXT%%). 4 | 5 | ## Usage instructions 6 | 7 |
8 | First time setup 9 | Run those commands if you have not yet installed any sysext on your system: 10 | 11 | ``` 12 | sudo install -d -m 0755 -o 0 -g 0 /var/lib/extensions /var/lib/extensions.d 13 | sudo restorecon -RFv /var/lib/extensions /var/lib/extensions.d 14 | sudo systemctl enable --now systemd-sysext.service 15 | ``` 16 |
17 | 18 |
19 | Installation 20 | Define a helper function: 21 | 22 | ``` 23 | install_sysext() { 24 | SYSEXT="${1}" 25 | URL="%%EXTENSIONSURL%%" 26 | sudo install -d -m 0755 -o 0 -g 0 /etc/sysupdate.${SYSEXT}.d 27 | sudo restorecon -RFv /etc/sysupdate.${SYSEXT}.d 28 | curl --silent --fail --location "${URL}/${SYSEXT}.conf" \ 29 | | sudo tee "/etc/sysupdate.${SYSEXT}.d/${SYSEXT}.conf" 30 | sudo /usr/lib/systemd/systemd-sysupdate update --component "${SYSEXT}" 31 | } 32 | ``` 33 | 34 | Install the sysext: 35 | 36 | ``` 37 | install_sysext %%SYSEXT%% 38 | ``` 39 | 40 | Reboot your system or refresh the merged sysexts: 41 | 42 | ``` 43 | sudo systemctl restart systemd-sysext.service 44 | systemd-sysext status 45 | ``` 46 | 47 | Note that this will merge all installed sysexts unconditionally. 48 |
49 | 50 |
51 | Updates 52 | Update this sysext using: 53 | 54 | ``` 55 | sudo /usr/lib/systemd/systemd-sysupdate update --component %%SYSEXT%% 56 | ``` 57 | 58 | If you want to use the new version immediately, make sure to refresh the merged 59 | sysexts: 60 | 61 | ``` 62 | sudo systemctl restart systemd-sysext.service 63 | systemd-sysext status 64 | ``` 65 | 66 | To update all sysexts on a system: 67 | 68 | ``` 69 | for c in $(/usr/lib/systemd/systemd-sysupdate components --json=short | jq --raw-output '.components[]'); do 70 | sudo /usr/lib/systemd/systemd-sysupdate update --component "${c}" 71 | done 72 | ``` 73 |
74 | 75 |
76 | Uninstall 77 | Define a helper function: 78 | 79 | ``` 80 | uninstall_sysext() { 81 | SYSEXT="${1}" 82 | sudo rm -i "/var/lib/extensions/${SYSEXT}.raw" 83 | sudo rm -i "/var/lib/extensions.d/${SYSEXT}-"*".raw" 84 | sudo rm -i "/etc/sysupdate.${SYSEXT}.d/${SYSEXT}.conf" 85 | sudo rmdir "/etc/sysupdate.${SYSEXT}.d/" 86 | } 87 | ``` 88 | 89 | Uninstall the sysext: 90 | 91 | ``` 92 | uninstall_sysext %%SYSEXT%% 93 | ``` 94 | 95 | Reboot your system or refresh the merged sysexts: 96 | 97 | ``` 98 | sudo systemctl restart systemd-sysext.service 99 | systemd-sysext status 100 | ``` 101 |
102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fedora RPM based systemd system extensions for Fedora image based systems 2 | 3 | **NOTE: This project is a work in progress. Make sure to read the [known 4 | limitations section](https://extensions.fcos.fr). Use at your own risk.** 5 | 6 | This repo gathers sysexts made exclusively from official Fedora packages. 7 | 8 | The goal of this repo is to eventually become the source of official Fedora 9 | sysexts built in the Fedora infrastructure. 10 | 11 | For sysexts built from community provided sources, see 12 | [extensions.fcos.fr/community](https://extensions.fcos.fr/community). 13 | 14 | For general explainations about systemd system extensions (sysexts) and how 15 | to use them, see the documentation from the main page: 16 | [extensions.fcos.fr](https://extensions.fcos.fr). 17 | 18 | ## Disabling fetching tags 19 | 20 | This project uses GitHub releases to publish sysexts, and those releases also 21 | create Git tags, thus you might want to disable fetching tags for the remote 22 | using: 23 | 24 | ```bash 25 | git config remote.origin.tagopt "--no-tags" 26 | ``` 27 | 28 | and then remove all local tags with: 29 | 30 | ```bash 31 | git tag -l | xargs git tag -d > /dev/null 32 | ``` 33 | 34 | ## Building 35 | 36 | Building those images currently require `root` privileges. The currently 37 | supported options for building those sysexts are: 38 | - using a rootless, privileged, non-SELinux confined container (such as a 39 | toolbox/distrobox container), redirecting `podman` commands to run them on 40 | the host: 41 | ``` 42 | [toolbox]$ cat /usr/local/bin/podman 43 | #!/bin/bash 44 | executable="$(basename ${0})" 45 | exec flatpak-spawn --host "${executable}" "${@}" 46 | ``` 47 | - Using nested podman containers (current path in CI). 48 | 49 | Make sure that you have the following packages installed: 50 | - `cpio` 51 | - `erofs-utils` 52 | - `jq` 53 | - [`just`](https://github.com/casey/just) 54 | - `podman` (only when not using the host redirection script above) 55 | - `wget` 56 | 57 | To build the `python` sysext: 58 | 59 | ``` 60 | $ cd python 61 | ``` 62 | 63 | List the supported target images: 64 | 65 | ``` 66 | $ just targets 67 | ``` 68 | 69 | Build the sysext for Fedora CoreOS *next*: 70 | 71 | ``` 72 | $ just build "quay.io/fedora/fedora-coreos:next" 73 | ``` 74 | 75 | ## `extensions.fcos.fr` redirector 76 | 77 | A Caddy based redirector is hosted at `extensions.fcos.fr`. The configutation 78 | is available in the parent project's Caddyfile. It redirects URLs queried by 79 | `systemd-sysupdate` to GitHub releases where the sysexts are hosted in this 80 | repo. 81 | 82 | ## Contributing 83 | 84 | See [CONTRIBUTING](CONTRIBUTING.md) for details about the CI setup specific to 85 | this repo. 86 | 87 | ## Credits 88 | 89 | This project is heavily inspired by the work done by 90 | [Thilo](https://github.com/t-lo) on the 91 | [Flatcar sysext bakery](https://flatcar.github.io/sysext-bakery/). 92 | 93 | ## Licenses 94 | 95 | See [LICENSES](LICENSES). 96 | -------------------------------------------------------------------------------- /.github/actions/gather/action.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Timothée Ravier 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | name: "Gather versions for sysexts" 5 | description: "Publish a release that references all available versions for each sysext" 6 | 7 | # This composite action needs the following environment variables to be set at 8 | # the workflow or job level: 9 | # - RELEASEURL: Mandatory, needed to fetch older releases 10 | 11 | runs: 12 | using: "composite" 13 | steps: 14 | - name: "Publish release" 15 | env: 16 | GH_TOKEN: ${{ github.token }} 17 | if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main' 18 | shell: bash 19 | run: | 20 | set -euxo pipefail 21 | 22 | gh release list --limit 2000 --json tagName > releases.json 23 | 24 | for sysext in $(./.github/list_sysexts.sh); do 25 | rm -f ./SHA256SUMS* ./*.conf 26 | 27 | releases=( 28 | $( 29 | cat releases.json \ 30 | | jq --arg SYSEXT "${sysext}" --raw-output ' 31 | map( 32 | select( 33 | (.tagName | startswith($SYSEXT)) 34 | and 35 | (.tagName != $SYSEXT) 36 | ) 37 | ) 38 | | .[].tagName 39 | ' \ 40 | | sort -h 41 | ) 42 | ) 43 | echo "Looking at releases: ${releases[@]}" 44 | for rel in ${releases[@]}; do 45 | echo "Fetching SHA256SUMS for release: ${rel}" 46 | curl --location --fail --output "SHA256SUMS.${rel}" "${RELEASEURL}/${rel}/SHA256SUMS" || touch "SHA256SUMS.${rel}" 47 | done 48 | ls ./SHA256SUMS.* | sort -h | xargs cat > SHA256SUMS 49 | new="$(cat SHA256SUMS | sha256sum)" 50 | 51 | old="" 52 | echo "Fetching SHA256SUMS from release: ${sysext}" 53 | curl --location --fail --output SHA256SUMS.old "${RELEASEURL}/${sysext}/SHA256SUMS" || touch SHA256SUMS.old 54 | old="$(cat SHA256SUMS.old | sha256sum)" 55 | 56 | if [[ "${new}" == "${old}" ]]; then 57 | echo "No changes for ${sysext} since last release. Skipping." 58 | else 59 | echo "Creating new release: ${sysext}" 60 | 61 | sed "s/%%SYSEXT%%/${sysext}/g" .github/workflow-templates/systemd-sysupdate.conf > ${sysext}.conf 62 | 63 | { 64 | echo "Versions available:" 65 | echo "\`\`\`" 66 | cat ./SHA256SUMS 67 | echo "\`\`\`" 68 | } > notes 69 | 70 | gh release delete \ 71 | --cleanup-tag \ 72 | --yes \ 73 | "${sysext}" \ 74 | || true 75 | 76 | gh release create \ 77 | --title "${sysext} systemd system extensions for Fedora" \ 78 | --notes-file notes \ 79 | "${sysext}" \ 80 | --latest=false \ 81 | ./SHA256SUMS ./${sysext}.conf 82 | fi 83 | done 84 | 85 | rm -f ./SHA256SUMS* ./*.conf 86 | 87 | for sysext in $(./.github/list_sysexts.sh); do 88 | curl --location --fail --output "SHA256SUMS.${sysext}" "${RELEASEURL}/${sysext}/SHA256SUMS" || touch "SHA256SUMS.${sysext}" 89 | done 90 | ls ./SHA256SUMS.* | sort -h | xargs cat > SHA256SUMS 91 | 92 | echo "See SHA256SUMS from this release for all the versions available." > notes 93 | 94 | gh release delete \ 95 | --cleanup-tag \ 96 | --yes \ 97 | latest \ 98 | || true 99 | 100 | gh release create \ 101 | --title "systemd system extensions for Fedora" \ 102 | --notes-file notes \ 103 | latest \ 104 | --latest=true \ 105 | ./SHA256SUMS 106 | -------------------------------------------------------------------------------- /.github/workflow-templates/container_workflows.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-FileCopyrightText: Timothée Ravier 4 | # SPDX-License-Identifier: CC0-1.0 5 | 6 | # Re-generate the GitHub workflows based on templates. We do not use a matrix 7 | # build strategy in GitHub worflows to reduce overall build time and avoid 8 | # pulling the same base container image multiple time, once for each individual 9 | # job. 10 | 11 | set -euo pipefail 12 | # set -x 13 | 14 | main() { 15 | if [[ ! -d .github ]] || [[ ! -d .git ]]; then 16 | echo "This script must be run at the root of the repo" 17 | exit 1 18 | fi 19 | 20 | # Remove all existing worflows 21 | rm -f "./.github/workflows/containers"*".yml" 22 | 23 | generate \ 24 | 'quay.io/fedora/fedora-coreos' \ 25 | 'stable' \ 26 | 'x86_64' \ 27 | 'Fedora CoreOS' 28 | 29 | generate \ 30 | 'quay.io/fedora/fedora-coreos' \ 31 | 'stable' \ 32 | 'aarch64' \ 33 | 'Fedora CoreOS' 34 | 35 | generate \ 36 | 'quay.io/fedora/fedora-coreos' \ 37 | 'next' \ 38 | 'x86_64' \ 39 | 'Fedora CoreOS' 40 | 41 | generate \ 42 | 'quay.io/fedora/fedora-coreos' \ 43 | 'next' \ 44 | 'aarch64' \ 45 | 'Fedora CoreOS' 46 | 47 | generate \ 48 | 'quay.io/fedora-ostree-desktops/silverblue' \ 49 | '41' \ 50 | 'x86_64' \ 51 | 'Fedora Silverblue' 52 | 53 | generate \ 54 | 'quay.io/fedora-ostree-desktops/silverblue' \ 55 | '42' \ 56 | 'x86_64' \ 57 | 'Fedora Silverblue' 58 | 59 | generate \ 60 | 'quay.io/fedora-ostree-desktops/kinoite' \ 61 | '41' \ 62 | 'x86_64' \ 63 | 'Fedora Kinoite' 64 | 65 | generate \ 66 | 'quay.io/fedora-ostree-desktops/kinoite' \ 67 | '42' \ 68 | 'x86_64' \ 69 | 'Fedora Kinoite' 70 | } 71 | 72 | generate() { 73 | local -r image="${1}" 74 | local -r release="${2}" 75 | local -r arch="${3}" 76 | local -r name="${4}" 77 | local -r shortname="$(echo "${name}" | tr '[:upper:]' '[:lower:]' | sed 's/ /-/g')" 78 | 79 | # For containers only 80 | local -r registry="quay.io/travier" 81 | local -r destination_suffix="-sysexts" 82 | 83 | # Get the list of sysexts for a given target 84 | sysexts=() 85 | for s in $(git ls-tree -d --name-only HEAD | grep -Ev ".github|docs|LICENSES"); do 86 | pushd "${s}" > /dev/null 87 | # Only require the architecture to be explicitly listed for non x86_64 for now 88 | if [[ "${arch}" == "x86_64" ]]; then 89 | if [[ $(just targets | grep -c "${image}:${release}") == "1" ]]; then 90 | sysexts+=("${s}") 91 | fi 92 | else 93 | if [[ $(just targets | grep -cE "${image}:${release} .*${arch}.*") == "1" ]]; then 94 | sysexts+=("${s}") 95 | fi 96 | fi 97 | popd > /dev/null 98 | done 99 | 100 | local -r tmpl=".github/workflow-templates/" 101 | if [[ ! -d "${tmpl}" ]]; then 102 | echo "Could not find the templates. Is this script run from the root of the repo?" 103 | exit 1 104 | fi 105 | 106 | # Generate container sysexts workflows 107 | # Skip non x86-64 builds for now 108 | if [[ "${arch}" != "x86_64" ]]; then 109 | return 0 110 | fi 111 | { 112 | sed \ 113 | -e "s|%%IMAGE%%|${image}|g" \ 114 | -e "s|%%RELEASE%%|${release}|g" \ 115 | -e "s|%%NAME%%|${name}|g" \ 116 | -e "s|%%REGISTRY%%|${registry}|g" \ 117 | -e "s|%%DESTINATION%%|${shortname}${destination_suffix}|g" \ 118 | -e "s|%%ARCH%%|${arch}|g" \ 119 | "${tmpl}/containers_header" 120 | echo "" 121 | for s in "${sysexts[@]}"; do 122 | if [[ -f "${s}/Containerfile" ]]; then 123 | sed \ 124 | -e "s|%%SYSEXT%%|${s}|g" \ 125 | -e "s|%%SYSEXT_NODOT%%|${s//\./_}|g" \ 126 | "${tmpl}/containers_build" 127 | echo "" 128 | fi 129 | done 130 | 131 | # Skip pushing containers for now 132 | return 0 133 | 134 | cat "${tmpl}/containers_logincosign" 135 | echo "" 136 | for s in "${sysexts[@]}"; do 137 | if [[ -f "${s}/Containerfile" ]]; then 138 | sed \ 139 | -e "s|%%SYSEXT%%|${s}|g" \ 140 | -e "s|%%SYSEXT_NODOT%%|${s//\./_}|g" \ 141 | "${tmpl}/containers_pushsign" 142 | echo "" 143 | fi 144 | done 145 | } > ".github/workflows/containers-${shortname}-${release}.yml" 146 | } 147 | 148 | main "${@}" 149 | -------------------------------------------------------------------------------- /update_workflows.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-FileCopyrightText: Timothée Ravier 4 | # SPDX-License-Identifier: MIT 5 | 6 | # Re-generate the GitHub workflows based on templates. We do not use a matrix 7 | # build strategy in GitHub worflows to reduce overall build time and avoid 8 | # pulling the same base container image multiple time, once for each individual 9 | # job. 10 | 11 | set -euo pipefail 12 | # set -x 13 | 14 | main() { 15 | if [[ ! -d .github ]] || [[ ! -d .git ]]; then 16 | echo "This script must be run at the root of the repo" 17 | exit 1 18 | fi 19 | 20 | local -r tmpl=".github/workflow-templates" 21 | if [[ ! -d "${tmpl}" ]]; then 22 | echo "Could not find the templates. Is this script run from the root of the repo?" 23 | exit 1 24 | fi 25 | 26 | # Remove all existing worflows 27 | rm -f "./.github/workflows/containers"*".yml" 28 | rm -f "./.github/workflows/sysexts"*".yml" 29 | 30 | local -r releaseurl="https://github.com/\${{ github.repository }}/releases/download" 31 | 32 | arches=( 33 | 'x86_64' 34 | 'aarch64' 35 | ) 36 | 37 | images=( 38 | 'quay.io/fedora-ostree-desktops/base-atomic:42' 39 | 'quay.io/fedora-ostree-desktops/base-atomic:43' 40 | 'quay.io/fedora-ostree-desktops/silverblue:42' 41 | 'quay.io/fedora-ostree-desktops/silverblue:43' 42 | 'quay.io/fedora-ostree-desktops/kinoite:42' 43 | 'quay.io/fedora-ostree-desktops/kinoite:43' 44 | 'quay.io/fedora/fedora-coreos:stable' 45 | 'quay.io/fedora/fedora-coreos:next' 46 | ) 47 | 48 | # Set jobnames 49 | declare -A jobnames 50 | jobnames["quay.io/fedora-ostree-desktops/base-atomic:42"]="fedora-42" 51 | jobnames["quay.io/fedora-ostree-desktops/base-atomic:43"]="fedora-43" 52 | jobnames["quay.io/fedora-ostree-desktops/silverblue:42"]="fedora-silverblue-42" 53 | jobnames["quay.io/fedora-ostree-desktops/silverblue:43"]="fedora-silverblue-43" 54 | jobnames["quay.io/fedora-ostree-desktops/kinoite:42"]="fedora-kinoite-42" 55 | jobnames["quay.io/fedora-ostree-desktops/kinoite:43"]="fedora-kinoite-43" 56 | jobnames["quay.io/fedora/fedora-coreos:stable"]="fedora-coreos-stable" 57 | jobnames["quay.io/fedora/fedora-coreos:next"]="fedora-coreos-next" 58 | 59 | # Get the list of sysexts for each image and each arch 60 | declare -A sysexts 61 | for arch in "${arches[@]}"; do 62 | for image in "${images[@]}"; do 63 | list=() 64 | for s in $(git ls-tree -d --name-only HEAD | grep -Ev ".github|docs|LICENSES"); do 65 | pushd "${s}" > /dev/null 66 | # Only require the architecture to be explicitly listed for non x86_64 for now 67 | if [[ "${arch}" == "x86_64" ]]; then 68 | if [[ $(just targets | grep -c "${image}") == "1" ]]; then 69 | list+=("${s}") 70 | fi 71 | else 72 | if [[ $(just targets | grep -cE "${image} .*${arch}.*") == "1" ]]; then 73 | list+=("${s}") 74 | fi 75 | fi 76 | popd > /dev/null 77 | done 78 | sysexts["${image}-${arch}"]="$(echo "${list[@]}" | tr ' ' ';')" 79 | done 80 | done 81 | 82 | # Generate EROFS sysexts workflows 83 | { 84 | sed -e "s|%%RELEASEURL%%|${releaseurl}|g" \ 85 | "${tmpl}/00_sysexts_header" 86 | 87 | for arch in "${arches[@]}"; do 88 | runson="ubuntu-24.04" 89 | if [[ "${arch}" == "aarch64" ]]; then 90 | runson="ubuntu-24.04-arm" 91 | fi 92 | for image in "${images[@]}"; do 93 | sed -e "s|%%JOBNAME%%|${jobnames["${image}"]}-${arch}|g" \ 94 | -e "s|%%RUNSON%%|${runson}|g" \ 95 | -e "s|%%IMAGE%%|${image}|g" \ 96 | "${tmpl}/10_sysexts_build_header" 97 | echo "" 98 | for s in $(echo "${sysexts["${image}-${arch}"]}" | tr ';' ' '); do 99 | sed "s|%%SYSEXT%%|${s}|g" "${tmpl}/15_sysexts_build" 100 | echo "" 101 | done 102 | done 103 | done 104 | 105 | # TODO: Dynamic list of jobs to depend on 106 | all_sysexts=() 107 | for arch in "${arches[@]}"; do 108 | for image in "${images[@]}"; do 109 | for s in $(echo "${sysexts["${image}-${arch}"]}" | tr ';' ' '); do 110 | all_sysexts+=("${s}") 111 | done 112 | done 113 | done 114 | uniq_sysexts="$(echo "${all_sysexts[@]}" | tr ' ' '\n' | sort -u | tr '\n' ';')" 115 | sed -e "s|%%SYSEXTS%%|${uniq_sysexts}|g" "${tmpl}/20_sysexts_gather" 116 | } > ".github/workflows/sysexts-fedora.yml" 117 | } 118 | 119 | main "${@}" 120 | -------------------------------------------------------------------------------- /.github/actions/build/action.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Timothée Ravier 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | name: "Build and publish a sysext" 5 | description: "Build and publish a systemd system extension under a versioned release" 6 | inputs: 7 | sysext: 8 | description: "The sysext to build" 9 | required: true 10 | image: 11 | description: "The image to use as a base for the sysext" 12 | required: true 13 | 14 | # This composite action needs the following environment variables to be set at 15 | # the workflow or job level: 16 | # - RELEASEURL: Mandatory, needed to fetch older releases 17 | # - FORCE_REBUILD: Optional, used to force sysext's rebuild (and publication) 18 | 19 | runs: 20 | using: "composite" 21 | steps: 22 | - name: "Build sysext if needed" 23 | env: 24 | SYSEXT: ${{ inputs.sysext }} 25 | IMAGE: ${{ inputs.image }} 26 | PR: ${{ github.event_name == 'pull_request' }} 27 | shell: bash 28 | run: | 29 | set -euxo pipefail 30 | 31 | cd "${SYSEXT}" 32 | 33 | # For PRs, only build if the content changed 34 | if [[ "${PR}" == "true" ]]; then 35 | diff="$( 36 | git diff origin/main HEAD --stat -- . ; \ 37 | git diff origin/main HEAD --stat -- ../sysext.just 38 | )" 39 | if [[ -z "${diff}" ]]; then 40 | echo "Skipping: No changes for this sysext in this PR" 41 | exit 0 42 | fi 43 | echo "Detected changes for this sysext in this PR. Building." 44 | just build ${IMAGE} 45 | exit 0 46 | fi 47 | 48 | # Check if we are asked to force a rebuild 49 | if [ -n ${FORCE_REBUILD+x} ]; then 50 | if [[ "${FORCE_REBUILD}" == true ]]; then 51 | echo "Building (forced rebuild)" 52 | just build ${IMAGE} 53 | exit 0 54 | fi 55 | fi 56 | 57 | # Only build for releases if the inputs changed 58 | just prepare-build ${IMAGE} 59 | 60 | new="$(cat inputs | sha256sum)" 61 | 62 | VERSION_ID="$(cat ./version_id)" 63 | VERSION="$(cat ./version)" 64 | if [[ "$(uname -m)" == "x86_64" ]]; then 65 | ARCH="x86-64" 66 | elif [[ "$(uname -m)" == "aarch64" ]]; then 67 | ARCH="arm64" 68 | else 69 | echo "Unsupported architecture" 70 | exit 1 71 | fi 72 | TAGNAME="${SYSEXT}-${VERSION}-${VERSION_ID}-${ARCH}" 73 | 74 | echo "Fetching info from existing release: ${TAGNAME}" 75 | curl --location --fail --output inputs.old "${RELEASEURL}/${TAGNAME}/inputs" || touch inputs.old 76 | old="$(cat inputs.old | sha256sum)" 77 | 78 | if [[ "${new}" == "${old}" ]]; then 79 | echo "No changes in inputs since last release. Skipping." 80 | exit 0 81 | fi 82 | 83 | echo "Detected changes. Building new sysext for: ${TAGNAME}" 84 | just resume-build ${IMAGE} 85 | 86 | - name: "Publish sysext" 87 | env: 88 | SYSEXT: ${{ inputs.sysext }} 89 | GH_TOKEN: ${{ github.token }} 90 | if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main' 91 | shell: bash 92 | run: | 93 | set -euxo pipefail 94 | 95 | git config --global --add safe.directory "${PWD}" 96 | 97 | cd "${SYSEXT}" 98 | 99 | VERSION="$(cat ./version)" 100 | VERSION_ID="$(cat ./version_id)" 101 | if [[ "$(uname -m)" == "x86_64" ]]; then 102 | ARCH="x86-64" 103 | elif [[ "$(uname -m)" == "aarch64" ]]; then 104 | ARCH="arm64" 105 | else 106 | echo "Unsupported architecture" 107 | exit 1 108 | fi 109 | TAGNAME="${SYSEXT}-${VERSION}-${VERSION_ID}-${ARCH}" 110 | 111 | if [[ ! -f "./${TAGNAME}.raw" ]]; then 112 | echo "No sysext built. Skipping." 113 | exit 0 114 | fi 115 | 116 | echo "Creating new release for: ${TAGNAME}" 117 | 118 | sha256sum *.raw > SHA256SUMS 119 | 120 | { 121 | echo "Release:" 122 | echo "\`\`\`" 123 | cat ./SHA256SUMS 124 | echo "\`\`\`" 125 | echo "" 126 | echo "Built using container image:" 127 | echo "\`\`\`" 128 | cat ./digest 129 | echo "\`\`\`" 130 | echo "" 131 | echo "Built using input files:" 132 | echo "\`\`\`" 133 | cat ./inputs 134 | echo "\`\`\`" 135 | echo "" 136 | echo "Built using scripts:" 137 | echo "\`\`\`" 138 | cat ./scripts 139 | echo "\`\`\`" 140 | } > notes 141 | 142 | gh release delete \ 143 | --cleanup-tag \ 144 | --yes \ 145 | "${TAGNAME}" \ 146 | || true 147 | 148 | # Wait a bit to avoid API errors and reduce flakes 149 | sleep 2 150 | 151 | # Ignore failures as those are generally GitHub API flakes and the 152 | # release does get created. If it does not, it will be on the next run. 153 | gh release create \ 154 | --title "${SYSEXT} ${VERSION} for Fedora ${VERSION_ID} (${ARCH})" \ 155 | --notes-file notes \ 156 | "${TAGNAME}" \ 157 | --latest=false \ 158 | ./*.raw ./SHA256SUMS ./inputs ./scripts ./digest \ 159 | || true 160 | -------------------------------------------------------------------------------- /docs/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | addressable (2.8.7) 5 | public_suffix (>= 2.0.2, < 7.0) 6 | base64 (0.2.0) 7 | bigdecimal (3.1.9) 8 | colorator (1.1.0) 9 | concurrent-ruby (1.3.5) 10 | csv (3.3.4) 11 | em-websocket (0.5.3) 12 | eventmachine (>= 0.12.9) 13 | http_parser.rb (~> 0) 14 | eventmachine (1.2.7) 15 | ffi (1.17.2) 16 | ffi (1.17.2-aarch64-linux-gnu) 17 | ffi (1.17.2-aarch64-linux-musl) 18 | ffi (1.17.2-arm-linux-gnu) 19 | ffi (1.17.2-arm-linux-musl) 20 | ffi (1.17.2-arm64-darwin) 21 | ffi (1.17.2-x86-linux-gnu) 22 | ffi (1.17.2-x86-linux-musl) 23 | ffi (1.17.2-x86_64-darwin) 24 | ffi (1.17.2-x86_64-linux-gnu) 25 | ffi (1.17.2-x86_64-linux-musl) 26 | forwardable-extended (2.6.0) 27 | google-protobuf (4.30.2) 28 | bigdecimal 29 | rake (>= 13) 30 | google-protobuf (4.30.2-aarch64-linux) 31 | bigdecimal 32 | rake (>= 13) 33 | google-protobuf (4.30.2-arm64-darwin) 34 | bigdecimal 35 | rake (>= 13) 36 | google-protobuf (4.30.2-x86-linux) 37 | bigdecimal 38 | rake (>= 13) 39 | google-protobuf (4.30.2-x86_64-darwin) 40 | bigdecimal 41 | rake (>= 13) 42 | google-protobuf (4.30.2-x86_64-linux) 43 | bigdecimal 44 | rake (>= 13) 45 | http_parser.rb (0.8.0) 46 | i18n (1.14.7) 47 | concurrent-ruby (~> 1.0) 48 | jekyll (4.4.1) 49 | addressable (~> 2.4) 50 | base64 (~> 0.2) 51 | colorator (~> 1.0) 52 | csv (~> 3.0) 53 | em-websocket (~> 0.5) 54 | i18n (~> 1.0) 55 | jekyll-sass-converter (>= 2.0, < 4.0) 56 | jekyll-watch (~> 2.0) 57 | json (~> 2.6) 58 | kramdown (~> 2.3, >= 2.3.1) 59 | kramdown-parser-gfm (~> 1.0) 60 | liquid (~> 4.0) 61 | mercenary (~> 0.3, >= 0.3.6) 62 | pathutil (~> 0.9) 63 | rouge (>= 3.0, < 5.0) 64 | safe_yaml (~> 1.0) 65 | terminal-table (>= 1.8, < 4.0) 66 | webrick (~> 1.7) 67 | jekyll-include-cache (0.2.1) 68 | jekyll (>= 3.7, < 5.0) 69 | jekyll-remote-theme (0.4.3) 70 | addressable (~> 2.0) 71 | jekyll (>= 3.5, < 5.0) 72 | jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0) 73 | rubyzip (>= 1.3.0, < 3.0) 74 | jekyll-sass-converter (3.0.0) 75 | sass-embedded (~> 1.54) 76 | jekyll-seo-tag (2.8.0) 77 | jekyll (>= 3.8, < 5.0) 78 | jekyll-watch (2.2.1) 79 | listen (~> 3.0) 80 | json (2.10.2) 81 | just-the-docs (0.10.1) 82 | jekyll (>= 3.8.5) 83 | jekyll-include-cache 84 | jekyll-seo-tag (>= 2.0) 85 | rake (>= 12.3.1) 86 | kramdown (2.5.1) 87 | rexml (>= 3.3.9) 88 | kramdown-parser-gfm (1.1.0) 89 | kramdown (~> 2.0) 90 | liquid (4.0.4) 91 | listen (3.9.0) 92 | rb-fsevent (~> 0.10, >= 0.10.3) 93 | rb-inotify (~> 0.9, >= 0.9.10) 94 | logger (1.7.0) 95 | mercenary (0.4.0) 96 | ostruct (0.6.1) 97 | pathutil (0.16.2) 98 | forwardable-extended (~> 2.6) 99 | public_suffix (6.0.1) 100 | rake (13.2.1) 101 | rb-fsevent (0.11.2) 102 | rb-inotify (0.11.1) 103 | ffi (~> 1.0) 104 | rexml (3.4.1) 105 | rouge (4.5.1) 106 | rubyzip (2.4.1) 107 | safe_yaml (1.0.5) 108 | sass-embedded (1.86.3) 109 | google-protobuf (~> 4.30) 110 | rake (>= 13) 111 | sass-embedded (1.86.3-aarch64-linux-android) 112 | google-protobuf (~> 4.30) 113 | sass-embedded (1.86.3-aarch64-linux-gnu) 114 | google-protobuf (~> 4.30) 115 | sass-embedded (1.86.3-aarch64-linux-musl) 116 | google-protobuf (~> 4.30) 117 | sass-embedded (1.86.3-aarch64-mingw-ucrt) 118 | google-protobuf (~> 4.30) 119 | sass-embedded (1.86.3-arm-linux-androideabi) 120 | google-protobuf (~> 4.30) 121 | sass-embedded (1.86.3-arm-linux-gnueabihf) 122 | google-protobuf (~> 4.30) 123 | sass-embedded (1.86.3-arm-linux-musleabihf) 124 | google-protobuf (~> 4.30) 125 | sass-embedded (1.86.3-arm64-darwin) 126 | google-protobuf (~> 4.30) 127 | sass-embedded (1.86.3-riscv64-linux-android) 128 | google-protobuf (~> 4.30) 129 | sass-embedded (1.86.3-riscv64-linux-gnu) 130 | google-protobuf (~> 4.30) 131 | sass-embedded (1.86.3-riscv64-linux-musl) 132 | google-protobuf (~> 4.30) 133 | sass-embedded (1.86.3-x86_64-darwin) 134 | google-protobuf (~> 4.30) 135 | sass-embedded (1.86.3-x86_64-linux-android) 136 | google-protobuf (~> 4.30) 137 | sass-embedded (1.86.3-x86_64-linux-gnu) 138 | google-protobuf (~> 4.30) 139 | sass-embedded (1.86.3-x86_64-linux-musl) 140 | google-protobuf (~> 4.30) 141 | terminal-table (3.0.2) 142 | unicode-display_width (>= 1.1.1, < 3) 143 | unicode-display_width (2.6.0) 144 | webrick (1.9.1) 145 | 146 | PLATFORMS 147 | aarch64-linux 148 | aarch64-linux-android 149 | aarch64-linux-gnu 150 | aarch64-linux-musl 151 | aarch64-mingw-ucrt 152 | arm-linux-androideabi 153 | arm-linux-gnu 154 | arm-linux-gnueabihf 155 | arm-linux-musl 156 | arm-linux-musleabihf 157 | arm64-darwin 158 | riscv64-linux-android 159 | riscv64-linux-gnu 160 | riscv64-linux-musl 161 | ruby 162 | x86-linux 163 | x86-linux-gnu 164 | x86-linux-musl 165 | x86_64-darwin 166 | x86_64-linux-android 167 | x86_64-linux-gnu 168 | x86_64-linux-musl 169 | 170 | DEPENDENCIES 171 | base64 172 | csv 173 | jekyll (~> 4.3) 174 | jekyll-remote-theme (~> 0.4.3) 175 | just-the-docs 176 | logger 177 | ostruct 178 | webrick (~> 1.8) 179 | 180 | BUNDLED WITH 181 | 2.6.2 182 | -------------------------------------------------------------------------------- /LICENSES/CC0-1.0.txt: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /sysext.just: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Timothée Ravier 2 | # SPDX-License-Identifier: MIT 3 | 4 | # Do no use this justfile directly. See sub-directories. 5 | 6 | # Explicitely allow overriding variables and recipes in justfiles importing this one 7 | set allow-duplicate-variables := true 8 | set allow-duplicate-recipes := true 9 | 10 | # Default to base-atomic images for x86_64 & aarch64 for the current branched, 11 | # stable and old stable Fedora releases. Can be override on a per sysext basis. 12 | base_images := " 13 | quay.io/fedora-ostree-desktops/base-atomic:42 x86_64,aarch64 14 | quay.io/fedora-ostree-desktops/base-atomic:43 x86_64,aarch64 15 | " 16 | 17 | # Default to building for the current architecture 18 | arch := arch() 19 | 20 | # Do not download any packages by default 21 | packages := "" 22 | 23 | # Package to use to set the version for a sysext 24 | version_package := "" 25 | 26 | # Do not enable additional repos by default 27 | enable_repos := "" 28 | 29 | # Do not enable any Copr repos by default 30 | copr_repos := "" 31 | 32 | # Do not enable RPM Fusion repos by default 33 | rpm_fusion_repos := "" 34 | 35 | # Disable repos from the build container 36 | disable_repos := "" 37 | 38 | # Do not enable any external repos by default 39 | external_repos := "" 40 | 41 | # Do not run any commands before downloading RPMs by default 42 | pre_commands := "" 43 | 44 | # Install weak dependencies by default 45 | dnf_weak_deps := "" 46 | 47 | # Do not exclude any dependency by default 48 | exclude_packages := "" 49 | 50 | # Default to noarch + current architecture 51 | dnf_arch := "" 52 | 53 | # Do not install any additional files by default 54 | files := "" 55 | 56 | # Path to files to manually exclude from the sysext 57 | cleanup_files := "" 58 | 59 | # Do not setup any upholds for units by default 60 | upholds := "" 61 | 62 | # zstd compression is still experimental in EROFS 63 | # compression := "zstd" 64 | compression := "lz4" 65 | 66 | # Print more logs to help debugging. Enable by setting JUST_DEBUG env variable. 67 | # Default to false. 68 | debug := env('JUST_DEBUG', '') 69 | 70 | # Set JUST_PODMAN_EXTRA_OPTS to pass extra opts to podman commands. 71 | # Use '--pull=never' for example to disable image update checks and pulls 72 | podman_extra_opts := env('JUST_PODMAN_EXTRA_OPTS', '') 73 | 74 | # Default podman options 75 | podman_opts := "--rm --arch=" + arch + " --security-opt label=disable" + podman_extra_opts 76 | 77 | # Default, empty, just recipe 78 | default: 79 | #!/bin/bash 80 | set -euo pipefail 81 | # set -x 82 | 83 | echo "Usage: 'just build '" 84 | echo "" 85 | echo "Valid targets for this sysext:" 86 | echo "{{base_images}}" 87 | 88 | # Main recipe with all the steps to use to build a sysext 89 | build target arch=arch: \ 90 | (check target arch) \ 91 | clean \ 92 | (download-rpms target arch) \ 93 | (download-manual arch) \ 94 | version \ 95 | (inputs target arch) \ 96 | (setup-rootfs target arch) \ 97 | install-rpms \ 98 | install-files \ 99 | install-manual \ 100 | move-etc \ 101 | validate \ 102 | (reset-selinux-labels target arch) \ 103 | (build-erofs target arch) 104 | 105 | # Split recipes for faster skip-builds in CI: Only download and generate inputs 106 | prepare-build target arch=arch: \ 107 | (check target arch) \ 108 | clean \ 109 | (download-rpms target arch) \ 110 | (download-manual arch) \ 111 | version \ 112 | (inputs target arch) 113 | 114 | # Split recipes for faster skip-builds in CI: Only builds, must be call after prepare-build 115 | resume-build target arch=arch: \ 116 | (setup-rootfs target arch) \ 117 | install-rpms \ 118 | install-files \ 119 | install-manual \ 120 | move-etc \ 121 | validate \ 122 | (reset-selinux-labels target arch) \ 123 | (build-erofs target arch) 124 | 125 | # List the supported targets for this sysext. To use in CI and scripting 126 | targets: 127 | #!/bin/bash 128 | set -euo pipefail 129 | if [[ -n "{{debug}}" ]]; then 130 | set -x 131 | fi 132 | 133 | if [[ -z "{{base_images}}" ]]; then 134 | echo "sysexts must explicitely say which base operating system images they support" 135 | exit 1 136 | fi 137 | 138 | echo "{{base_images}}" | { grep -v "^$" || test $? = 1; } 139 | 140 | # Sanity check that some variables are set 141 | check target arch=arch: 142 | #!/bin/bash 143 | set -euo pipefail 144 | if [[ -n "{{debug}}" ]]; then 145 | set -x 146 | fi 147 | 148 | # Make sure that the sysext lists the base images that it supports 149 | if [[ -z "{{base_images}}" ]]; then 150 | echo "sysexts must explicitely say which base operating system images they support" 151 | exit 1 152 | fi 153 | 154 | # Make sure that the current target is in the supported list 155 | found=false 156 | mapfile -t baseimages <<< "{{base_images}}" 157 | for base in "${baseimages[@]}"; do 158 | if [[ -z "${base}" ]]; then 159 | continue 160 | fi 161 | # echo "Checking against: $base" 162 | # Split on whitespace 163 | baseimage=($base) 164 | if [[ "${baseimage[0]}" == {{target}} ]]; then 165 | # echo "Base image name matched: ${baseimage[0]}" 166 | # Ignore architecture check if nothing is specified and architecture is x86_64 167 | # echo "${baseimage[@]} ${#baseimage[@]}" 168 | if [[ "${#baseimage[@]}" -eq 1 ]]; then 169 | # echo "No architecture set for base image" 170 | if [[ "{{arch}}" == "x86_64" ]]; then 171 | found=true 172 | break 173 | fi 174 | # Otherwise skip this entry as we can not be sure it's supported 175 | # echo "Potentially unsupported arch for this image: {{arch}}" 176 | break 177 | fi 178 | IFS=',' 179 | # Check if the architecture is in the list 180 | read -ra arches <<< "${baseimage[1]}" 181 | unset IFS 182 | # echo "Architectures available: ${arches[@]}" 183 | for a in "${arches[@]}"; do 184 | # echo "Looking at: ${a}" 185 | if [[ "${a}" == "{{arch}}" ]]; then 186 | found=true 187 | break 188 | fi 189 | done 190 | # Break again out of the loop if found 191 | if [[ "${found}" == true ]]; then 192 | break 193 | fi 194 | fi 195 | done 196 | if [[ ${found} == "false" ]]; then 197 | echo "{{target}} {{arch}} is not listed as a supported base image for this sysext" 198 | echo "" 199 | echo "Valid targets for this sysext:" 200 | echo "{{base_images}}" 201 | exit 1 202 | fi 203 | 204 | # Download RPMs to install. Use the following variables: 205 | # - packages: List of packages to download (and later install) 206 | # - enable_repos: List of additional repos to enable 207 | download-rpms target arch=arch: 208 | #!/bin/bash 209 | set -euo pipefail 210 | if [[ -n "{{debug}}" ]]; then 211 | set -x 212 | fi 213 | 214 | # Skip this step if we have not been asked to download packages 215 | if [[ -z "{{packages}}" ]]; then 216 | exit 0 217 | fi 218 | 219 | enablerepos="" 220 | if [[ -n "{{enable_repos}}" ]]; then 221 | for r in {{enable_repos}}; do 222 | echo "➕ Enabling repo: ${r}" 223 | enablerepos+=" --enablerepo=${r}" 224 | done 225 | fi 226 | 227 | disablerepos="" 228 | if [[ -n "{{disable_repos}}" ]]; then 229 | for r in {{disable_repos}}; do 230 | echo "➖ Disabling repo: ${r}" 231 | disablerepos+=" --disablerepo=${r}" 232 | done 233 | fi 234 | 235 | dnf_arch="" 236 | if [[ -z "{{dnf_arch}}" ]]; then 237 | dnf_arches="noarch {{arch}}" 238 | else 239 | dnf_arches="{{dnf_arch}}" 240 | fi 241 | for a in ${dnf_arches}; do 242 | dnf_arch+="--arch=${a} " 243 | done 244 | 245 | dnf_opts="" 246 | if [[ "{{dnf_weak_deps}}" == false ]]; then 247 | dnf_opts="--setopt=install_weak_deps=False" 248 | fi 249 | if [[ -n "{{exclude_packages}}" ]]; then 250 | excluded_packages="$(echo "{{exclude_packages}}" | xargs)" 251 | for p in ${excluded_packages}; do 252 | echo "➖ Excluding package: ${p}" 253 | dnf_opts+=" --exclude=${p}" 254 | done 255 | fi 256 | 257 | packages="$(echo "{{packages}}" | xargs)" 258 | 259 | # Always disable the openh264 repo by default 260 | pre_commands="dnf5 config-manager setopt fedora-cisco-openh264.enabled=0; " 261 | 262 | if [[ -n "{{pre_commands}}" ]]; then 263 | pre_commands+="{{pre_commands}} ; " 264 | fi 265 | if [[ -n "{{copr_repos}}" ]]; then 266 | pre_commands+="dnf install -y dnf5-plugins" 267 | for r in "{{copr_repos}}"; do 268 | pre_commands+=" ; dnf copr enable -y ${r}" 269 | done 270 | pre_commands+=" ; " 271 | fi 272 | if [[ -n "{{external_repos}}" ]]; then 273 | pre_commands+="dnf install -y dnf5-plugins" 274 | external_repos="$(echo "{{external_repos}}" | xargs)" 275 | for r in ${external_repos}; do 276 | pre_commands+=" ; dnf config-manager addrepo --from-repofile=${r}" 277 | done 278 | pre_commands+=" ; " 279 | fi 280 | 281 | if [[ -n "{{rpm_fusion_repos}}" ]]; then 282 | release=$(podman run {{podman_opts}} "{{target}}" \ 283 | bash -c 'rpm -E %fedora' | tr -d '\n') 284 | for r in {{rpm_fusion_repos}}; do 285 | if [[ "${r}" != "free" ]] && [[ "${r}" != "nonfree" ]]; then 286 | echo "Unrecognized RPM Fusion repo: ${r}" 287 | exit 1 288 | fi 289 | echo "➕ Enabling RPM Fusion repo: '${r}'" 290 | pre_commands+=" dnf install -y https://mirrors.rpmfusion.org/${r}/fedora/rpmfusion-${r}-release-${release}.noarch.rpm ;" 291 | done 292 | fi 293 | 294 | mkdir -p ../.dnf-cache 295 | 296 | mkdir rpms 297 | cd rpms 298 | 299 | echo "⬇️ Downloading packages (${dnf_arches}): ${packages}" 300 | # dnf install --downloadonly --downloaddir . ${dnf_arch} ${enablerepos} ${packages} 301 | podman run -ti {{podman_opts}} \ 302 | --volume "${PWD}:/var/srv" \ 303 | --volume "${PWD}/../../.dnf-cache:/var/cache/libdnf5" \ 304 | --workdir "/var/srv" \ 305 | "{{target}}" \ 306 | bash -xc "export FORCE_COLUMNS=100 && ${pre_commands}dnf download --resolve ${dnf_arch} ${dnf_opts} ${disablerepos} ${enablerepos} ${packages}" 307 | 308 | # Manual download step, that can be overridden to dowload non RPM content 309 | download-manual arch=arch: 310 | #!/bin/bash 311 | set -euo pipefail 312 | # set -x 313 | exit 0 314 | 315 | # Recipe to override to set a custom version 316 | version: 317 | #!/bin/bash 318 | set -euo pipefail 319 | if [[ -n "{{debug}}" ]]; then 320 | set -x 321 | fi 322 | 323 | package_version() { 324 | rpm="${1}" 325 | epoch="$(rpm -qp --queryformat '%{EPOCH}' ${rpm})" 326 | version="$(rpm -qp --queryformat '%{VERSION}-%{RELEASE}' ${rpm})" 327 | if [[ "${epoch}" == "(none)" ]]; then 328 | epoch="" 329 | else 330 | epoch="${epoch}-" 331 | fi 332 | echo "${epoch}${version}" > ./version 333 | } 334 | 335 | echo "🏷️ Writing down version" 336 | 337 | if [[ -n "{{version_package}}" ]]; then 338 | if [[ $(ls rpms/*.rpm | grep -cE "^rpms/{{version_package}}-[0-9]" ) -ne 1 ]]; then 339 | echo "More than one package matched: {{version_package}}." 340 | exit 1 341 | fi 342 | rpm="$(ls rpms/*.rpm | sort -h | grep -E "^rpms/{{version_package}}-[0-9]" | head -1)" 343 | package_version "${rpm}" 344 | exit 0 345 | fi 346 | 347 | if [[ -z "{{packages}}" ]]; then 348 | echo "No package listed. You must define the 'version' recipe in your justfile for this sysext." 349 | exit 1 350 | fi 351 | 352 | packages=($(echo "{{packages}}" | xargs)) 353 | 354 | if [[ ${#packages[@]} -ne 1 ]]; then 355 | if [[ $(ls rpms/*.rpm | grep -cE "^rpms/{{name}}-[0-9]") -ne 1 ]]; then 356 | echo "More that one package listed. Set 'version_package' or define the 'version' recipe in your justfile for this sysext." 357 | exit 1 358 | fi 359 | rpm="$(ls rpms/*.rpm | sort -h | grep -E "^rpms/{{name}}-[0-9]" | head -1)" 360 | package_version "${rpm}" 361 | exit 0 362 | fi 363 | 364 | # Only one package listed, let's use its version 365 | rpm="$(ls rpms/${packages[0]}*.rpm | sort -h | head -1)" 366 | package_version "${rpm}" 367 | 368 | # Generate 'inputs' files for change detection in CI 369 | inputs target arch=arch: 370 | #!/bin/bash 371 | set -euo pipefail 372 | if [[ -n "{{debug}}" ]]; then 373 | set -x 374 | fi 375 | 376 | echo "🏷️ Writing down inputs" 377 | 378 | # Make sure that we always have a version set 379 | version="" 380 | if [[ -f ./version ]]; then 381 | version="$(cat ./version)" 382 | else 383 | version=$(podman run {{podman_opts}} "{{target}}" \ 384 | bash -c 'source /etc/os-release ; echo -n ${OSTREE_VERSION}') 385 | fi 386 | # Remove special characters from the version 387 | version="$(cat ./version | sed "s/\^/_/" | sed "s/:/_/")" 388 | # Write back version to file 389 | echo "${version}" > ./version 390 | 391 | # Get and store name, tag and digest for the container image used to build the sysext 392 | echo "{{target}}@$(podman inspect {{target}} | jq -r '.[0].Digest')" > ./digest 393 | 394 | # Store version_id (Fedora release) 395 | version_id=$(podman run {{podman_opts}} "{{target}}" \ 396 | bash -c 'source /etc/os-release ; echo -n ${VERSION_ID}') 397 | echo "${version_id}" > ./version_id 398 | 399 | # Store the hashes of the RPMs used to build the sysext 400 | if [[ -d ./rpms ]]; then 401 | cd rpms 402 | sha256sum *.rpm >> ../inputs 403 | cd .. 404 | fi 405 | # Store the hashes of all the files added to the sysext 406 | if [[ -n "{{files}}" ]]; then 407 | for f in {{files}}; do 408 | find ${f} -type f | sort -h | xargs sha256sum >> ./inputs 409 | done 410 | fi 411 | # Make sure that we have an inputs file in all cases 412 | touch ./inputs 413 | 414 | # Store the hashes of the scripts used to build the sysext 415 | sha256sum justfile >> ./scripts 416 | cd .. 417 | sha256sum sysext.just >> ./{{name}}/scripts 418 | 419 | # Sets up the rootfs directory and creates the extension release config 420 | setup-rootfs target arch=arch: 421 | #!/bin/bash 422 | set -euo pipefail 423 | if [[ -n "{{debug}}" ]]; then 424 | set -x 425 | fi 426 | 427 | if [[ "${UID}" == "0" ]]; then 428 | SUDO="" 429 | else 430 | SUDO="sudo" 431 | fi 432 | 433 | version_id="$(cat ./version_id)" 434 | 435 | mkdir rootfs 436 | cd rootfs 437 | 438 | # Only ask systemd to reload its configuration if we have services to 439 | # uphold / start on boot 440 | reload_manager="false" 441 | 442 | # Filter the variable into an array 443 | upholds=() 444 | mapfile -t upholds_raw <<< "{{upholds}}" 445 | for uphold in "${upholds_raw[@]}"; do 446 | if [[ -z "${uphold}" ]]; then 447 | continue 448 | fi 449 | upholds+=("${uphold}") 450 | done 451 | # Setup upholds if there are any 452 | if [[ "${#upholds[@]}" -ne 0 ]]; then 453 | # Set now, but will be used later in the extension config file 454 | reload_manager="true" 455 | echo "➡️ Setting up upholds for: ${upholds[@]}" 456 | ${SUDO} install -d -m 0755 -o 0 -g 0 usr/lib/systemd/system/multi-user.target.d 457 | { 458 | echo "[Unit]" 459 | for uphold in "${upholds[@]}"; do 460 | echo "Upholds=${uphold}" 461 | done 462 | } | ${SUDO} tee "usr/lib/systemd/system/multi-user.target.d/10-{{name}}-sysext.conf" > /dev/null 463 | fi 464 | 465 | # Post process architecture to match systemd architecture list 466 | if [[ {{arch}} == "x86_64" ]]; then 467 | arch="x86-64" 468 | elif [[ {{arch}} == "aarch64" ]]; then 469 | arch="arm64" 470 | else 471 | echo "Unsupported architecture" 472 | exit 1 473 | fi 474 | 475 | echo "➡️ Setting up extension config file" 476 | ${SUDO} install -d -m0755 usr/lib/extension-release.d 477 | { 478 | # We can not restict the ID to `fedora` here as it will break support for 479 | # Universal Blue. See: https://github.com/systemd/systemd/pull/37648 480 | echo "ID=\"_any\"" 481 | echo "VERSION_ID=\"${version_id}\"" 482 | echo "ARCHITECTURE=\"${arch}\"" 483 | if [[ "${reload_manager}" == "true" ]]; then 484 | echo "EXTENSION_RELOAD_MANAGER=1" 485 | fi 486 | } | ${SUDO} tee "usr/lib/extension-release.d/extension-release.{{name}}" > /dev/null 487 | 488 | # Install (extract) RPM packages download in download-rpms recipe. Uses: 489 | # - packages: List of packages to install 490 | install-rpms: 491 | #!/bin/bash 492 | set -euo pipefail 493 | if [[ -n "{{debug}}" ]]; then 494 | set -x 495 | fi 496 | 497 | # Skip this step if we have not been asked to install packages 498 | if [[ -z "{{packages}}" ]]; then 499 | exit 0 500 | fi 501 | 502 | if [[ "${UID}" == "0" ]]; then 503 | SUDO="" 504 | else 505 | SUDO="sudo" 506 | fi 507 | 508 | cd rootfs 509 | 510 | echo "📦 Extracting packages:" 511 | for rpm in ../rpms/*.rpm; do 512 | echo "$(basename ${rpm})" 513 | rpm2cpio "${rpm}" > ${rpm}.tar 514 | ${SUDO} cpio -idmv &> /dev/null < ${rpm}.tar 515 | rm ${rpm}.tar 516 | done 517 | 518 | # Install files from the current directory. Uses: 519 | # - files: List of folders or files to copy to `rootfs`. Use either `usr` or 520 | # `opt` as everything else is ignored. Spaces are not supported. 521 | install-files: 522 | #!/bin/bash 523 | set -euo pipefail 524 | if [[ -n "{{debug}}" ]]; then 525 | set -x 526 | fi 527 | 528 | # Skip this step if we have not been asked to copy files 529 | if [[ -z "{{files}}" ]]; then 530 | exit 0 531 | fi 532 | 533 | if [[ "${UID}" == "0" ]]; then 534 | SUDO="" 535 | else 536 | SUDO="sudo" 537 | fi 538 | 539 | cd rootfs 540 | 541 | echo "📁 Copying additional files from: {{files}}" 542 | for f in {{files}}; do 543 | ${SUDO} cp -a ../${f} . 544 | done 545 | 546 | # Manual installation step, that can be overridden to install non RPM content 547 | # or fixup issues after RPM installation. 548 | install-manual: 549 | #!/bin/bash 550 | set -euo pipefail 551 | if [[ -n "{{debug}}" ]]; then 552 | set -x 553 | fi 554 | exit 0 555 | 556 | # Move /etc to /usr/etc. Might be converted to a confext generator. 557 | move-etc: 558 | #!/bin/bash 559 | set -euo pipefail 560 | if [[ -n "{{debug}}" ]]; then 561 | set -x 562 | fi 563 | 564 | if [[ "${UID}" == "0" ]]; then 565 | SUDO="" 566 | else 567 | SUDO="sudo" 568 | fi 569 | 570 | cd rootfs 571 | 572 | if [[ -d ./etc ]] then 573 | echo "➡️ Moving /etc to /usr/etc" 574 | ${SUDO} mv --no-clobber --no-copy ./etc ./usr/etc 575 | fi 576 | 577 | # Validation pass that checks for common errors and will also try to fix some 578 | # common cases: 579 | # - Cleanup files as requested in the justfile 580 | # - Remove all empty directories in /var, /run and /opt 581 | # - Try to merge the content of /usr/sbin with /usr/bin for Fedora 42 and later 582 | # - Run the checks 583 | validate: 584 | #!/bin/bash 585 | set -euo pipefail 586 | if [[ -n "{{debug}}" ]]; then 587 | set -x 588 | fi 589 | 590 | # Some checks vary by Fedora release 591 | version_id="$(cat ./version_id)" 592 | 593 | failed_checks=0 594 | 595 | if [[ "${UID}" == "0" ]]; then 596 | SUDO="" 597 | else 598 | SUDO="sudo" 599 | fi 600 | 601 | cd rootfs 602 | 603 | # Remove files as requested 604 | if [[ -n "{{cleanup_files}}" ]]; then 605 | cleanup=($(echo "{{cleanup_files}}" | xargs)) 606 | for f in "${cleanup[@]}"; do 607 | echo "🧹 Cleaning up file: ${f}" 608 | rm ./${f} 609 | done 610 | fi 611 | 612 | # Remove all empty directories in /var, /run and /opt 613 | for d in 'var' 'run' 'opt'; do 614 | if [[ -d "./${d}" ]]; then 615 | echo "🧹 Cleaning up empty directories in /${d}" 616 | ${SUDO} find "./${d}" -type d -empty -delete 617 | fi 618 | done 619 | 620 | # Try to merge /lib64 with /usr/lib64 621 | if [[ -d "lib64" ]]; then 622 | echo "➡️ Moving /lib64 to /usr/lib64" 623 | if [[ ! -d "usr/lib64" ]]; then 624 | install -dm 0755 ./usr/lib64 625 | fi 626 | ${SUDO} mv --verbose --no-clobber ./lib64/* ./usr/lib64 627 | ${SUDO} rmdir lib64 628 | fi 629 | 630 | # Try to merge /usr/sbin with /usr/bin for Fedora 42+ 631 | if [[ "${version_id}" -ge 42 ]] && [[ -d "usr/sbin" ]]; then 632 | echo "➡️ Moving /usr/sbin to /usr/bin" 633 | ${SUDO} mv --verbose --no-clobber ./usr/sbin/* ./usr/bin 634 | ${SUDO} rmdir usr/sbin 635 | fi 636 | 637 | # Check sbin/bin merge starting with Fedora 42 638 | if [[ "${version_id}" -ge 42 ]] && [[ -d "usr/sbin" ]]; then 639 | failed_checks=$((failed_checks+1)) 640 | echo "❌ Found /usr/sbin directory on Fedora 42+ sysext (see bin/sbin merge change)" 641 | ls -alh usr/sbin 642 | fi 643 | 644 | # Check that /var is empty as it will be ignored 645 | if [[ -d "var" ]]; then 646 | failed_checks=$((failed_checks+1)) 647 | echo "❌ Found /var directory, which will be ignored: clear it or convert it to a tmpfiles.d config" 648 | ls -alh var 649 | fi 650 | 651 | # Check that /run is empty as it will be ignored 652 | if [[ -d "run" ]]; then 653 | failed_checks=$((failed_checks+1)) 654 | echo "❌ Found /run directory, which will be ignored: clear it or convert it to a tmpfiles.d config" 655 | ls -alh run 656 | fi 657 | 658 | # Check that we don't use /opt as it will not work 659 | if [[ -d "opt" ]]; then 660 | failed_checks=$((failed_checks+1)) 661 | echo "❌ Found /opt directory, which will not work: move the content to /usr/lib" 662 | ls -alh opt 663 | fi 664 | 665 | # Check that we don't have other directories as they will be ignored 666 | if [[ "$(ls | grep -cvE "^usr$|^run$|^var$|^opt$")" -ne 0 ]]; then 667 | failed_checks=$((failed_checks+1)) 668 | echo "❌ Found other directories which will be ignored: move them or clear them" 669 | ls | grep -vE "^usr$|^run$|^var$|^opt$" 670 | fi 671 | 672 | if [[ "${failed_checks}" -ne 0 ]]; then 673 | exit 1 674 | fi 675 | 676 | # Reset SELinux labels to expected values from the policy 677 | reset-selinux-labels target arch=arch: 678 | #!/bin/bash 679 | set -euo pipefail 680 | if [[ -n "{{debug}}" ]]; then 681 | set -x 682 | fi 683 | 684 | if [[ "${UID}" == "0" ]]; then 685 | SUDO="" 686 | else 687 | SUDO="sudo" 688 | fi 689 | 690 | # Only install the packages in the container if we have an SELinux policy 691 | # module in the sysext and might thus need specific labels 692 | pre_commands="" 693 | if [[ -d "./rootfs/usr/share/selinux/packages" ]]; then 694 | # Always disable the openh264 repo by default 695 | pre_commands="dnf5 config-manager setopt fedora-cisco-openh264.enabled=0; " 696 | 697 | dnf_opts="" 698 | if [[ "{{dnf_weak_deps}}" == false ]]; then 699 | dnf_opts="--setopt=install_weak_deps=False" 700 | fi 701 | if [[ -n "{{exclude_packages}}" ]]; then 702 | excluded_packages="$(echo "{{exclude_packages}}" | xargs)" 703 | for p in ${excluded_packages}; do 704 | echo "➖ Excluding package: ${p}" 705 | dnf_opts+=" --exclude=${p}" 706 | done 707 | fi 708 | 709 | if [[ -n "{{pre_commands}}" ]]; then 710 | pre_commands+="{{pre_commands}} ; " 711 | fi 712 | 713 | disablerepos="" 714 | if [[ -n "{{disable_repos}}" ]]; then 715 | for r in {{disable_repos}}; do 716 | echo "➖ Disabling repo: ${r}" 717 | disablerepos+=" --disablerepo=${r}" 718 | done 719 | fi 720 | 721 | if [[ -n "{{packages}}" ]]; then 722 | pre_commands+="export FORCE_COLUMNS=100 && dnf install -y ${dnf_opts} ${disablerepos} ./rpms/* && " 723 | fi 724 | 725 | mkdir -p ../.dnf-cache 726 | fi 727 | 728 | filecontexts="/etc/selinux/targeted/contexts/files/file_contexts" 729 | echo "🏷️ Resetting SELinux labels" 730 | podman run -ti {{podman_opts}} \ 731 | --volume "${PWD}:/var/srv" \ 732 | --volume "${PWD}/../.dnf-cache:/var/cache/libdnf5" \ 733 | --workdir "/var/srv" \ 734 | --privileged \ 735 | "{{target}}" \ 736 | bash -c "${pre_commands}cd rootfs && setfiles -r . ${filecontexts} . && chcon --user=system_u --recursive ." 737 | 738 | # Creates the EROFS sysext file 739 | build-erofs target arch=arch: 740 | #!/bin/bash 741 | set -euo pipefail 742 | if [[ -n "{{debug}}" ]]; then 743 | set -x 744 | fi 745 | 746 | if [[ "${UID}" == "0" ]]; then 747 | SUDO="" 748 | else 749 | SUDO="sudo" 750 | fi 751 | 752 | version="$(cat ./version)" 753 | version_id="$(cat ./version_id)" 754 | # Post process architecture to match systemd architecture list 755 | if [[ {{arch}} == "x86_64" ]]; then 756 | arch="x86-64" 757 | elif [[ {{arch}} == "aarch64" ]]; then 758 | arch="arm64" 759 | else 760 | echo "Unsupported architecture" 761 | exit 1 762 | fi 763 | 764 | echo "🔒 Creating EROFS sysext ({{compression}})" 765 | ${SUDO} mkfs.erofs -z{{compression}} {{name}}-${version}-${version_id}-${arch}.raw rootfs > /dev/null 766 | 767 | if [[ "${UID}" != "0" ]]; then 768 | ${SUDO} chown "${USER}:" {{name}}*.raw 769 | fi 770 | 771 | echo "🎉 Done!" 772 | 773 | # Clean up files from previous builds 774 | clean: 775 | #!/bin/bash 776 | set -euo pipefail 777 | if [[ -n "{{debug}}" ]]; then 778 | set -x 779 | fi 780 | 781 | if [[ "${UID}" == "0" ]]; then 782 | SUDO="" 783 | else 784 | SUDO="sudo" 785 | fi 786 | 787 | echo "🧹 Cleaning up files from previous builds" 788 | rm -rf inputs scripts digest version version_id 789 | rm -rf ./rpms 790 | rm -rf ./binaries 791 | ${SUDO} rm -rf ./rootfs 792 | rm -f ./*.raw 793 | --------------------------------------------------------------------------------