diff --git a/debian/python3-patchman.install b/debian/python3-patchman.install index e13b11ca..71f47b3a 100755 --- a/debian/python3-patchman.install +++ b/debian/python3-patchman.install @@ -1,4 +1,5 @@ #!/usr/bin/dh-exec etc/patchman/apache.conf.example => etc/apache2/conf-available/patchman.conf etc/patchman/local_settings.py etc/patchman -etc/systemd/system/patchman-celery.service => lib/systemd/system/patchman-celery.service +etc/systemd/system/patchman-celery-worker.service => lib/systemd/system/patchman-celery-worker@.service +etc/systemd/system/patchman-celery-beat.service => lib/systemd/system/patchman-celery-beat.service diff --git a/debian/python3-patchman.postinst b/debian/python3-patchman.postinst index b64cb816..bce66010 100644 --- a/debian/python3-patchman.postinst +++ b/debian/python3-patchman.postinst @@ -25,8 +25,37 @@ if [ "$1" = "configure" ] ; then chown -R www-data:www-data /var/lib/patchman adduser --system --group patchman-celery usermod -a -G www-data patchman-celery + chown root:patchman-celery /etc/patchman/celery.conf + chmod 640 /etc/patchman/celery.conf chmod g+w /var/lib/patchman /var/lib/patchman/db /var/lib/patchman/db/patchman.db + WORKER_COUNT=1 + if [ -f /etc/patchman/celery.conf ]; then + . /etc/patchman/celery.conf + WORKER_COUNT=${CELERY_WORKER_COUNT:-1} + fi + + if [ -d /run/systemd/system ]; then + systemctl daemon-reload >/dev/null || true + for i in $(seq 1 "${WORKER_COUNT}"); do + deb-systemd-helper enable "patchman-celery-worker@$i.service" >/dev/null || true + deb-systemd-invoke start "patchman-celery-worker@$i.service" >/dev/null || true + done + + active_instances=$(systemctl list-units --type=service --state=active "patchman-celery-worker@*" --no-legend | awk '{print $1}') + + for service in $active_instances; do + inst_num=$(echo "$service" | cut -d'@' -f2 | cut -d'.' -f1) + if [ "$inst_num" -gt "${WORKER_COUNT}" ]; then + deb-systemd-invoke stop "$service" >/dev/null || true + deb-systemd-helper disable "$service" >/dev/null || true + fi + done + + deb-systemd-helper enable "patchman-celery-beat.service" >/dev/null || true + deb-systemd-invoke start "patchman-celery-beat.service" >/dev/null || true + fi + echo echo "Remember to run 'patchman-manage createsuperuser' to create a user." echo diff --git a/etc/patchman/celery.conf b/etc/patchman/celery.conf index 7afc96ee..2e6f9855 100644 --- a/etc/patchman/celery.conf +++ b/etc/patchman/celery.conf @@ -1,2 +1,5 @@ REDIS_HOST=127.0.0.1 REDIS_PORT=6379 +CELERY_POOL_TYPE=solo +CELERY_WORKER_COUNT=1 +CELERY_CONCURRENCY=1 diff --git a/etc/systemd/system/patchman-celery-beat.service b/etc/systemd/system/patchman-celery-beat.service new file mode 100644 index 00000000..b4ba9f3d --- /dev/null +++ b/etc/systemd/system/patchman-celery-beat.service @@ -0,0 +1,19 @@ +[Unit] +Description=Patchman Celery Beat Scheduler Service +Requires=network-online.target +After=network-online.target + +[Service] +Type=simple +User=patchman-celery +Group=patchman-celery +EnvironmentFile=/etc/patchman/celery.conf +ExecStart=/usr/bin/celery \ + --broker redis://${REDIS_HOST:-127.0.0.1}:${REDIS_PORT:-6379}/0 \ + --app patchman \ + beat \ + --loglevel info \ + --scheduler django_celery_beat.schedulers:DatabaseScheduler + +[Install] +WantedBy=multi-user.target diff --git a/etc/systemd/system/patchman-celery-worker.service b/etc/systemd/system/patchman-celery-worker.service new file mode 100644 index 00000000..8807cbff --- /dev/null +++ b/etc/systemd/system/patchman-celery-worker.service @@ -0,0 +1,21 @@ +[Unit] +Description=Patchman Celery Worker Service %i +Requires=network-online.target +After=network-online.target + +[Service] +Type=simple +User=patchman-celery +Group=patchman-celery +EnvironmentFile=/etc/patchman/celery.conf +ExecStart=/usr/bin/celery \ + --broker redis://${REDIS_HOST:-127.0.0.1}:${REDIS_PORT:-6379}/0 \ + --app patchman \ + worker \ + --task-events \ + --pool ${CELERY_POOL_TYPE:-solo} \ + --concurrency ${CELERY_CONCURRENCY:-1} \ + --hostname patchman-celery-worker%i@%%h + +[Install] +WantedBy=multi-user.target diff --git a/etc/systemd/system/patchman-celery.service b/etc/systemd/system/patchman-celery.service deleted file mode 100644 index 6408d818..00000000 --- a/etc/systemd/system/patchman-celery.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=Patchman Celery Service -Requires=network-online.target -After=network-onlne.target - -[Service] -Type=simple -User=patchman-celery -Group=patchman-celery -EnvironmentFile=/etc/patchman/celery.conf -ExecStart=/usr/bin/celery --broker redis://${REDIS_HOST}:${REDIS_PORT}/0 --app patchman worker --loglevel info --beat --scheduler django_celery_beat.schedulers:DatabaseScheduler --task-events --pool threads - -[Install] -WantedBy=multi-user.target diff --git a/patchman-client.spec b/patchman-client.spec index 68736038..f2f8279a 100644 --- a/patchman-client.spec +++ b/patchman-client.spec @@ -10,7 +10,7 @@ Source: %{expand:%%(pwd)} BuildArch: noarch Requires: curl which coreutils util-linux gawk -%define binary_payload w9.gzdio +%define _binary_payload w9.gzdio %description patchman-client provides a client that uploads reports to a patchman server @@ -20,14 +20,15 @@ find . -mindepth 1 -delete cp -af %{SOURCEURL0}/. . %install -mkdir -p %{buildroot}/usr/sbin -mkdir -p %{buildroot}/etc/patchman -cp ./client/%{name} %{buildroot}/usr/sbin -cp ./client/%{name}.conf %{buildroot}/etc/patchman +mkdir -p %{buildroot}%{_sbindir} +mkdir -p %{buildroot}%{_sysconfdir}/patchman +install -m 755 client/%{name} %{buildroot}%{_sbindir}/%{name} +install -m 644 client/%{name}.conf %{buildroot}%{_sysconfdir}/patchman/%{name}.conf %files -%defattr(755,root,root) -/usr/sbin/patchman-client -%config(noreplace) /etc/patchman/patchman-client.conf +%defattr(-,root,root) +%{_sbindir}/patchman-client +%dir %{_sysconfdir}/patchman +%config(noreplace) %{_sysconfdir}/patchman/patchman-client.conf %changelog diff --git a/scripts/rpm-post-install.sh b/scripts/rpm-post-install.sh index 24ade8af..798c43ea 100644 --- a/scripts/rpm-post-install.sh +++ b/scripts/rpm-post-install.sh @@ -4,8 +4,9 @@ if [ ! -e /etc/httpd/conf.d/patchman.conf ] ; then cp /etc/patchman/apache.conf.example /etc/httpd/conf.d/patchman.conf fi -if ! grep /usr/lib/python3.9/site-packages /etc/httpd/conf.d/patchman.conf >/dev/null 2>&1 ; then - sed -i -e "s/^\(Define patchman_pythonpath\).*/\1 \/usr\/lib\/python3.9\/site-packages/" \ +PYTHON_SITEPACKAGES=$(python3 -c "import site; print(site.getsitepackages()[0])") +if ! grep "${PYTHON_SITEPACKAGES}" /etc/httpd/conf.d/patchman.conf >/dev/null 2>&1 ; then + sed -i -e "s|^\(Define patchman_pythonpath\).*|\1 ${PYTHON_SITEPACKAGES}|" \ /etc/httpd/conf.d/patchman.conf fi @@ -24,15 +25,38 @@ patchman-manage makemigrations patchman-manage migrate --run-syncdb --fake-initial sqlite3 /var/lib/patchman/db/patchman.db 'PRAGMA journal_mode=WAL;' -chown -R apache:apache /var/lib/patchman adduser --system --group patchman-celery usermod -a -G apache patchman-celery -chmod g+w /var/lib/patchman /var/lib/patchman/db /var/lib/patchman/db/patchman.db -chcon --type httpd_sys_rw_content_t /var/lib/patchman/db/patchman.db -semanage port -a -t http_port_t -p tcp 5672 +chown root:patchman-celery /etc/patchman/celery.conf +chmod 640 /etc/patchman/celery.conf + +chown -R apache:apache /var/lib/patchman +semanage fcontext -a -t httpd_sys_rw_content_t "/var/lib/patchman/db(/.*)?" +restorecon -Rv /var/lib/patchman/db setsebool -P httpd_can_network_memcache 1 setsebool -P httpd_can_network_connect 1 +WORKER_COUNT=1 +if [ -f /etc/patchman/celery.conf ]; then + . /etc/patchman/celery.conf + WORKER_COUNT=${CELERY_WORKER_COUNT:-1} +fi + +for i in $(seq 1 "${WORKER_COUNT}"); do + systemctl enable --now "patchman-celery-worker@$i.service" +done + +active_instances=$(systemctl list-units --type=service --state=active "patchman-celery-worker@*" --no-legend | awk '{print $1}') +for service in $active_instances; do + inst_num=$(echo "$service" | cut -d'@' -f2 | cut -d'.' -f1) + if [ "$inst_num" -gt "${WORKER_COUNT}" ]; then + systemctl stop "$service" + systemctl disable "$service" + fi +done + +systemctl enable --now patchman-celery-beat.service + echo echo "Remember to run 'patchman-manage createsuperuser' to create a user." echo diff --git a/setup.py b/setup.py index 8e18eaf9..a7dbfc68 100755 --- a/setup.py +++ b/setup.py @@ -17,6 +17,7 @@ # along with Patchman. If not, see import os +import sys from setuptools import find_packages, setup @@ -29,8 +30,14 @@ with open('requirements.txt', 'r', encoding='utf_8') as rt: install_requires = rt.read().splitlines() - data_files = [] +if 'bdist_rpm' in sys.argv: + data_files.append( + ('/usr/lib/systemd/system', [ + 'etc/systemd/system/patchman-celery-worker@.service', + 'etc/systemd/system/patchman-celery-beat.service' + ]) + ) for dirpath, dirnames, filenames in os.walk('etc'): # Ignore dirnames that start with '.'