@cryptotaxi247 / netdata-1 / commits / 0b04755a1

Use systemd-tmpfiles to handle required directories at runtime when possible. (#21243)

* Use systemd-tmpfiles to handle required directories. This pushes handling of permissions and ownership of our required directories to systemd-tmpfiles when possible, which helps persistently ensure that they are correct, and allows us to make at least some Netdata service files both simpler and more reliable. * Address review comments. * Fix typos. * Update directory creation to be more robust. * Update tmpfiles config to more robustly ensure correct permissions. This adds new entries for the cloud.d and registry directories to be created, as well as adding entries to apply correct permissions and ownership for database files, claiming configuration, and a handful of other files.

Austin S. Hemmelgarn committed Dec 3, 2025 at 11:29 UTC 0b04755a1039cb1d5651e19af35650feb71577a0
10 files changed +103 -35
CMakeLists.txt
+11
@@ -3313,6 +3313,7 @@ set(libconfigdir_POST "${LIBCONFIG_DIR}")
3313 set(cachedir_POST "${CACHE_DIR}")
3314 set(varlibdir_POST "${VARLIB_DIR}")
3315 set(registrydir_POST "${VARLIB_DIR}/registry")
3316 +set(logdir_POST "${LOG_DIR}")
3317 set(netdata_user_POST "${NETDATA_USER}")
3318 set(netdata_group_POST "${NETDATA_USER}")
3319
@@ -3481,6 +3482,12 @@ install(FILES
3482 COMPONENT netdata
3483 DESTINATION usr/lib/netdata/system/systemd/sysusers)
3484
3485 +configure_file(system/systemd/tmpfiles.conf.in system/systemd/tmpfiles/netdata.conf @ONLY)
3486 +install(FILES
3487 + ${CMAKE_BINARY_DIR}/system/systemd/tmpfiles/netdata.conf
3488 + COMPONENT netdata
3489 + DESTINATION usr/lib/netdata/system/systemd/tmpfiles)
3490 +
3491 if(BUILD_FOR_PACKAGING)
3492 install(FILES
3493 ${CMAKE_BINARY_DIR}/system/systemd/netdata.service
@@ -3490,6 +3497,10 @@ if(BUILD_FOR_PACKAGING)
3497 ${CMAKE_BINARY_DIR}/system/systemd/sysusers/netdata.conf
3498 COMPONENT user
3499 DESTINATION usr/lib/sysusers.d)
3500 + install(FILES
3501 + ${CMAKE_BINARY_DIR}/system/systemd/tmpfiles/netdata.conf
3502 + COMPONENT netdata
3503 + DESTINATION usr/lib/tmpfiles.d)
3504 install(DIRECTORY
3505 COMPONENT netdata
3506 DESTINATION usr/lib/systemd/journald@netdata.conf.d)
netdata-installer.sh
+3 -27
@@ -754,8 +754,8 @@ fi
754 [ -L "${NETDATA_USER_CONFIG_DIR}/orig" ] && run rm -f "${NETDATA_USER_CONFIG_DIR}/orig"
755 run ln -s "${NETDATA_STOCK_CONFIG_DIR}" "${NETDATA_USER_CONFIG_DIR}/orig"
756
757 -# --- web dir ----
757
758 +# --- web dir ---
759 if [ ! -d "${NETDATA_WEB_DIR}" ]; then
760 echo >&2 "Creating directory '${NETDATA_WEB_DIR}'"
761 run mkdir -p "${NETDATA_WEB_DIR}" || exit 1
@@ -763,33 +763,9 @@ fi
763 run find "${NETDATA_WEB_DIR}" -type f -exec chmod 0664 {} \;
764 run find "${NETDATA_WEB_DIR}" -type d -exec chmod 0775 {} \;
765
766 -# --- data dirs ----
766 +# --- other dirs ----
767
768 -for x in "${NETDATA_LIB_DIR}" "${NETDATA_CACHE_DIR}" "${NETDATA_LOG_DIR}"; do
769 - if [ ! -d "${x}" ]; then
770 - echo >&2 "Creating directory '${x}'"
771 - if ! run mkdir -p "${x}"; then
772 - warning "Failed to create ${x}, it must be created by hand or the Netdata Agent will not be able to be started."
773 - fi
774 - fi
775 -
776 - run chown -R "${NETDATA_USER}:${NETDATA_GROUP}" "${x}"
777 - #run find "${x}" -type f -exec chmod 0660 {} \;
778 - #run find "${x}" -type d -exec chmod 0770 {} \;
779 -done
780 -
781 -run chmod 755 "${NETDATA_LOG_DIR}"
782 -
783 -# --- claiming dir ----
784 -
785 -if [ ! -d "${NETDATA_CLAIMING_DIR}" ]; then
786 - echo >&2 "Creating directory '${NETDATA_CLAIMING_DIR}'"
787 - if ! run mkdir -p "${NETDATA_CLAIMING_DIR}"; then
788 - warning "failed to create ${NETDATA_CLAIMING_DIR}, it will need to be created manually."
789 - fi
790 -fi
791 -run chown -R "${NETDATA_USER}:${NETDATA_GROUP}" "${NETDATA_CLAIMING_DIR}"
792 -run chmod 770 "${NETDATA_CLAIMING_DIR}"
768 +install_netdata_dirs
769
770 # --- plugins ----
771
netdata.spec.in
+20
@@ -522,9 +522,28 @@ install -m 755 -d "${RPM_BUILD_ROOT}%{_presetdir}"
522 install -m 644 -p "system/systemd/50-%{name}.preset" "${RPM_BUILD_ROOT}%{_presetdir}/50-%{name}.preset"
523 install -m 755 -d "${RPM_BUILD_ROOT}%{_systemd_util_dir}/journald@%{name}.conf.d"
524 install -m 644 -p "system/systemd/journald@%{name}.conf" "${RPM_BUILD_ROOT}%{_systemd_util_dir}/journald@%{name}.conf.d/%{name}.conf"
525 +install -m 755 -d "${RPM_BUILD_ROOT}%{_tmpfilesdir}"
526 +install -m 644 -p "%{__cmake_builddir}/system/systemd/tmpfiles/%{name}.conf" "${RPM_BUILD_ROOT}%{_tmpfilesdir}/%{name}.conf"
527 install -m 755 -d "${RPM_BUILD_ROOT}%{_sysusersdir}"
528 install -m 644 -p "%{__cmake_builddir}/system/systemd/sysusers/%{name}.conf" "${RPM_BUILD_ROOT}%{_sysusersdir}/%{name}.conf"
529
530 +%pre
531 +
532 +if ! getent group %{name} > /dev/null; then
533 + groupadd --system %{name}
534 +fi
535 +
536 +if ! getent passwd %{name} > /dev/null; then
537 + useradd --system -g %{name} --home %{contentdir} --no-create-home -s /sbin/nologin -c "Netdata pseudo user" %{name}
538 +fi
539 +
540 +# I am not sure that the corresponding group names are exactly the same as in Debian, but we should start somewhere, shouldn't we?
541 +for item in docker nginx varnish haproxy adm nsd proxy squid ceph nobody I2C; do
542 + if getent group $item > /dev/null 2>&1; then
543 + usermod -a -G ${item} %{name}
544 + fi
545 +done
546 +
547 %post
548 %if 0%{?suse_version}
549 %service_add_post %{name}.service
@@ -584,6 +603,7 @@ rm -rf "${RPM_BUILD_ROOT}"
603 %{_unitdir}/%{name}-updater.service
604 %{_presetdir}/50-%{name}.preset
605 %{_systemd_util_dir}/journald@%{name}.conf.d/%{name}.conf
606 +%{_tmpfilesdir}/%{name}.conf
607
608 %{_datarootdir}/%{name}/build-info-cmake-cache.gz
609
packaging/installer/functions.sh
+41
@@ -745,6 +745,47 @@ install_netdata_service() {
745 return 1
746 }
747
748 +install_netdata_tmpfiles() {
749 + if [ "${UID}" -eq 0 ]; then
750 + run mkdir -p /usr/lib/tmpfiles.d || return 1
751 + run install -m 0644 -p "${NETDATA_PREFIX}/usr/lib/netdata/system/systemd/tmpfiles/netdata.conf" /usr/lib/tmpfiles.d/netdata.conf || return 1
752 + return 0
753 + else
754 + return 1
755 + fi
756 +}
757 +
758 +install_netdata_dirs() {
759 + _DIRS_INSTALLED=0
760 + if install_netdata_tmpfiles && command -v systemd-tmpfiles >/dev/null 2>&1 ; then
761 + systemd-tmpfiles --create /usr/lib/tmpfiles.d/netdata.conf && _DIRS_INSTALLED=1
762 + fi
763 +
764 + if [ "${_DIRS_INSTALLED}" -eq 0 ]; then
765 + for x in "${NETDATA_LIB_DIR}" "${NETDATA_CACHE_DIR}" "${NETDATA_LOG_DIR}"; do
766 + if [ ! -d "${x}" ]; then
767 + echo >&2 "Creating directory '${x}'"
768 + if ! run mkdir -p "${x}"; then
769 + warning "Failed to create ${x}, it must be created by hand or the Netdata Agent will not be able to be started."
770 + fi
771 + fi
772 +
773 + run chown -R "${NETDATA_USER}:${NETDATA_GROUP}" "${x}"
774 + done
775 +
776 + run chmod 755 "${NETDATA_LOG_DIR}"
777 +
778 + if [ ! -d "${NETDATA_CLAIMING_DIR}" ]; then
779 + echo >&2 "Creating directory '${NETDATA_CLAIMING_DIR}'"
780 + if ! run mkdir -p "${NETDATA_CLAIMING_DIR}"; then
781 + warning "failed to create ${NETDATA_CLAIMING_DIR}, it will need to be created manually."
782 + fi
783 + fi
784 + run chown -R "${NETDATA_USER}:${NETDATA_GROUP}" "${NETDATA_CLAIMING_DIR}"
785 + run chmod 770 "${NETDATA_CLAIMING_DIR}"
786 + fi
787 +}
788 +
789 # -----------------------------------------------------------------------------
790 # stop netdata
791
packaging/installer/netdata-uninstaller.sh
+1
@@ -811,6 +811,7 @@ fi
811
812 rm_file /etc/logrotate.d/netdata
813 rm_file /etc/init.d/netdata
814 +rm_file /usr/lib/tmpfiles.d/netdata.conf
815 rm_file /Library/LaunchDaemons/com.github.netdata.plist
816
817 if [ -n "${NETDATA_PREFIX}" ] && [ -d "${NETDATA_PREFIX}" ] && [ "netdata" = "$(basename "$NETDATA_PREFIX")" ] ; then
packaging/makeself/install-or-update.sh
+2 -1
@@ -169,7 +169,8 @@ progress "fix permissions"
169
170 run chmod g+rx,o+rx /opt
171 run find /opt/netdata -type d -exec chmod go+rx '{}' \+
172 -run chown -R ${NETDATA_USER}:${NETDATA_GROUP} /opt/netdata/var
172 +
173 +install_netdata_dirs
174
175 if [ -d /opt/netdata/usr/libexec/netdata/plugins.d/ebpf.d ]; then
176 run chown -R root:${NETDATA_GROUP} /opt/netdata/usr/libexec/netdata/plugins.d/ebpf.d
system/openrc/init.d/netdata.in
+6 -1
@@ -16,8 +16,13 @@ command_args="-P ${NETDATA_PIDFILE} ${NETDATA_EXTRA_ARGS}"
16 command_args_foreground="-D"
17
18 depend() {
19 + # Gentoo and its derivatives still use systemd-tmpfiles even with OpenRC, Alpine does not.
20 + if rc-service --exists systemd-tmpfiles-setup; then
21 + need net systemd-tmpfiles-setup
22 + else
23 + need net
24 + fi
25 use logger
20 - need net
26 after apache2 squid nginx mysql named opensips upsd hostapd postfix lm_sensors
27 }
28
system/systemd/netdata.service.in
+2 -4
@@ -3,8 +3,8 @@
3 Description=Netdata, X-Ray Vision for your infrastructure!
4
5 # append here other services you want netdata to wait for them to start
6 -After=network.target network-online.target nss-lookup.target
7 -Wants=network-online.target nss-lookup.target
6 +After=systemd-tmpfiles-setup.service network.target network-online.target nss-lookup.target
7 +Wants=systemd-tmpfiles-setup.service network-online.target nss-lookup.target
8
9 [Service]
10 LogNamespace=netdata
@@ -15,8 +15,6 @@ RuntimeDirectory=netdata
15 RuntimeDirectoryMode=0775
16 PIDFile=/run/netdata/netdata.pid
17 ExecStart=@sbindir_POST@/netdata -P /run/netdata/netdata.pid -D
18 -ExecStartPre=/bin/mkdir -p @localstatedir_POST@/cache/netdata
19 -ExecStartPre=/bin/chown -R @netdata_user_POST@ @localstatedir_POST@/cache/netdata
18 PermissionsStartOnly=true
19
20 # saving a big db on slow disks may need some time
system/systemd/netdata.service.v235.in
+2 -2
@@ -3,8 +3,8 @@
3 Description=Netdata, X-Ray Vision for your infrastructure!
4
5 # append here other services you want netdata to wait for them to start
6 -After=network.target network-online.target nss-lookup.target
7 -Wants=network-online.target nss-lookup.target
6 +After=systemd-tmpfiles-setup.service network.target network-online.target nss-lookup.target
7 +Wants=systemd-tmpfiles-setup.service network-online.target nss-lookup.target
8
9 [Service]
10 LogNamespace=netdata
system/systemd/tmpfiles.conf.in new
+15
@@ -0,0 +1,15 @@
1 +d /run/netdata 0755 @netdata_user_POST@ @netdata_group_POST@ -
2 +
3 +d @cachedir_POST@ 0755 @netdata_user_POST@ @netdata_group_POST@ -
4 +z @cachedir_POST@/dbengine* 0750 @netdata_user_POST@ @netdata_group_POST@ -
5 +z @cachedir_POST@/dbengine*/* 0600 @netdata_user_POST@ @netdata_group_POST@ -
6 +z @cachedir_POST@/*-meta.db* 0660 @netdata_user_POST@ @netdata_group_POST@ -
7 +
8 +d @varlibdir_POST@ 0770 @netdata_user_POST@ @netdata_group_POST@ -
9 +d @varlibdir_POST@/cloud.d 0770 @netdata_user_POST@ @netdata_group_POST@ -
10 +z @varlibdir_POST@/cloud.d/* 0660 @netdata_user_POST@ @netdata_group_POST@ -
11 +d @varlibdir_POST@/registry 0770 @netdata_user_POST@ @netdata_group_POST@ -
12 +z @varlibdir_POST@/registry/netdata.public.unique.id 0660 @netdata_user_POST@ @netdata_group_POST@ -
13 +z @varlibdir_POST@/netdata.api.key 0660 @netdata_user_POST@ @netdata_group_POST@ -
14 +
15 +d @logdir_POST@ 0755 @netdata_user_POST@ @netdata_group_POST@ -