fix(rpm): standardize systemd scriptlets and unit installation paths

- Add BuildRequires: systemd-rpm-macros to sentinel and correlator specs
- Replace manual systemctl calls with %systemd_post, %systemd_preun,
  %systemd_postun_with_restart macros (handles daemon-reload, stop/disable,
  try-restart on upgrade correctly and is a no-op in containers)
- ja4sentinel.spec: use %{_unitdir} macro instead of hardcoded path
  (/usr/lib/systemd/system); remove cross-service /var/run/logcorrelator
  from %files and %post (owned by logcorrelator package, not sentinel)
- logcorrelator.spec: move unit from /etc/systemd/system (admin namespace)
  to %{_unitdir} (/usr/lib/systemd/system) — correct packaging location;
  move user/group creation from %post to %pre so file ownership is valid
  during RPM install phase; add Requires(pre): shadow-utils; fix bare
  directory entries in %files with %dir macro; add version fallback macro
  so spec is buildable without --define version
- test-rpm.sh: auto-build RPM via Dockerfile.package if dist/rpm/ is
  empty; update service file path check to /usr/lib/systemd/system/

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
toto
2026-04-08 10:49:21 +02:00
parent f7ee5e63f8
commit f448dcb4b0
3 changed files with 75 additions and 88 deletions

View File

@ -3,7 +3,7 @@
# Built with rpmbuild (not FPM)
Name: logcorrelator
Version: %{version}
Version: %{spec_version}
Release: 1%{?dist}
Summary: Log correlation service for HTTP and network events
@ -14,11 +14,20 @@ Packager: logcorrelator <dev@example.com>
BuildArch: x86_64
# Version macro with safe fallback
%if %{defined version}
%define spec_version %{version}
%else
%define spec_version 1.1.22
%endif
# Dependencies
Requires: systemd
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
Requires: systemd
Requires(pre): shadow-utils
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
BuildRequires: systemd-rpm-macros
%description
logcorrelator est un service système écrit en Go qui reçoit deux flux de logs JSON
@ -42,11 +51,9 @@ ls -la %{_builddir}/
mkdir -p %{buildroot}/usr/bin
mkdir -p %{buildroot}/etc/logcorrelator
mkdir -p %{buildroot}/var/log/logcorrelator
mkdir -p %{buildroot}/var/run/logcorrelator
mkdir -p %{buildroot}/var/lib/logcorrelator
mkdir -p %{buildroot}/etc/systemd/system
mkdir -p %{buildroot}%{_unitdir}
mkdir -p %{buildroot}/etc/logrotate.d
mkdir -p %{buildroot}/usr/lib/tmpfiles.d
# Install binary (from BUILD directory)
install -m 0755 %{_builddir}/usr/bin/logcorrelator %{buildroot}/usr/bin/logcorrelator
@ -55,18 +62,17 @@ install -m 0755 %{_builddir}/usr/bin/logcorrelator %{buildroot}/usr/bin/logcorre
install -m 0640 %{_builddir}/etc/logcorrelator/logcorrelator.yml %{buildroot}/etc/logcorrelator/logcorrelator.yml
install -m 0640 %{_builddir}/etc/logcorrelator/logcorrelator.yml.example %{buildroot}/etc/logcorrelator/logcorrelator.yml.example
# Install systemd service
install -m 0644 %{_builddir}/etc/systemd/system/logcorrelator.service %{buildroot}/etc/systemd/system/logcorrelator.service
# Install systemd service — destination is %{_unitdir} (/usr/lib/systemd/system), never /etc/
install -m 0644 %{_builddir}/etc/systemd/system/logcorrelator.service %{buildroot}%{_unitdir}/logcorrelator.service
# Install logrotate config
install -m 0644 %{_builddir}/etc/logrotate.d/logcorrelator %{buildroot}/etc/logrotate.d/logcorrelator
%post
# Create logcorrelator user and group
%pre
# Create service user and group before file installation so %attr() works correctly
if ! getent group logcorrelator >/dev/null 2>&1; then
groupadd --system logcorrelator
fi
if ! getent passwd logcorrelator >/dev/null 2>&1; then
useradd --system \
--gid logcorrelator \
@ -76,20 +82,22 @@ if ! getent passwd logcorrelator >/dev/null 2>&1; then
logcorrelator
fi
# Create directories
mkdir -p /var/lib/logcorrelator
mkdir -p /var/log/logcorrelator
# Note: /var/run/logcorrelator est géré par RuntimeDirectory= (systemd) et tmpfiles.d
%post
# Use standard systemd RPM macros (daemon-reload, preset, no-op in containers)
%systemd_post logcorrelator.service
# Explicitly enable+start on fresh install
if [ $1 -eq 1 ] && [ -x /usr/bin/systemctl ] && [ -d /run/systemd/system ]; then
/usr/bin/systemctl enable logcorrelator.service 2>/dev/null || :
/usr/bin/systemctl start logcorrelator.service 2>/dev/null || :
fi
# Set ownership
chown -R logcorrelator:logcorrelator /var/lib/logcorrelator
chown -R logcorrelator:logcorrelator /var/log/logcorrelator
chown -R logcorrelator:logcorrelator /etc/logcorrelator
# Set permissions
chmod 750 /var/lib/logcorrelator
chmod 750 /var/log/logcorrelator
chmod 750 /etc/logcorrelator
# Set ownership and permissions (idempotent — safe on both install and upgrade)
chown -R logcorrelator:logcorrelator /var/lib/logcorrelator 2>/dev/null || true
chown -R logcorrelator:logcorrelator /var/log/logcorrelator 2>/dev/null || true
chown -R logcorrelator:logcorrelator /etc/logcorrelator 2>/dev/null || true
chmod 750 /var/lib/logcorrelator 2>/dev/null || true
chmod 750 /var/log/logcorrelator 2>/dev/null || true
chmod 750 /etc/logcorrelator 2>/dev/null || true
# Copy default config if not exists
if [ ! -f /etc/logcorrelator/logcorrelator.yml ]; then
@ -98,44 +106,19 @@ if [ ! -f /etc/logcorrelator/logcorrelator.yml ]; then
chmod 640 /etc/logcorrelator/logcorrelator.yml
fi
# Reload systemd and start service
if [ -x /bin/systemctl ]; then
systemctl daemon-reload
systemctl enable logcorrelator.service
systemctl start logcorrelator.service
fi
exit 0
%preun
if [ $1 -eq 0 ]; then
# Package removal, not upgrade
if [ -x /bin/systemctl ]; then
systemctl stop logcorrelator.service
systemctl disable logcorrelator.service
fi
fi
exit 0
%systemd_preun logcorrelator.service
%postun
if [ -x /bin/systemctl ]; then
systemctl daemon-reload
if [ $1 -ge 1 ]; then
# Package upgrade, restart service
systemctl try-restart logcorrelator.service
fi
fi
exit 0
%systemd_postun_with_restart logcorrelator.service
%files
/usr/bin/logcorrelator
%config(noreplace) /etc/logcorrelator/logcorrelator.yml
/etc/logcorrelator/logcorrelator.yml.example
/var/log/logcorrelator
/var/lib/logcorrelator
/etc/systemd/system/logcorrelator.service
%dir /var/log/logcorrelator
%dir /var/lib/logcorrelator
%{_unitdir}/logcorrelator.service
%config(noreplace) /etc/logrotate.d/logcorrelator
%changelog

