# Disable debug information package creation %define debug_package %{nil} %global goipath github.com/flightctl/flightctl # SELinux specifics %global selinuxtype targeted %define selinux_policyver 3.14.3-67 Name: flightctl # Version and Release are automatically updated by Packit during build # Do not manually change these values - they will be overwritten Version: 1.4.0~main~205~g454c21c09 Release: 1.20261008142632655928.main.205.g454c21c0%{?dist} Summary: Flight Control service %gometa License: Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT URL: %{gourl} Source0: flightctl-1.4.0~main~205~g454c21c09.tar.gz BuildRequires: golang BuildRequires: make BuildRequires: git BuildRequires: openssl-devel BuildRequires: systemd-rpm-macros Requires: openssl %global flightctl_target flightctl.target %description # Main package is empty and not created. # cli sub-package %package cli Summary: Flight Control CLI Recommends: bash-completion %description cli flightctl is the CLI for controlling the Flight Control service. # agent sub-package %package agent Summary: Flight Control management agent Requires: flightctl-selinux = %{version} Recommends: flightctl-greenboot Requires: jq Requires: sudo %description agent The flightctl-agent package provides the management agent for the Flight Control fleet management service. # greenboot sub-package %package greenboot Summary: Greenboot integration for the Flight Control agent Requires: greenboot Requires: flightctl-agent = %{version} %description greenboot The flightctl-greenboot package provides greenboot health checks, bootc timer masking, and greenboot configuration for the Flight Control agent on image-mode (bootc) systems. # selinux sub-package %package selinux Summary: SELinux policies for the Flight Control management agent BuildRequires: selinux-policy >= %{selinux_policyver} BuildRequires: selinux-policy-devel >= %{selinux_policyver} BuildRequires: container-selinux BuildArch: noarch Requires: selinux-policy >= %{selinux_policyver} # For restorecon Requires: policycoreutils # For semanage Requires: policycoreutils-python-utils # For policy macros Requires: container-selinux %description selinux The flightctl-selinux package provides the SELinux policy modules required by the Flight Control management agent. # services sub-package %package services Summary: Flight Control services Requires: bash Requires: openssl Requires: podman Requires: python3-pyyaml BuildRequires: systemd-rpm-macros %{?systemd_requires} Requires: selinux-policy-targeted Obsoletes: flightctl-telemetry-gateway < %{version}-%{release} %description services The flightctl-services package provides installation and setup of files for running containerized Flight Control services %package observability Summary: Complete Flight Control observability stack Requires: flightctl-services = %{version}-%{release} Requires: /usr/sbin/semanage Requires: /usr/sbin/restorecon Requires: podman Requires: systemd %{?systemd_requires} Requires: selinux-policy-targeted %description observability This package provides the Flight Control Observability Stack, including Prometheus for metric storage and Grafana for visualization. # catalog-collector sub-package %package catalog-collector Summary: Flight Control catalog collector Requires: podman Requires: systemd BuildRequires: systemd-rpm-macros %{?systemd_requires} Requires: selinux-policy-targeted %description catalog-collector The flightctl-catalog-collector package provides a Quadlet unit that runs the containerized Flight Control catalog collector, which imports catalogs from external registries such as the Kubeflow Model Registry into Flight Control. The collector has no usable default pipeline, so the unit does not start until a configuration file exists at %{_sysconfdir}/flightctl/flightctl-catalog-collector/config.yaml. Example configurations are installed under %{_datadir}/flightctl/flightctl-catalog-collector/examples. This sub-package is independent of flightctl-services: the collector can run on a host that only forwards catalogs to a remote Flight Control service. %files observability # Shared directories (also owned by services package) %dir %{_datadir}/flightctl %dir %{_datadir}/flightctl/flightctl-grafana %dir %{_datadir}/flightctl/flightctl-prometheus %dir %{_datadir}/flightctl/flightctl-userinfo-proxy %dir %{_datadir}/containers/systemd # Grafana configuration templates and static files %{_datadir}/flightctl/flightctl-grafana/grafana.ini.template %{_datadir}/flightctl/flightctl-grafana/grafana-datasources.yaml %{_datadir}/flightctl/flightctl-grafana/grafana-dashboards.yaml # Grafana provisioning files installed directly to /etc %config(noreplace) /etc/flightctl/flightctl-grafana/provisioning/datasources/grafana-datasources.yaml %config(noreplace) /etc/flightctl/flightctl-grafana/provisioning/dashboards/grafana-dashboards.yaml %config(noreplace) /etc/flightctl/flightctl-grafana/provisioning/dashboards/flightctl/*.json # Prometheus static configuration %{_datadir}/flightctl/flightctl-prometheus/prometheus.yml # UserInfo Proxy configuration templates %{_datadir}/flightctl/flightctl-userinfo-proxy/env.template # Generated quadlet files (created during build by flightctl-standalone) %{_datadir}/containers/systemd/flightctl-grafana.container %{_datadir}/containers/systemd/flightctl-prometheus.container %{_datadir}/containers/systemd/flightctl-userinfo-proxy.container # Systemd target for full observability stack /usr/lib/systemd/system/flightctl-observability.target # Directories owned by the observability RPM # Note: Parent directories are also owned by services package (shared ownership is allowed) %dir /etc/flightctl %dir /etc/flightctl/pki %dir /etc/flightctl/pki/flightctl-grafana %dir /etc/flightctl/pki/flightctl-prometheus %dir /etc/flightctl/pki/flightctl-userinfo-proxy %dir /etc/flightctl/flightctl-grafana %dir /etc/flightctl/flightctl-grafana/provisioning %dir /etc/flightctl/flightctl-grafana/provisioning/datasources %dir /etc/flightctl/flightctl-grafana/provisioning/alerting %dir /etc/flightctl/flightctl-grafana/provisioning/dashboards %dir /etc/flightctl/flightctl-grafana/provisioning/dashboards/flightctl %dir /etc/flightctl/flightctl-grafana/certs %dir /etc/flightctl/flightctl-prometheus %dir /var/lib/prometheus %dir /var/lib/grafana # Ghost files for runtime-generated configuration %ghost /etc/flightctl/flightctl-grafana/grafana.ini %pre observability echo "Preparing to install Flight Control Observability Stack..." echo "Note: Observability stack can be installed independently of other Flight Control services." # Workaround: save observability state before upgrade so %%posttrans can restore it. # Needed because older versions' %%preun unconditionally stops services on upgrade. # Can be removed once all deployments have upgraded past this version. if [ "$1" -eq 2 ]; then if /usr/bin/systemctl is-active --quiet flightctl-observability.target 2>/dev/null; then touch /run/flightctl-observability-was-active fi fi %post observability # On initial install: apply preset policy to enable/disable services based on system defaults %systemd_post flightctl-observability.target echo "Running post-install actions for Flight Control Observability Stack..." # Set ownership for persistent data directories chown 65534:65534 /var/lib/prometheus # Apply persistent SELinux contexts for volumes and configuration files. /usr/sbin/semanage fcontext -a -t container_file_t "/etc/flightctl/flightctl-prometheus(/.*)?" >/dev/null 2>&1 || : /usr/sbin/semanage fcontext -a -t container_file_t "/var/lib/prometheus(/.*)?" >/dev/null 2>&1 || : /usr/sbin/semanage fcontext -a -t container_file_t "/etc/flightctl/flightctl-grafana(/.*)?" >/dev/null 2>&1 || : /usr/sbin/semanage fcontext -a -t container_file_t "/var/lib/grafana(/.*)?" >/dev/null 2>&1 || : # Restore file contexts based on the new rules (and default rules) /usr/sbin/restorecon -RvF /etc/flightctl/flightctl-prometheus >/dev/null 2>&1 || : /usr/sbin/restorecon -RvF /var/lib/prometheus >/dev/null 2>&1 || : /usr/sbin/restorecon -RvF /etc/flightctl/flightctl-grafana >/dev/null 2>&1 || : /usr/sbin/restorecon -RvF /var/lib/grafana >/dev/null 2>&1 || : # Enable specific SELinux boolean if needed /usr/sbin/setsebool -P container_manage_cgroup on >/dev/null 2>&1 || : # Reload systemd daemon to pick up new quadlet files echo "Reloading systemd daemon..." /usr/bin/systemctl daemon-reload # On upgrade: mark the observability target for restart so PartOf= services restart if [ "$1" -ge 2 ] && [ -x "/usr/lib/systemd/systemd-update-helper" ]; then /usr/lib/systemd/systemd-update-helper mark-restart-system-units flightctl-observability.target || : fi %preun observability echo "Running pre-uninstall actions for Flight Control Observability Stack..." # On package removal: stop and disable all services (PartOf= propagates to all services) %systemd_preun flightctl-observability.target %postun observability # On upgrade: mark services for restart after transaction %systemd_postun_with_restart flightctl-observability.target if [ $1 -eq 0 ]; then # Clean up Podman containers associated with the services /usr/bin/podman rm -f flightctl-grafana >/dev/null 2>&1 || : /usr/bin/podman rm -f flightctl-userinfo-proxy >/dev/null 2>&1 || : /usr/bin/podman rm -f flightctl-prometheus >/dev/null 2>&1 || : # Note: Podman secrets are managed by the telemetry-gateway package # and will be cleaned up when that package is uninstalled # Remove SELinux fcontext rules added by this package /usr/sbin/semanage fcontext -d -t container_file_t "/etc/flightctl/flightctl-grafana(/.*)?" >/dev/null 2>&1 || : /usr/sbin/semanage fcontext -d -t container_file_t "/var/lib/grafana(/.*)?" >/dev/null 2>&1 || : /usr/sbin/semanage fcontext -d -t container_file_t "/etc/flightctl/flightctl-prometheus(/.*)?" >/dev/null 2>&1 || : /usr/sbin/semanage fcontext -d -t container_file_t "/var/lib/prometheus(/.*)?" >/dev/null 2>&1 || : # Restore default SELinux contexts for affected directories /usr/sbin/restorecon -RvF /etc/flightctl/flightctl-grafana >/dev/null 2>&1 || : /usr/sbin/restorecon -RvF /var/lib/grafana >/dev/null 2>&1 || : /usr/sbin/restorecon -RvF /etc/flightctl/flightctl-prometheus >/dev/null 2>&1 || : /usr/sbin/restorecon -RvF /var/lib/prometheus >/dev/null 2>&1 || : /usr/bin/systemctl daemon-reload >/dev/null 2>&1 || : fi %posttrans observability # Workaround: restore observability services if they were running before upgrade. # Needed because older versions' %%preun unconditionally stops services on upgrade. # Can be removed once all deployments have upgraded past this version. if [ -f /run/flightctl-observability-was-active ]; then rm -f /run/flightctl-observability-was-active /usr/bin/systemctl start flightctl-observability.target >/dev/null 2>&1 || : fi %prep %goprep -A %setup -q %{forgesetupargs} -n flightctl-1.4.0~main~205~g454c21c09 %build %global fips_enabled 0%{?rhel} %if %{fips_enabled} %define disable_fips %{nil} %else %define disable_fips DISABLE_FIPS="true" %endif # if this is a buggy version of go we need to set GOPROXY as workaround # see https://github.com/golang/go/issues/61928 GOENVFILE=$(go env GOROOT)/go.env if [[ ! -f "${GOENVFILE}" ]]; then export GOPROXY='https://proxy.golang.org,direct' fi SOURCE_GIT_TAG="$( tag=$(./hack/current-version 2>/dev/null || true); if [ -z "$tag" ]; then tag=$(echo "v%{version}" | tr '~' '-'); fi; echo "${tag}"; )" \ SOURCE_GIT_TREE_STATE="clean" \ SOURCE_GIT_COMMIT="$( commit=$( (git rev-parse HEAD 2>/dev/null || true) | cut -c1-9); if [ -z "$commit" ]; then commit=$(grep -v '^\$Format' packaging/rpm/git-metadata 2>/dev/null | tr -d '[:space:]'); fi; if [ -z "$commit" ]; then commit=$(echo %{version} | grep -o '[-~]g[0-9a-f]*' | sed 's/[-~]g//'); fi; echo "${commit:-unknown}" | cut -c1-9; )" \ %{?disable_fips} %make_build build-cli build-agent build-backup build-restore build-standalone build-mirror-images # SELinux modules build %make_build --directory packaging/selinux %if %{fips_enabled} GOFLAGS='' GOBIN="$PWD/bin" go install github.com/flightctl/fips-validator@v0.0.0-20250930084220-ceca2caa6e48 %endif %install mkdir -p %{buildroot}/usr/bin mkdir -p %{buildroot}/etc/flightctl cp bin/flightctl %{buildroot}/usr/bin cp bin/flightctl-backup %{buildroot}/usr/bin cp bin/flightctl-restore %{buildroot}/usr/bin cp bin/flightctl-mirror-images %{buildroot}/usr/bin mkdir -p %{buildroot}/usr/lib/systemd/system mkdir -p %{buildroot}/usr/lib/tmpfiles.d mkdir -p %{buildroot}/usr/lib/flightctl/custom-info.d mkdir -p %{buildroot}/usr/lib/flightctl/hooks.d/{afterupdating,beforeupdating,afterrebooting,beforerebooting} mkdir -p %{buildroot}/usr/lib/greenboot/check/required.d mkdir -p %{buildroot}/usr/lib/greenboot/red.d mkdir -p %{buildroot}/usr/share/flightctl/functions install -m 0755 packaging/greenboot/functions.sh %{buildroot}/usr/share/flightctl/functions/greenboot.sh install -m 0755 packaging/greenboot/flightctl-agent-running-check.sh %{buildroot}/usr/lib/greenboot/check/required.d/20_check_flightctl_agent.sh install -m 0755 packaging/greenboot/flightctl-agent-pre-rollback.sh %{buildroot}/usr/lib/greenboot/red.d/40_flightctl_agent_pre_rollback.sh mkdir -p %{buildroot}/usr/libexec/flightctl install -m 0755 packaging/flightctl/mask-bootc-timer.sh %{buildroot}/usr/libexec/flightctl/mask-bootc-timer.sh install -m 0644 packaging/systemd/flightctl-mask-bootc-timer.service %{buildroot}/usr/lib/systemd/system cp bin/flightctl-agent %{buildroot}/usr/bin cp packaging/must-gather/flightctl-must-gather %{buildroot}/usr/bin cp packaging/hooks.d/afterupdating/00-default.yaml %{buildroot}/usr/lib/flightctl/hooks.d/afterupdating cp packaging/systemd/flightctl-agent.service %{buildroot}/usr/lib/systemd/system echo "d /var/lib/flightctl 0755 root root -" > %{buildroot}/usr/lib/tmpfiles.d/flightctl.conf echo "# systemd-tmpfiles configuration for CentOS bootc buildinfo directories" > %{buildroot}/usr/lib/tmpfiles.d/centos-buildinfo.conf echo "d /var/roothome 0755 root root -" >> %{buildroot}/usr/lib/tmpfiles.d/centos-buildinfo.conf echo "d /var/roothome/buildinfo 0755 root root -" >> %{buildroot}/usr/lib/tmpfiles.d/centos-buildinfo.conf echo "d /var/roothome/buildinfo/content_manifests 0755 root root -" >> %{buildroot}/usr/lib/tmpfiles.d/centos-buildinfo.conf bin/flightctl completion bash > flightctl-completion.bash install -Dpm 0644 flightctl-completion.bash -t %{buildroot}/%{_datadir}/bash-completion/completions bin/flightctl completion fish > flightctl-completion.fish install -Dpm 0644 flightctl-completion.fish -t %{buildroot}/%{_datadir}/fish/vendor_completions.d/ bin/flightctl completion zsh > _flightctl-completion install -Dpm 0644 _flightctl-completion -t %{buildroot}/%{_datadir}/zsh/site-functions/ install -d %{buildroot}%{_datadir}/selinux/packages/%{selinuxtype} install -m644 packaging/selinux/*.bz2 %{buildroot}%{_datadir}/selinux/packages/%{selinuxtype} install -Dpm 0644 packaging/flightctl-services-install.conf %{buildroot}%{_sysconfdir}/flightctl/flightctl-services-install.conf mkdir -p %{buildroot}%{_sysusersdir} install -Dpm 0644 packaging/rpm/sysusers.d/flightctl.conf %{buildroot}%{_sysusersdir}/flightctl.conf install -Dpm 0440 packaging/rpm/sudoers.d/flightctl %{buildroot}/etc/sudoers.d/flightctl # Collect license files (top-level + vendored dependencies if present) rm -f licenses.list find -type f \( -name LICENSE -o -name License \) | while read LICENSE_FILE; do install -Dv -m0644 "${LICENSE_FILE}" "%{buildroot}%{_datadir}/licenses/%{NAME}/${LICENSE_FILE}" echo "%%license %{_datadir}/licenses/%{NAME}/${LICENSE_FILE}" >> licenses.list done # Own intermediate directories so RPM removes them on uninstall find "%{buildroot}%{_datadir}/licenses/%{NAME}" -mindepth 1 -type d | sort -r | while read DIR; do echo "%%dir ${DIR#%{buildroot}}" >> licenses.list done touch licenses.list # flightctl-services sub-package steps # Use the flightctl-standalone render quadlets command to generate quadlet files with the correct image tags. # # The IMAGE_TAG is derived from the RPM version, which may include tildes (~) # for proper version sorting (e.g., 0.5.1~rc1-1). However, the tagged images # always use hyphens (-) instead of tildes (~). To ensure valid image tags we need # to transform the version string by replacing tildes with hyphens. IMAGE_TAG=$(echo %{version} | tr '~' '-') %define images_config packaging/images/%{?rhel:el%{rhel}}%{!?rhel:el9}/images.yaml # Check if IMAGE_TAG matches a release version pattern (x.x.x or x.x.x-rcX). # Release versions match: 1.2.3 or 1.2.3-rc1 # Development builds have additional suffixes like: 1.2.3-main-79-g54721648 if echo "${IMAGE_TAG}" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-rc[0-9]+)?$'; then APPLY_UI_OVERRIDE="--flightctl-ui-tag-override" else APPLY_UI_OVERRIDE="" fi bin/flightctl-standalone render quadlets \ --config "%{images_config}" \ --flightctl-services-tag-override "${IMAGE_TAG}" \ ${APPLY_UI_OVERRIDE} \ --readonly-config-dir "%{buildroot}%{_datadir}/flightctl" \ --writeable-config-dir "%{buildroot}%{_sysconfdir}/flightctl" \ --quadlet-dir "%{buildroot}%{_datadir}/containers/systemd" \ --systemd-dir "%{buildroot}/usr/lib/systemd/system" \ --bin-dir "%{buildroot}/usr/bin" \ --var-tmp-dir "%{buildroot}%{_var}/tmp" \ --var-lib-dir "%{buildroot}/var/lib" # Create host-side registry configuration directories bind-mounted by the # worker Quadlets. The E2E setup populates these after deployment. install -d -m 0755 \ %{buildroot}%{_sysconfdir}/flightctl/flightctl-worker/registries.conf.d \ %{buildroot}%{_sysconfdir}/flightctl/flightctl-delta-worker/registries.conf.d mkdir -p %{buildroot}%{_sysconfdir}/flightctl/tpm-cas # Copy services must gather script cp packaging/must-gather/flightctl-services-must-gather %{buildroot}%{_bindir} # Copy certificate and encryption key generation scripts mkdir -p %{buildroot}%{_datadir}/flightctl install -m 0755 deploy/helm/flightctl/scripts/generate-certificates.sh %{buildroot}%{_datadir}/flightctl/generate-certificates.sh install -m 0755 deploy/helm/flightctl/scripts/generate-encryption-key.sh %{buildroot}%{_datadir}/flightctl/generate-encryption-key.sh # Copy sos report flightctl plugin mkdir -p %{buildroot}/usr/share/sosreport cp packaging/sosreport/sos/report/plugins/flightctl.py %{buildroot}/usr/share/sosreport # install observability # Install pre-upgrade helper script to libexec mkdir -p %{buildroot}%{_libexecdir}/flightctl install -Dpm 0755 deploy/scripts/pre-upgrade-dry-run.sh %{buildroot}%{_libexecdir}/flightctl/pre-upgrade-dry-run.sh # Observability quadlets are now rendered together with regular services above # using flightctl-standalone render quadlets, which processes all components in deploy/podman/ # Install systemd targets for service grouping install -m 0644 deploy/podman/flightctl-observability.target %{buildroot}/usr/lib/systemd/system/ # Create observability persistent data directories mkdir -p %{buildroot}/var/lib/prometheus mkdir -p %{buildroot}/var/lib/grafana # flightctl-catalog-collector sub-package steps # # The collector quadlet is installed directly rather than through # "flightctl-standalone render quadlets": the collector is an optional # add-on that is not part of flightctl.target and must stay installable # without flightctl-services. # # The image reference still comes from the same %{images_config} that # drives the services quadlets, so there is exactly one place that decides # which registry and which dist suffix a build uses. Hardcoding it here # would silently diverge from images.yaml the first time a downstream # build repointed the registry. This is the same rule the pam-issuer # image already follows. # # packaging/images/rhelN/images.yaml is deliberately not consulted # here. Those files list only the RPM-only images the air-gap mirror tool # needs and omit the service entries the render step above requires, so a # downstream RHEL build repoints %{images_config} itself rather than # splitting the collector onto a second source. CATALOG_COLLECTOR_IMAGE=$(awk ' /^catalog-collector:[[:space:]]*$/ { in_entry = 1; next } /^[^[:space:]#]/ { in_entry = 0 } in_entry && $1 == "image:" { print $2; exit } ' "%{images_config}") if [ -z "${CATALOG_COLLECTOR_IMAGE}" ]; then echo "ERROR: no catalog-collector image entry in %{images_config}" >&2 exit 1 fi install -d -m 0755 %{buildroot}%{_sysconfdir}/flightctl/flightctl-catalog-collector install -d -m 0755 %{buildroot}%{_datadir}/flightctl/flightctl-catalog-collector/examples install -m 0644 deploy/podman/flightctl-catalog-collector/examples/config-vanilla.yaml \ %{buildroot}%{_datadir}/flightctl/flightctl-catalog-collector/examples/config-vanilla.yaml install -m 0644 deploy/podman/flightctl-catalog-collector/examples/config-rhoai-to-flightctl.yaml \ %{buildroot}%{_datadir}/flightctl/flightctl-catalog-collector/examples/config-rhoai-to-flightctl.yaml install -m 0644 deploy/podman/flightctl-catalog-collector/examples/vanilla-publish-8080.conf \ %{buildroot}%{_datadir}/flightctl/flightctl-catalog-collector/examples/vanilla-publish-8080.conf install -d -m 0755 %{buildroot}%{_datadir}/containers/systemd sed -e "s|@CATALOG_COLLECTOR_IMAGE@|${CATALOG_COLLECTOR_IMAGE}:${IMAGE_TAG}|" \ deploy/podman/flightctl-catalog-collector/flightctl-catalog-collector.container \ > %{buildroot}%{_datadir}/containers/systemd/flightctl-catalog-collector.container chmod 0644 %{buildroot}%{_datadir}/containers/systemd/flightctl-catalog-collector.container grep -q '@CATALOG_COLLECTOR_IMAGE@' \ %{buildroot}%{_datadir}/containers/systemd/flightctl-catalog-collector.container \ && { echo "ERROR: catalog collector image placeholder was not substituted" >&2; exit 1; } || : %check # Run the installed binary from the buildroot and capture its output out="$("%{buildroot}%{_bindir}/flightctl-agent" version)" echo "$out" # Extract the parts after the colons version=$(printf '%s\n' "$out" | sed -n 's/^Agent Version:[[:space:]]*//p') commit=$(printf '%s\n' "$out" | sed -n 's/^Git Commit:[[:space:]]*//p') # Fail if either is empty if [ -z "$version" ]; then echo "ERROR: Agent Version is empty" exit 1 fi if [ -z "$commit" ]; then echo "ERROR: Git Commit is empty" exit 1 fi %if %{fips_enabled} bin/fips-validator binary %{buildroot}%{_bindir}/flightctl bin/fips-validator binary %{buildroot}%{_bindir}/flightctl-agent bin/fips-validator binary %{buildroot}%{_bindir}/flightctl-backup bin/fips-validator binary %{buildroot}%{_bindir}/flightctl-restore GOLANG_FIPS=1 OPENSSL_FORCE_FIPS_MODE=1 LD_DEBUG=symbols bin/flightctl version |& grep OPENSSL %endif %pre selinux %selinux_relabel_pre -s %{selinuxtype} %post selinux # Install SELinux module - if this fails, RPM installation will still continue if ! semodule -s %{selinuxtype} -i %{_datadir}/selinux/packages/%{selinuxtype}/flightctl_agent.pp.bz2; then echo "ERROR: Failed to install flightctl SELinux policy (AST failure or compatibility issue)" >&2 exit 1 fi %postun selinux if [ $1 -eq 0 ]; then semodule -s %{selinuxtype} -r flightctl_agent 2>/dev/null || : fi %posttrans selinux %selinux_relabel_post -s %{selinuxtype} # File listings # No %%files section for the main package, so it won't be built %files cli -f licenses.list %dir %{_datadir}/licenses/%{NAME} %{_bindir}/flightctl %{_bindir}/flightctl-backup %{_bindir}/flightctl-restore %{_bindir}/flightctl-mirror-images %{_datadir}/bash-completion/completions/flightctl-completion.bash %{_datadir}/fish/vendor_completions.d/flightctl-completion.fish %{_datadir}/zsh/site-functions/_flightctl-completion %files agent %license LICENSE %dir /etc/flightctl %{_bindir}/flightctl-agent %{_bindir}/flightctl-must-gather /usr/lib/flightctl/hooks.d/afterupdating/00-default.yaml /usr/lib/systemd/system/flightctl-agent.service /usr/lib/tmpfiles.d/flightctl.conf /usr/lib/tmpfiles.d/centos-buildinfo.conf /usr/share/sosreport/flightctl.py %{_sysusersdir}/flightctl.conf /etc/sudoers.d/* %files greenboot /usr/share/flightctl/functions/greenboot.sh /usr/lib/greenboot/check/required.d/20_check_flightctl_agent.sh /usr/lib/greenboot/red.d/40_flightctl_agent_pre_rollback.sh /usr/libexec/flightctl/mask-bootc-timer.sh /usr/lib/systemd/system/flightctl-mask-bootc-timer.service %post agent # Ensure /var/lib/flightctl exists immediately for environments where systemd-tmpfiles succeeds or via fallback # Try systemd-tmpfiles first, fall back to manual creation if it fails /usr/bin/systemd-tmpfiles --create /usr/lib/tmpfiles.d/flightctl.conf || { mkdir -p /var/lib/flightctl && \ chown root:root /var/lib/flightctl && \ chmod 0755 /var/lib/flightctl } # These files prevent tmpfiles.d from managing the /var/roothome/buildinfo directory rm -f /var/roothome/buildinfo/content_manifests/content-sets.json rm -f /var/roothome/buildinfo/labels.json # Remove the directories so tmpfiles.d can recreate them properly rmdir /var/roothome/buildinfo/content_manifests 2>/dev/null || true rmdir /var/roothome/buildinfo 2>/dev/null || true INSTALL_DIR="/usr/lib/python$(python3 --version | sed 's/^.* \(3[.][0-9]*\).*$/\1/')/site-packages/sos/report/plugins" mkdir -p $INSTALL_DIR cp /usr/share/sosreport/flightctl.py $INSTALL_DIR chmod 0644 $INSTALL_DIR/flightctl.py rm -rf /usr/share/sosreport # We want a regular user to run applications with as there are several issues around system users # and running quadlet applications. id -u flightctl 2>/dev/null || useradd --create-home --user-group flightctl # This enables lingering for the user with a fallback when building in an env without an active systemd. loginctl enable-linger flightctl || (mkdir -p /var/lib/systemd/linger/ && touch /var/lib/systemd/linger/flightctl) mkdir -p ~flightctl/.config/{containers/systemd,systemd/user} mkdir -p ~flightctl/.local chown -R flightctl:flightctl ~flightctl/{.config,.local} %post greenboot # Enable greenboot-healthcheck if present (not enabled by default in greenboot-rs 0.16.x). # Must be unconditional: greenboot's own %%systemd_post preset removes greenboot-success.target # (renamed from greenboot-set-success.target) due to a CentOS preset mismatch. Re-running # `systemctl enable` recreates it via the Also= directive. # See: https://github.com/fedora-iot/greenboot-rs/issues/171 # See: https://github.com/openshift/microshift/pull/5530 systemctl enable --quiet greenboot-healthcheck 2>/dev/null || : # Disable stale unit if left enabled from a previous package version. systemctl disable flightctl-configure-greenboot.service 2>/dev/null || : # Mask bootc auto-update timer on first boot (bootc/composefs); the script # is also run directly below for immediate effect during RPM install. systemctl enable flightctl-mask-bootc-timer.service >/dev/null 2>&1 || : # Disable bootc automatic updates on bootc systems (flightctl manages updates). # mask-bootc-timer.sh applies the mask; flightctl-mask-bootc-timer.service re-runs on # boot when image-build %post changes do not persist on bootc/composefs disks. /usr/libexec/flightctl/mask-bootc-timer.sh 2>/dev/null || true %postun agent if [ "$1" -eq 0 ]; then loginctl disable-linger flightctl || : fi %preun greenboot %systemd_preun flightctl-mask-bootc-timer.service %postun greenboot # Restore bootc automatic-update timer only on full removal (not upgrade) if [ "$1" -eq 0 ]; then systemctl unmask bootc-fetch-apply-updates.timer 2>/dev/null || true systemctl start bootc-fetch-apply-updates.timer 2>/dev/null || true fi %files selinux %{_datadir}/selinux/packages/%{selinuxtype}/flightctl_agent.pp.bz2 %files services %defattr(0644,root,root,-) # Files mounted to system config %dir %{_sysconfdir}/flightctl %dir %{_sysconfdir}/flightctl/encryption %dir %{_sysconfdir}/flightctl/pki %dir %{_sysconfdir}/flightctl/pki/flightctl-api %dir %{_sysconfdir}/flightctl/pki/flightctl-alertmanager-proxy %dir %{_sysconfdir}/flightctl/pki/flightctl-pam-issuer %dir %{_sysconfdir}/flightctl/pki/flightctl-gateway %dir %{_sysconfdir}/flightctl/pki/flightctl-imagebuilder-api %dir %{_sysconfdir}/flightctl/pki/flightctl-remote-access %dir %{_sysconfdir}/flightctl/pki/flightctl-telemetry-gateway %dir %{_sysconfdir}/flightctl/pki/db %dir %{_sysconfdir}/flightctl/flightctl-alert-exporter %dir %{_sysconfdir}/flightctl/flightctl-alertmanager-proxy %dir %{_sysconfdir}/flightctl/flightctl-api %dir %{_sysconfdir}/flightctl/tpm-cas %dir %{_sysconfdir}/flightctl/flightctl-cli-artifacts %dir %{_sysconfdir}/flightctl/flightctl-db-migrate %dir %{_sysconfdir}/flightctl/flightctl-gateway %dir %{_sysconfdir}/flightctl/flightctl-imagebuilder-api %dir %{_sysconfdir}/flightctl/flightctl-imagebuilder-worker %dir %{_sysconfdir}/flightctl/flightctl-remote-access %dir %{_sysconfdir}/flightctl/flightctl-pam-issuer %dir %{_sysconfdir}/flightctl/flightctl-periodic %dir %{_sysconfdir}/flightctl/flightctl-ui %dir %{_sysconfdir}/flightctl/flightctl-worker %dir %{_sysconfdir}/flightctl/flightctl-worker/registries.conf.d %dir %{_sysconfdir}/flightctl/flightctl-delta-worker %dir %{_sysconfdir}/flightctl/flightctl-delta-worker/registries.conf.d %dir %{_sysconfdir}/flightctl/flightctl-telemetry-gateway %dir %{_sysconfdir}/flightctl/flightctl-telemetry-gateway/forward %dir %{_sysconfdir}/flightctl/ssh %config(noreplace) %{_sysconfdir}/flightctl/service-config.yaml %config(noreplace) %{_sysconfdir}/flightctl/flightctl-services-install.conf %config(noreplace) %{_sysconfdir}/flightctl/ssh/known_hosts %ghost /etc/flightctl/flightctl-telemetry-gateway/config.yaml # Files mounted to data dir %dir %attr(0755,root,root) %{_datadir}/flightctl %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-api %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-db %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-kv %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-alertmanager-proxy %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-ui %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-cli-artifacts %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-gateway %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-pam-issuer %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-alertmanager %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-alert-exporter %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-periodic %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-worker %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-delta-worker %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-db-migrate %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-imagebuilder-api %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-imagebuilder-worker %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-remote-access %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-telemetry-gateway %dir %attr(0755,root,root) %{_var}/tmp/flightctl-builds %dir %attr(0755,root,root) %{_var}/tmp/flightctl-exports %{_datadir}/flightctl/flightctl-api/config.yaml.template %{_datadir}/flightctl/flightctl-api/env.template %attr(0755,root,root) %{_datadir}/flightctl/flightctl-db/enable-superuser.sh %{_datadir}/flightctl/flightctl-kv/valkey.conf %{_datadir}/flightctl/flightctl-ui/env.template %attr(0755,root,root) %{_datadir}/flightctl/flightctl-ui/init.sh %attr(0755,root,root) %{_datadir}/flightctl/init_utils.sh %{_datadir}/flightctl/flightctl-cli-artifacts/env.template %{_datadir}/flightctl/flightctl-alertmanager/alertmanager.yml %{_datadir}/flightctl/flightctl-alertmanager-proxy/env.template %{_datadir}/flightctl/flightctl-pam-issuer/config.yaml.template %{_datadir}/flightctl/flightctl-gateway/nginx.conf.template %{_datadir}/flightctl/flightctl-alertmanager-proxy/config.yaml.template %{_datadir}/flightctl/flightctl-alert-exporter/config.yaml.template %{_datadir}/flightctl/flightctl-periodic/config.yaml.template %{_datadir}/flightctl/flightctl-worker/config.yaml.template %{_datadir}/flightctl/flightctl-delta-worker/config.yaml.template %{_datadir}/flightctl/flightctl-db-migrate/config.yaml.template %{_datadir}/flightctl/flightctl-imagebuilder-api/config.yaml.template %{_datadir}/flightctl/flightctl-imagebuilder-worker/config.yaml.template %{_datadir}/flightctl/flightctl-remote-access/config.yaml.template %{_datadir}/flightctl/flightctl-remote-access/env.template %{_datadir}/flightctl/flightctl-telemetry-gateway/config.yaml.template # Quadlet files (excluding observability components which are in separate packages) %{_datadir}/containers/systemd/flightctl-api.container %{_datadir}/containers/systemd/flightctl-worker.container %{_datadir}/containers/systemd/flightctl-delta-worker.container %{_datadir}/containers/systemd/flightctl-periodic.container %{_datadir}/containers/systemd/flightctl-alert*.container %{_datadir}/containers/systemd/flightctl-cli-artifacts*.container %{_datadir}/containers/systemd/flightctl-db*.container %{_datadir}/containers/systemd/flightctl-db*.volume %{_datadir}/containers/systemd/flightctl-kv*.container %{_datadir}/containers/systemd/flightctl-kv.volume %{_datadir}/containers/systemd/flightctl-pam-issuer.container %{_datadir}/containers/systemd/flightctl-pam-issuer-etc.volume %{_datadir}/containers/systemd/flightctl-gateway.container %{_datadir}/containers/systemd/flightctl-ui*.container %{_datadir}/containers/systemd/flightctl-ui-certs.volume %{_datadir}/containers/systemd/flightctl-imagebuilder*.container %{_datadir}/containers/systemd/flightctl-remote-access.container %{_datadir}/containers/systemd/flightctl-alertmanager.volume %{_datadir}/containers/systemd/flightctl-telemetry-gateway.container %{_datadir}/containers/systemd/flightctl.network %{_datadir}/containers/systemd/flightctl-listeners.volume # Handle permissions for scripts setting host config %attr(0755,root,root) %{_datadir}/flightctl/init_db.sh %attr(0755,root,root) %{_datadir}/flightctl/init_kv.sh %attr(0755,root,root) %{_datadir}/flightctl/init_certs.sh %attr(0755,root,root) %{_datadir}/flightctl/secrets.sh %attr(0755,root,root) %{_datadir}/flightctl/yaml_helpers.py %attr(0755,root,root) %{_datadir}/flightctl/generate-certificates.sh %attr(0755,root,root) %{_datadir}/flightctl/generate-encryption-key.sh # flightctl-services pre upgrade checks %dir %{_libexecdir}/flightctl %attr(0755,root,root) %{_libexecdir}/flightctl/pre-upgrade-dry-run.sh # Files mounted to lib dir /usr/lib/systemd/system/flightctl.target /usr/lib/systemd/system/flightctl-certs-init.service /usr/lib/systemd/system/flightctl-api-init.service # Files mounted to bin dir %attr(0755,root,root) %{_bindir}/flightctl-services-must-gather %attr(0755,root,root) %{_bindir}/flightctl-standalone # Optional pre-upgrade database migration dry-run %pre services # $1 == 1 if it's an install # $1 == 2 if it's an upgrade if [ "$1" -eq 2 ]; then IMAGE_TAG="$(echo %{version} | tr '~' '-')" %define db_setup_registry quay.io %define db_setup_image flightctl/flightctl-db-setup-%{?rhel:el%{rhel}}%{!?rhel:el9} echo "flightctl: running pre upgrade checks, target version $IMAGE_TAG" if [ -x "%{_libexecdir}/flightctl/pre-upgrade-dry-run.sh" ]; then SCRIPT="%{_libexecdir}/flightctl/pre-upgrade-dry-run.sh" # Versions before the EDM-3833 fix hardcode the wrong image name and overwrite # the DB_SETUP_IMAGE env var. Detect this and patch just that line in a temp copy # so the rest of the script (config reading, secrets, network) stays correct for # the currently installed system state. # Can be removed once all deployments have upgraded past the fix. if grep -q 'DB_SETUP_IMAGE="quay.io/flightctl/flightctl-db-setup:' "$SCRIPT" 2>/dev/null; then TMPSCRIPT=$(mktemp /tmp/flightctl-dry-run.XXXXXX.sh) cp "$SCRIPT" "$TMPSCRIPT" chmod +x "$TMPSCRIPT" CORRECT_IMAGE="%{db_setup_registry}/%{db_setup_image}:${IMAGE_TAG}" sed -i "s|DB_SETUP_IMAGE=.*|DB_SETUP_IMAGE=\"${CORRECT_IMAGE}\"|" "$TMPSCRIPT" SCRIPT="$TMPSCRIPT" fi IMAGE_TAG="$IMAGE_TAG" \ DB_SETUP_REGISTRY="%{db_setup_registry}" \ DB_SETUP_IMAGE="%{db_setup_image}" \ CONFIG_PATH="%{_sysconfdir}/flightctl/flightctl-api/config.yaml" \ bash "$SCRIPT" "$IMAGE_TAG" "%{_sysconfdir}/flightctl/flightctl-api/config.yaml" || { [ -z "${TMPSCRIPT:-}" ] || rm -f "$TMPSCRIPT" echo "flightctl: dry-run failed; aborting upgrade." >&2 exit 1 } [ -z "${TMPSCRIPT:-}" ] || rm -f "$TMPSCRIPT" else echo "flightctl: pre-upgrade-dry-run.sh not found at %{_libexecdir}/flightctl; skipping." fi fi %post services # On initial install: apply preset policy to enable/disable services based on system defaults %systemd_post %{flightctl_target} # Enable specific SELinux boolean if needed /usr/sbin/setsebool -P container_manage_cgroup on >/dev/null 2>&1 || : # Reload systemd to recognize new container files /usr/bin/systemctl daemon-reload >/dev/null 2>&1 || : # On upgrade: mark the target for restart so all PartOf= services restart. # The OLD package's %%postun may not mark the target (older versions marked # individual services with an incomplete list). Marking is idempotent. if [ "$1" -ge 2 ] && [ -x "/usr/lib/systemd/systemd-update-helper" ]; then /usr/lib/systemd/systemd-update-helper mark-restart-system-units %{flightctl_target} || : fi cfg="%{_sysconfdir}/flightctl/flightctl-services-install.conf" if [ "$1" -eq 1 ]; then # it's a fresh install %{__cat} < true now that the nginx gateway # terminates TLS and the UI must trust X-Forwarded-Proto/Host headers. svcconfig="%{_sysconfdir}/flightctl/service-config.yaml" if [ -f "$svcconfig" ]; then %{__sed} -E -i 's/^([[:space:]]*trustXForwardedHeaders:[[:space:]]*)("false"|'"'"'false'"'"'|false)([[:space:]]*(#.*)?)$/\1true\3/' "$svcconfig" || : fi %{__cat} <<'EOF' [flightctl] Upgraded. Review status: systemctl list-units 'flightctl*' --all EOF fi %preun services # On package removal: stop and disable all services %systemd_preun %{flightctl_target} %systemd_preun flightctl-network.service %postun services # On upgrade: mark services for restart after transaction completes %systemd_postun_with_restart %{flightctl_target} # On full removal: delete temporary build/export storage that may contain # leftover subdirectories from interrupted jobs (non-empty dirs RPM won't remove). if [ "$1" -eq 0 ]; then rm -rf %{_var}/tmp/flightctl-builds || true rm -rf %{_var}/tmp/flightctl-exports || true fi # If contexts were managed via policy, no cleanup is needed here. %posttrans services # Reload systemd after all file operations (install + old-file removal) are # complete. The daemon-reload in %%post runs before the old package's files # are deleted, so quadlet files removed in this version are still visible to # systemd at that point. A second reload here picks up those removals. /usr/bin/systemctl daemon-reload >/dev/null 2>&1 || : # Clean up stale systemd units from quadlet files removed in previous # versions. Each unit may still be in systemd's active state from the # prior version; stop + reset-failed clears it so it no longer appears # in "systemctl list-units". # This block can be removed once all deployments have upgraded past this fix. # flightctl-cli-artifacts-init — removed in EDM-3783 (shipped in 1.0.0–1.1.2) # flightctl-alertmanager-proxy-init — removed in EDM-2304 (shipped in 0.10.0) for unit in \ flightctl-cli-artifacts-init.service \ flightctl-alertmanager-proxy-init.service \ ; do /usr/bin/systemctl stop "$unit" 2>/dev/null || : /usr/bin/systemctl reset-failed "$unit" 2>/dev/null || : done %files catalog-collector %defattr(0644,root,root,-) # Shared directories (also owned by the agent and services packages) %dir %{_sysconfdir}/flightctl %dir %attr(0755,root,root) %{_datadir}/flightctl %dir %{_datadir}/containers/systemd # Administrator-supplied configuration, credentials, and CA bundles. # Intentionally empty: the unit stays inactive until config.yaml exists. %dir %{_sysconfdir}/flightctl/flightctl-catalog-collector # Example configurations %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-catalog-collector %dir %attr(0755,root,root) %{_datadir}/flightctl/flightctl-catalog-collector/examples %{_datadir}/flightctl/flightctl-catalog-collector/examples/config-vanilla.yaml %{_datadir}/flightctl/flightctl-catalog-collector/examples/config-rhoai-to-flightctl.yaml %{_datadir}/flightctl/flightctl-catalog-collector/examples/vanilla-publish-8080.conf # Quadlet unit %{_datadir}/containers/systemd/flightctl-catalog-collector.container %post catalog-collector # Quadlet units are generated at daemon-reload time, so the generator has to # run before the unit exists. Enablement comes from the unit's [Install] # section, which the generator turns into the usual wants symlink. /usr/bin/systemctl daemon-reload >/dev/null 2>&1 || : if [ "$1" -eq 1 ]; then # fresh install %{__cat} </dev/null 2>&1 || : %changelog * Thu Oct 08 2026 Packit - 1.4.0~main~205~g454c21c09-1.20261008142632655928.main.205.g454c21c0 - NO-ISSUE: Support status.systemInfo.osMode field selector (#3709) (Ben Keith) - EDM-3708: Invalidate Helm prefetch cache when values change (#3704) (Efilaluck) - NO-ISSUE: Reduce routine delta log noise (#3717) (Asaf Ben Natan) - EDM-5243: and EDM-5231 Upstream OS and application delta guidance (#3716) (Asaf Ben Natan) - EDM-6228: Package and deploy flightctl-catalog-collector (#3710) (Assaf Albo) - NO-ISSUE: Exclude test tree from production image build stages (#3689) (Asaf Ben Natan) - EDM-6241: [CI] E2E test-vm fails to boot due to broken CentOS Stream 9 image (#3711) (hferber1) - EDM-4865: Show catalog item feature requirements on CLI (#3700) (Ben Keith) - NO-ISSUE: Embed OpenAPI specs as YAML instead of base64 blobs (#3708) (Chai-bot) - EDM-6108: Periodic Label Reconciliation (#3668) (Kyle Kyrazis) - EDM-4865: Prefer status.systemInfo.osMode with fallback to capabilities.osMode (#3652) (Ben Keith) - NO-ISSUE: synchronize integration test readiness and teardown (#3701) (Chai-bot) - EDM-6112: Ensure Device Ownership is resolved prior to rollout (#3707) (Kyle Kyrazis) - EDM-4865: Add gpus, kvm, and osMode to Device status.systemInfo (#3645) (Ben Keith) - EDM-5242: Document CI-published OS delta guidance (#3685) (Asaf Ben Natan) - EDM-6109: Prevent Managed Labels from being updated (#3666) (Kyle Kyrazis) - EDM-6238: Fix GetTopLevelDir to locate repo root via go.mod instead of PWD path matching (#3705) (amalykhi) - EDM-4865: Add device feature requirements to catalog item versions (#3644) (Ben Keith) - EDM-6227: Add Kubeflow Model Registry source to catalog collector (#3691) (Assaf Albo) - EDM-5228: fix application delta outcomes and updates after restart (#3703) (Asaf Ben Natan) - EDM-5276: fix CVE-2026-92615 on main (#3697) (Amir Yogev) - EDM-6093: Filter catalog items by fleet using field selectors (alternative) (#3696) (Chai-bot) - EDM-2822: Stop CLI after expired refresh token (#3684) (Efilaluck) - EDM-3761: fix confusing update-status message during critical resource alerts (#3673) (Efilaluck) - EDM-6223: resolve stale catalog application references (#3688) (Efilaluck) - NO-ISSUE: decouple Helm rendering from agent chart helpers (#3690) (Chai-bot) - NO-ISSUE: fix shared response mutation in API tests (#3686) (Asaf Ben Natan) - EDM-5230: fix Helm delta E2E handling (#3675) (Asaf Ben Natan) - EDM-5711: Document enrollment hook architecture and usage (#3687) (Gal Elharar) - EDM-6099: Add health checks and operational metrics to the catalog collector (#3682) (Assaf Albo) - EDM-5712: Add enrollment hook E2E coverage (#3661) (Eldar101) - EDM-6116: Label Provenance Endpoints (#3676) (Kyle Kyrazis) - EDM-6107: Reconcile Server Managed Labels on Status Update (#3664) (Kyle Kyrazis) - EDM-5955: Document periodic system info collection and systemInfoStatus (#3655) (Chai-bot) - EDM-5960: Bound periodic source execution (#3653) (Chai-bot) - NO-ISSUE: Update LabelSyncMapping API contract (#3677) (Kyle Kyrazis) - NO-ISSUE: Bump the docker group across 5 directories with 9 updates (#3621) (dependabot[bot]) - EDM-3792: Persist agent lastSeen synchronously (#3663) (Efilaluck) - EDM-6155: Remove orphaned required image from HelmApplication schema (#3670) (Chai-bot) - EDM-6106: Reconcile device labels through the service (#3656) (Kyle Kyrazis) - EDM-5962: Show collection status in CLI device detail (#3654) (Chai-bot) - EDM-5230: Add application delta e2e coverage (#3639) (Asaf Ben Natan) - EDM-6148: Add catalog collector framework and Flightctl destination (#3662) (Assaf Albo) - EDM-5311: Accept string CVSS scores from Quay (#3647) (Efilaluck) - EDM-6146: Remove EnrollmentHookPolicy OpenAPI security blocks (#3660) (Gal Elharar) - EDM-6144: docs: add user documentation for immediate alert status push (#3657) (Chai-bot) - EDM-5957: Enable auto-discovery of custom info scripts by default (#3561) (Kyle Kyrazis) - EDM-6087: immediate status push on critical alert transitions (#3651) (Chai-bot) - EDM-6104: LabelSyncMapping API and Stores (#3624) (Kyle Kyrazis) - EDM-5256: Add Quay vulnerability backend E2E coverage (#3593) (Efilaluck) - EDM-5630: Make AAP identity cache TTL configurable (#3575) (Chai-bot) - EDM-5633: Fix AAP pagination to handle relative next URLs (#3574) (Chai-bot) - EDM-5299: Add OTLP/HTTP forwarding documentation for telemetry gateway (#3604) (Assaf Albo) - EDM-5311: [DOCS][Upstream] Quay backend documentation for flightctl (#3599) (Efilaluck) - EDM-5709: Post-enrollment agent flow through condition reporting (#3635) (Gal Elharar) - EDM-3256: Detect integrated SoC GPUs on NVIDIA Jetson platforms (#3502) (Samuel De La Cruz Lopez) - EDM-5228: Apply application deltas (#3557) (Asaf Ben Natan) - EDM-5708: Enrollment hook notify worker with shared webhook delivery (#3629) (Gal Elharar) - NO-ISSUE: Remove disabled compatibility workflow path (#3636) (Asaf Ben Natan) - NO-ISSUE: retry destination manifest inspection for e2e image bundles (#3643) (Asaf Ben Natan) - EDM-6105: Add CEL evaluator (#3623) (Kyle Kyrazis) - EDM-5959: Report System Info Status (#3573) (Kyle Kyrazis) - NO-ISSUE: Strip design-doc and AC tags from comments (#3638) (Gal Elharar) - EDM-5227: Render application delta hints (#3556) (Asaf Ben Natan) - NO-ISSUE: Bump go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc (#3583) (dependabot[bot]) - EDM-5226: app image digests prepare deltas (#3514) (Asaf Ben Natan) - EDM-5303: Greenboot health check boot-loops devices when flightctl-agent is enabled but not enrolled (#3478) (bugs-buddy-jira-ai-issue-solver[bot]) - EDM-5707: Enrollment hook status API, ManualOverride, and events (#3602) (Gal Elharar) - EDM-5225: Add OS delta E2E coverage (#3464) (Asaf Ben Natan) - EDM-5225: Add production OS delta support (#3626) (Asaf Ben Natan) - NO-ISSUE: Reuse passed E2E results in merge queue (#3619) (Asaf Ben Natan) - NO-ISSUE: Add delta-worker to kind deployment (#3625) (Celia Amador Gonzalez) - EDM-5224: RenderDevice sets OS deltaImage and Updated.Size (#3459) (Asaf Ben Natan) - EDM-6026: Update vm-to-quadlet to 2d2a64d (#3618) (Asaf Ben Natan) - EDM-4985: use newer GHCR bootc image builder image (#3606) (Asaf Ben Natan) - NO-ISSUE: Group Dependabot updates by category (#3616) (Asaf Ben Natan) - EDM-5223: Hold rollout behind PrepareDeltas and resume once (#3457) (Asaf Ben Natan) - EDM-5705: Fleet selector and rendered-spec enrollment hooks gate (#3596) (Gal Elharar) - EDM-6027: Quote env var values in writeENVFile to prevent truncation (#3576) (Chai-bot) - EDM-5287: Use vm instead of a devicesim for RBAC lifecycle e2e test (#3600) (Itzik Brown) - NO-ISSUE: Switch service Containerfiles from flightctl-base to ubi-minimal (#3538) (Chai-bot) - EDM-5301: Add telemetry gateway forwarding E2E coverage (#3515) (Eldar101) - NO-ISSUE: Allow to skip mock cleanup when building RPMs (#3605) (Celia Amador Gonzalez) - NO-ISSUE: stabilize telemetry gateway integration startup (#3591) (Asaf Ben Natan) - EDM-6026: Support runAs for VM applications (#3572) (Asaf Ben Natan) - EDM-5223: Add delta completion event pipeline (#3589) (Asaf Ben Natan) - EDM-5958: Run systeminfo collection independently (#3562) (Kyle Kyrazis) - EDM-5770: Adjust e2e test 90246 to recent vm status change (#3594) (Itzik Brown) - EDM-5706: Add EnrollmentHooks condition, approval snapshot, and notify secrets (#3569) (Gal Elharar) - NO-ISSUE: Reconcile AGENTS.md architecture guidance (#3586) (Asaf Ben Natan) - EDM-5223: Extract delta worker foundation (#3587) (Asaf Ben Natan) - EDM-6030: Expose image builder operation timeouts (#3578) (Asaf Ben Natan) - NO-ISSUE: replace external nip.io DNS with local CoreDNS in kind (#3571) (Chai-bot) - EDM-4869: Expose vulnerability source in grouped views (#3555) (Efilaluck) - NO-ISSUE: Extend validation of RolloutPolicy for DeltaGeneration (#3577) (Celia Amador Gonzalez) - EDM-5222: Persist PrepareDeltas wait and emit generation progress events (#3455) (Asaf Ben Natan) - EDM-5222: Extract delta worker services (#3566) (Asaf Ben Natan) - NO-ISSUE: Protect access token refresher from concurrent read/write races (#3471) (Itzik Brown) - EDM-5222: Align delta worker deployment defaults (#3570) (Asaf Ben Natan) - NO-ISSUE: Bump kin-openapi and oapi-codegen in tools/go.mod to match main (#3563) (Chai-bot) - EDM-5222: Extract delta worker refactor layer (#3565) (Asaf Ben Natan) - EDM-5703: Add EnrollmentHookPolicy resource (#3544) (Gal Elharar) - EDM-5254: [DEV] Helm deployment for Quay backend (#3473) (Efilaluck) - EDM-5264: reject duplicate vm published host ports (#3549) (Asaf Ben Natan) - NO-ISSUE: Bump google.golang.org/grpc from 1.83.1 to 1.83.2 (#3546) (dependabot[bot]) - NO-ISSUE: Fix 4 GHSAs by bumping github.com/go-chi/chi/v5 to v5.3.0 (#3559) (Chai-bot) - NO-ISSUE: Fix CVE-2026-56855, CVE-2026-78662 by bumping golang.org/x/crypto to v0.56.0 (#3558) (Chai-bot) - EDM-5221: Emit PrepareDeltas types and list OS digest pairs (#3453) (Asaf Ben Natan) - EDM-5770: Align degraded VM application status (#3548) (Asaf Ben Natan) - NO-ISSUE: Update vm-to-quadlet to eb9f6ce (perf + version command) (#3535) (Asaf Ben Natan) - EDM-5253: Quay Scanner — resilience and concurrency (#3472) (Efilaluck) - NO-ISSUE: deduplicate organizations reported by auth providers, Fixes #3534 (#3536) (Miro Kolar) - EDM-5036: external DB support for encryption-at-rest e2e tests (#3366) (amalykhi) - NO-ISSUE: Avoid Helm uninstall PV reclaim race (#3552) (Asaf Ben Natan) - EDM-5702: Pre-enrollment lifecycle, ER fields, and failurePolicy (#3531) (Gal Elharar) - EDM-5889: pass current rlimit_nofile to imagebuilder-worker container so that it doesn't fail when trying to build container in container images (deployment on kubernetes) (#3547) (Luca Ferrari) - EDM-5717: Document VM render timeout (#3545) (Asaf Ben Natan) - EDM-5220: Generate one OS delta per image-repository digest pair (#3450) (Asaf Ben Natan) - EDM-5693: Use fixed nine-character Git hashes in build metadata (#3512) (Eldar101) - EDM-5046: revert third-party greenboot health check disable (#3537) (Gal Elharar) - EDM-5252: Quay Scanner — finding conversion and integration (#3469) (Efilaluck) - EDM-3773: Preserve prefetch errors across OS rollback status (#3477) (Kyle Kyrazis) - EDM-5701: Enrollment hook types, hooks.d, and hook-context (#3530) (Gal Elharar) - EDM-4844: Enforce service-only access to resource stores (#3406) (Asaf Ben Natan) - EDM-5571: update vm-to-quadlet to 000e218 (StopTimeout/ExitPolicy fix) (#3513) (Asaf Ben Natan) - EDM-5718: flightctl-cleanup Job logs Failed to watch errors during helm uninstall (#3527) (hferber1) - EDM-5219: Run generation on a dedicated delta-worker and queue (#3446) (Asaf Ben Natan) - EDM-5251: Quay Security API client — fetch and filter (#3466) (Efilaluck) - EDM-5218: Configure a writable OCI target for generated deltas (#3443) (Asaf Ben Natan) - EDM-4834: Remove business-rule validationCallbacks (#3405) (Asaf Ben Natan) - EDM-5288: Wait for healthy VM apps before fleet SSH checks (#3503) (Eldar101) - NO-ISSUE: Patch CVE-2026-50162 — update oras-go to v2.6.2 (#3508) (Chai-bot) - NO-ISSUE: Update NetworkPolicy to allow the OpenShift router to reach the Grafana pod (#3421) (Itzik Brown) - EDM-5217: Persist delta prepares and generations (#3439) (Asaf Ben Natan) - NO-ISSUE: Aggregate Dependabot dependency updates (#3500) (Chai-bot) - EDM-5297: Implement OTLP/HTTP forwarding with custom headers (#3462) (Assaf Albo) - EDM-5345: Fix CVE-2026-42504 by bumping Go minimum version to 1.26.4 (#3505) (Chai-bot) - EDM-4892: remove empty directories after removing a host configuration source (#3493) (Efilaluck) - EDM-4115: e2e test for a domain of a vm app is crashed (#3452) (Itzik Brown) - EDM-4832: Condition merge in the service layer (#3403) (Asaf Ben Natan) - EDM-5250: Quay configuration and backend selection (#3463) (Efilaluck) - EDM-5214: Agent discovers and applies an OS delta, or falls back to a full pull (#3424) (Asaf Ben Natan) - NO-ISSUE: Resolve package-mode enrollment host in Podman (#3494) (Eldar101) - EDM-4115: e2e tests for vm app with volumes (#3451) (Itzik Brown) - EDM-2740: Server-side view of the lifecycle status does not have guardrails (#3361) (bugs-buddy-jira-ai-issue-solver[bot]) - EDM-5249: Trustify Scanner adapter and sync task refactor (#3437) (Efilaluck) - EDM-5419: Clarify compose provider requirements in documentation (#3495) (Chai-bot) - EDM-5213: Report OS delta consumer fields on systemInfo (#3425) (Asaf Ben Natan) - NO-ISSUE: Bump github.com/go-git/go-git/v5 from 5.16.0 to 5.19.2 (#3352) (dependabot[bot]) - NO-ISSUE: pin setup-go cache-dependency-path to avoid post-step cache failure (#3488) (Amir Yogev) - NO-ISSUE: patch CVE-2026-44740 in go-git/go-billy (#3485) (Amir Yogev) - EDM-3085: Wire DEFAULT_AAP_APP_NAME through Makefile ldflags for downstream branding (#3481) (Chai-bot) - EDM-5195: patch CVE-2026-33818 (encoding/asn1 DoS) via Go toolchain bump to go1.26.7 (#3480) (Amir Yogev) - EDM-2966: Normalizing baseDomain to lowercase (#2512) (Gal Elharar) - EDM-5290: Fix flaky VM agent helm e2e test 87874 (registry outage across quadlet re-create) (#3479) (Samuel De La Cruz Lopez) - EDM-4115: Fix login lockout for vm app tests (#3470) (Itzik Brown) - EDM-4205: E2E tests for WiFi AP onboarding access (#3465) (Samuel De La Cruz Lopez) - EDM-4503: patch CVE-2026-27145 (crypto/x509 DoS) via Go toolchain bump to go1.26.5 (#3467) (Amir Yogev) - NO-ISSUE: Fix typo in decomission test labels (#3468) (Itzik Brown) - EDM-4203: E2E tests for enrollment and completion flow (#3461) (Samuel De La Cruz Lopez) - EDM-4193: E2E tests for onboarding service lifecycle (#3460) (Samuel De La Cruz Lopez) - EDM-5248: Define Scanner interface and extend store query (#3434) (Efilaluck) - EDM-5284: Accept runAs alongside catalog item references (#3442) (Ben Keith) - EDM-4090: Add lifecycle apps test (#3430) (Itzik Brown) - EDM-4199: E2E tests for wizard configuration flow (#3454) (Samuel De La Cruz Lopez) - NO-ISSUE: Preload package-mode helper image for e2e (#3435) (Eldar101) - EDM-4845: Retry transient vulnerability fleet creation (#3447) (Eldar101) - EDM-3772: stabilize rollout disruption budget test (#3418) (Eldar101) - EDM-4813: Wait for catalog ref OS updates through reboot (#3449) (Eldar101) - NO-ISSUE: Reset device labels in E2E helper (#3448) (Eldar101) - EDM-5283: Fall back to socat when virt-launcher has no nc (#3440) (Asaf Ben Natan) - EDM-5202: Add fleet detach application summary e2e (#3419) (Eldar101) - EDM-4115: Add fleet VM lifecycle e2e and RBAC coverage for app commands (#3420) (Asaf Ben Natan) - NO-ISSUE: Add risk label justification to CodeRabbit PR summary (#3431) (Andy Dalton) - EDM-5266: Select virt-launcher image from device OS major (#3429) (Asaf Ben Natan) - EDM-4115: Add VM e2e tests for spec updates, crash recovery and console exclusivity (#3414) (Itzik Brown) - NO-ISSUE: Add Ship/Show/Ask risk classification labels to CodeRabbit (#3415) (Andy Dalton) - EDM-4830: Device decommission decisions in service (#3402) (Asaf Ben Natan) - EDM-4115: Add dual-VM e2e test for concurrent apps and publishPorts (#3412) (Itzik Brown) - EDM-5204: do not fail RPM %%pre when no dry-run temp script is created (#3413) (Asaf Ben Natan) - EDM-4115: Extend VM e2e Basic test (#3379) (Itzik Brown) - NO-ISSUE: include remote-access in flightctl.target (#3380) (Asaf Ben Natan) - EDM-5037: Use host networking for ImageExport bootc-image-builder (#3360) (Asaf Ben Natan) - NO-ISSUE: fix flaky management cert rotation integration test (#3376) (Asaf Ben Natan) - EDM-4335: agent rendered-error backoff and status jitter (#3337) (Asaf Ben Natan) - Fixes #3347: Add aarch64 container image builds (#3226) (kkyrazis) - NO-ISSUE: align package image preload with testcontainers runtime (#3375) (Eldar101) - EDM-4742: Remove the ready-replica gate for Running (#3370) (Itzik Brown) - EDM-5028: fix Mutate status poisoning without LastSeen; trim UpdateStatus clones (#3369) (Asaf Ben Natan) - EDM-5035: Allow Helm stop/start when rendered lifecycle fields are present (#3357) (Asaf Ben Natan) - NO-ISSUE: Skip redundant FleetRolloutDeviceSelected re-renders (#3368) (Asaf Ben Natan) - EDM-4768: add package-mode e2e suite (#3354) (Eldar101) - EDM-5028: Add Device/Fleet Mutate CAS with status/annotation wrappers (#3353) (Asaf Ben Natan) - EDM-4780: add encryption-at-rest e2e tests (#3292) (amalykhi) - EDM-4968: Package-mode OS guards for spec.os.catalogItemRef (#3356) (Gal) - EDM-4851: add e2e test for imagebuild with Basic-auth registry (#3313) (amalykhi) - NO-ISSUE: Clarify VM app console not-ready errors with a stable error code (#3358) (Asaf Ben Natan) - EDM-4842: Fix console rendered version e2e assertion (#3355) (Eldar101) - EDM-4988: Keep crash-looping VM apps Degraded until healthy (#3351) (Asaf Ben Natan) - EDM-4970: Harden authprovider API readiness probe (#3329) (Eldar101) - NO-ISSUE: Clarify imagebuilder RHEL config and use quadlet drop-ins (#3349) (kkyrazis) - EDM-4988: Improve VM application error visibility (#3346) (Asaf Ben Natan) - NO-ISSUE: Stop systemd services and reset failed status after an app stop (#3335) (Itzik Brown) - EDM-4066: Add catalog item references e2e tests (#3308) (talhil-rh) - EDM-5023: Fix Podman restore race condition and use safe SQL identifier quoting (#3348) (amalykhi) * Tue Oct 06 2026 Flight Control Maintainers - 1.0-1 - Add catalog-collector sub-package with Quadlet unit and example configurations * Wed Nov 26 2025 Dakota Crowder - 1.0-1 - Adding certificate generation service * Mon Nov 17 2025 Dakota Crowder - 1.0-1 - Refactoring quadlet install, add standalone utils * Wed Nov 12 2025 Ben Keith - 1.0-1 - Make observability and telemetry-gateway packages require services package * Mon Oct 27 2025 Dakota Crowder - 1.0-1 - Add must-gather script for the services sub package * Wed Oct 8 2025 Ilya Skornyakov - 0.10.0 - Add pre-upgrade database migration dry-run capability * Tue Jul 15 2025 Sam Batschelet - 0.9.0-2 - Improve selinux policy deps and install * Sun Jul 6 2025 Ori Amizur - 0.9.0-1 - Add support for Flight Control standalone observability stack * Tue Apr 15 2025 Dakota Crowder - 0.6.0-4 - Add ability to create an AAP Oauth Application within flightctl-services sub-package * Fri Apr 11 2025 Dakota Crowder - 0.6.0-3 - Add versioning to container images within flightctl-services sub-package * Thu Apr 3 2025 Ori Amizur - 0.6.0-2 - Add sos report plugin support * Mon Mar 31 2025 Dakota Crowder - 0.6.0-1 - Add services sub-package for installation of containerized flightctl services * Fri Feb 7 2025 Miguel Angel Ajo - 0.4.0-1 - Add selinux support for console pty access * Mon Nov 4 2024 Miguel Angel Ajo - 0.3.0-1 - Move the Release field to -1 so we avoid auto generating packages with -5 all the time. * Wed Aug 21 2024 Sam Batschelet - 0.0.1-5 - Add must-gather script to provide a simple mechanism to collect agent debug * Wed Aug 7 2024 Sam Batschelet - 0.0.1-4 - Add basic greenboot support for failed flightctl-agent service * Wed Mar 13 2024 Ricardo Noriega - 0.0.1-3 - New specfile for both CLI and agent packages