View File

@ -44,12 +44,24 @@ case "${DISTRO}" in
;;
esac
# Find the latest RPM file
# Find the latest RPM file — build it first if missing
RPM_FILE=$(ls -t "${RPM_PATH}"/logcorrelator-*.rpm 2>/dev/null | head -n 1)
if [ -z "${RPM_FILE}" ]; then
echo "ERROR: No RPM file found in ${RPM_PATH}"
echo "Please run 'make package-rpm' first"
echo "No RPM found in ${RPM_PATH} — building now via Dockerfile.package..."
REPO_ROOT="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")"
VERSION="${VERSION:-$(git -C "${REPO_ROOT}" describe --tags --abbrev=0 2>/dev/null | sed 's/^v//' || echo "0.0.0-dev")}"
docker build \
--build-arg VERSION="${VERSION}" \
-f "${REPO_ROOT}/services/correlator/Dockerfile.package" \
--target output \
-o "${RPM_DIR}" \
"${REPO_ROOT}"
RPM_FILE=$(ls -t "${RPM_PATH}"/logcorrelator-*.rpm 2>/dev/null | head -n 1)
fi
if [ -z "${RPM_FILE}" ]; then
echo "ERROR: RPM build failed — no RPM found in ${RPM_PATH}"
exit 1
fi
@ -177,11 +189,12 @@ echo "OK: $EXAMPLE_CONFIG - owner=$OWNER, permissions=$PERMS"
echo ""
echo "=== Checking systemd service ==="
if [ ! -f /etc/systemd/system/logcorrelator.service ]; then
echo "FAIL: systemd service file not found"
# Packaged units must be in /usr/lib/systemd/system, not /etc/systemd/system
if [ ! -f /usr/lib/systemd/system/logcorrelator.service ]; then
echo "FAIL: systemd service file not found at /usr/lib/systemd/system/logcorrelator.service"
exit 1
fi
echo "OK: systemd service file exists"
echo "OK: systemd service file exists at /usr/lib/systemd/system/"
echo ""
echo "=== Checking logrotate config ==="

View File

@ -13,10 +13,13 @@ Summary: JA4 TLS fingerprinting daemon for network monitoring
License: MIT
URL: https://github.com/your-repo/ja4sentinel
BuildArch: x86_64
BuildRequires: systemd-rpm-macros
# Distribution-agnostic dependencies
# systemd is available on all target distros (Rocky 8/9/10, AlmaLinux)
Requires: systemd
Requires: systemd
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
# libpcap is required for packet capture (dynamically linked)
# Version varies by distro: Rocky 8/9/10 (1.9.0+)
Requires: libpcap >= 1.9.0
@ -55,7 +58,7 @@ mkdir -p %{buildroot}/usr/share/ja4sentinel
install -m 755 %{_sourcedir}/ja4sentinel %{buildroot}/usr/bin/ja4sentinel
# Install systemd service
install -m 644 %{_sourcedir}/ja4sentinel.service %{buildroot}/usr/lib/systemd/system/ja4sentinel.service
install -m 644 %{_sourcedir}/ja4sentinel.service %{buildroot}%{_unitdir}/ja4sentinel.service
# Install logrotate configuration
install -m 644 %{_sourcedir}/logrotate/ja4sentinel %{buildroot}/etc/logrotate.d/ja4sentinel
@ -69,9 +72,16 @@ install -m 640 %{_sourcedir}/config.yml %{buildroot}/usr/share/ja4sentinel/confi
exit 0
%post
# Use standard systemd RPM macros (handles daemon-reload, preset, no-op in containers)
%systemd_post ja4sentinel.service
# Explicitly enable+start on fresh install — this is a security daemon, auto-start is expected
if [ $1 -eq 1 ] && [ -x /usr/bin/systemctl ] && [ -d /run/systemd/system ]; then
/usr/bin/systemctl enable ja4sentinel.service 2>/dev/null || :
/usr/bin/systemctl start ja4sentinel.service 2>/dev/null || :
fi
# Set proper ownership (root:root for packet capture)
chown -R root:root /var/lib/ja4sentinel 2>/dev/null || true
chown -R root:root /var/run/logcorrelator 2>/dev/null || true
chown -R root:root /var/log/ja4sentinel 2>/dev/null || true
chown -R root:root /etc/ja4sentinel 2>/dev/null || true
@ -86,40 +96,21 @@ if [ ! -f /etc/ja4sentinel/config.yml ]; then
chmod 640 /etc/ja4sentinel/config.yml
fi
# Reload systemd and enable service (only if systemd is running)
if [ -x /bin/systemctl ] && [ -d /run/systemd/system ]; then
/bin/systemctl daemon-reload
/bin/systemctl enable ja4sentinel.service 2>/dev/null || :
/bin/systemctl start ja4sentinel.service 2>/dev/null || :
fi
%preun
if [ $1 -eq 0 ]; then
# Package removal, stop and disable service
if [ -x /bin/systemctl ]; then
/bin/systemctl stop ja4sentinel.service >/dev/null 2>&1 || :
/bin/systemctl disable ja4sentinel.service >/dev/null 2>&1 || :
fi
fi
%systemd_preun ja4sentinel.service
%postun
if [ $1 -eq 0 ]; then
# Package removal, reload systemd
if [ -x /bin/systemctl ]; then
/bin/systemctl daemon-reload
fi
fi
%systemd_postun_with_restart ja4sentinel.service
%files
/usr/bin/ja4sentinel
/usr/lib/systemd/system/ja4sentinel.service
%{_unitdir}/ja4sentinel.service
/etc/logrotate.d/ja4sentinel
/usr/share/ja4sentinel/config.yml
%config(noreplace) /etc/ja4sentinel/config.yml.default
%dir /etc/ja4sentinel
%dir /var/lib/ja4sentinel
%dir /var/log/ja4sentinel
%dir /var/run/logcorrelator
%changelog