diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f40663b7..e9a0844a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -16,11 +16,14 @@ Changed - redis v8.6 Contributed by @nzlosh + * Added systemd generators for st2auth, st2api, st2stream service unit files. + Contributed by @nzlosh #762 + Removed ~~~~~~~ * Removed focal and rocky8 - Contributed by @nzlosh + Contributed by @nzlosh + @skiedude #761 v3.9 diff --git a/packages/st2/debian/rules b/packages/st2/debian/rules index 13466738..96c2f517 100755 --- a/packages/st2/debian/rules +++ b/packages/st2/debian/rules @@ -40,9 +40,6 @@ override_dh_gencontrol: override_dh_installinit: dh_systemd_enable --name=st2actionrunner st2actionrunner.service install -Dp -m644 debian/st2actionrunner@.service debian/st2/lib/systemd/system/st2actionrunner@.service - dh_systemd_enable --name=st2api st2api.service - dh_systemd_enable --name=st2stream st2stream.service - dh_systemd_enable --name=st2auth st2auth.service dh_systemd_enable --name=st2notifier st2notifier.service dh_systemd_enable --name=st2rulesengine st2rulesengine.service dh_systemd_enable --name=st2sensorcontainer st2sensorcontainer.service diff --git a/packages/st2/debian/st2api-generator b/packages/st2/debian/st2api-generator index ae6d2e7e..cdff9af0 100755 --- a/packages/st2/debian/st2api-generator +++ b/packages/st2/debian/st2api-generator @@ -4,6 +4,9 @@ import logging import time import sys +ISO8601 = "%Y-%m-%dT%H:%M:%S%z" +EXEC_TIME = time.localtime() + ST2SVC = "st2api" DEFAULT_IP = "127.0.0.1" DEFAULT_PORT = "9101" @@ -37,8 +40,33 @@ section = ST2SVC[3:] bind_address = config[section].get("host", DEFAULT_IP) bind_port = config[section].get("port", DEFAULT_PORT) -contents = f"""[Unit] -# Generated by {sys.argv[0]} at {time.asctime(time.localtime())} +# Default to gevent if the configuration is unset as this will be the correct option from v3.10+. +concurrency_library = config["system"].get("concurrency_library", "gevent") + +service_contents = f"""[Unit] +# Generated by {sys.argv[0]} at {time.strftime(ISO8601, EXEC_TIME)} +Description=StackStorm service st2api +After=network.target st2api.socket +Requires=st2api.socket + +[Service] +Type=simple +User=st2 +Group=st2 +Environment="DAEMON_ARGS=-k {concurrency_library} -b {bind_address}:{bind_port} --workers 1 --threads 1 --graceful-timeout 10 --timeout 30 --log-config /etc/st2/logging.api.gunicorn.conf --error-logfile /var/log/st2/st2api.log" +EnvironmentFile=-/etc/default/st2api +ExecStart=/opt/stackstorm/st2/bin/gunicorn st2api.wsgi:application $DAEMON_ARGS +TimeoutSec=60 +PrivateTmp=true +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +""" + +socket_contents = f"""[Unit] +# Generated by {sys.argv[0]} at {time.strftime(ISO8601, EXEC_TIME)} Description=StackStorm {ST2SVC} Socket. PartOf={ST2SVC}.service SourcePath={ST2CFG} @@ -50,7 +78,8 @@ ListenStream={bind_address}:{bind_port} WantedBy=sockets.target """ -with open(f"{NORMAL_DIR}/{ST2SVC}.socket", "w") as f: - f.write(contents) +for ext, contents in (("socket", socket_contents), ("service", service_contents)): + with open(f"{NORMAL_DIR}/{ST2SVC}.{ext}", "w") as f: + f.write(contents) LOG.info(f"{ST2SVC} generated.") diff --git a/packages/st2/debian/st2api.service b/packages/st2/debian/st2api.service deleted file mode 100644 index 1921126d..00000000 --- a/packages/st2/debian/st2api.service +++ /dev/null @@ -1,19 +0,0 @@ -[Unit] -Description=StackStorm service st2api -After=network.target st2api.socket -Requires=st2api.socket - -[Service] -Type=simple -User=st2 -Group=st2 -Environment="DAEMON_ARGS=-k eventlet -b 127.0.0.1:9101 --workers 1 --threads 1 --graceful-timeout 10 --timeout 30 --log-config /etc/st2/logging.api.gunicorn.conf --error-logfile /var/log/st2/st2api.log" -EnvironmentFile=-/etc/default/st2api -ExecStart=/opt/stackstorm/st2/bin/gunicorn st2api.wsgi:application $DAEMON_ARGS -TimeoutSec=60 -PrivateTmp=true -Restart=on-failure -RestartSec=5 - -[Install] -WantedBy=multi-user.target diff --git a/packages/st2/debian/st2auth-generator b/packages/st2/debian/st2auth-generator index f1b017e9..689a1410 100755 --- a/packages/st2/debian/st2auth-generator +++ b/packages/st2/debian/st2auth-generator @@ -4,6 +4,9 @@ import logging import time import sys +ISO8601 = "%Y-%m-%dT%H:%M:%S%z" +EXEC_TIME = time.localtime() + ST2SVC="st2auth" DEFAULT_IP="127.0.0.1" DEFAULT_PORT="9100" @@ -37,8 +40,11 @@ section = ST2SVC[3:] bind_address = config[section].get("host", DEFAULT_IP) bind_port = config[section].get("port", DEFAULT_PORT) -contents = f"""[Unit] -# Generated by {sys.argv[0]} at {time.asctime(time.localtime())} +# Default to gevent if the configuration is unset as this will be the correct option from v3.10+. +concurrency_library = config["system"].get("concurrency_library", "gevent") + +socket_contents = f"""[Unit] +# Generated by {sys.argv[0]} at {time.strftime(ISO8601, EXEC_TIME)} Description=StackStorm {ST2SVC} Socket. PartOf={ST2SVC}.service SourcePath={ST2CFG} @@ -50,7 +56,30 @@ ListenStream={bind_address}:{bind_port} WantedBy=sockets.target """ -with open(f"{NORMAL_DIR}/{ST2SVC}.socket", "w") as f: - f.write(contents) +service_contents = f"""[Unit] +# Generated by {sys.argv[0]} at {time.strftime(ISO8601, EXEC_TIME)} +Description=StackStorm service st2auth +After=network.target st2auth.socket +Requires=st2auth.socket + +[Service] +Type=simple +User=st2 +Group=st2 +Environment="DAEMON_ARGS=-k {concurrency_library} -b {bind_address}:{bind_port} --workers 1 --threads 1 --graceful-timeout 10 --timeout 30 --log-config /etc/st2/logging.auth.gunicorn.conf --error-logfile /var/log/st2/st2auth.log" +EnvironmentFile=-/etc/default/st2auth +ExecStart=/opt/stackstorm/st2/bin/gunicorn st2auth.wsgi:application $DAEMON_ARGS +TimeoutSec=60 +PrivateTmp=true +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +""" + +for ext, contents in (("socket", socket_contents), ("service", service_contents)): + with open(f"{NORMAL_DIR}/{ST2SVC}.{ext}", "w") as f: + f.write(contents) LOG.info(f"{ST2SVC} generated.") diff --git a/packages/st2/debian/st2auth.service b/packages/st2/debian/st2auth.service deleted file mode 100644 index 54420192..00000000 --- a/packages/st2/debian/st2auth.service +++ /dev/null @@ -1,19 +0,0 @@ -[Unit] -Description=StackStorm service st2auth -After=network.target st2auth.socket -Requires=st2auth.socket - -[Service] -Type=simple -User=st2 -Group=st2 -Environment="DAEMON_ARGS=-k eventlet -b 127.0.0.1:9100 --workers 1 --threads 1 --graceful-timeout 10 --timeout 30 --log-config /etc/st2/logging.auth.gunicorn.conf --error-logfile /var/log/st2/st2auth.log" -EnvironmentFile=-/etc/default/st2auth -ExecStart=/opt/stackstorm/st2/bin/gunicorn st2auth.wsgi:application $DAEMON_ARGS -TimeoutSec=60 -PrivateTmp=true -Restart=on-failure -RestartSec=5 - -[Install] -WantedBy=multi-user.target diff --git a/packages/st2/debian/st2stream-generator b/packages/st2/debian/st2stream-generator index e7d82e0f..eb3ead10 100755 --- a/packages/st2/debian/st2stream-generator +++ b/packages/st2/debian/st2stream-generator @@ -4,6 +4,9 @@ import logging import time import sys +ISO8601 = "%Y-%m-%dT%H:%M:%S%z" +EXEC_TIME = time.localtime() + ST2SVC="st2stream" DEFAULT_IP="127.0.0.1" DEFAULT_PORT="9102" @@ -37,8 +40,32 @@ section = ST2SVC[3:] bind_address = config[section].get("host", DEFAULT_IP) bind_port = config[section].get("port", DEFAULT_PORT) -contents = f"""[Unit] -# Generated by {sys.argv[0]} at {time.asctime(time.localtime())} +concurrency_library = config["system"].get("concurrency_library", "gevent") + +service_contents = f"""[Unit] +# Generated by {sys.argv[0]} at {time.strftime(ISO8601, EXEC_TIME)} +Description=StackStorm service st2stream +After=network.target st2stream.socket +Requires=st2stream.socket + +[Service] +Type=simple +User=st2 +Group=st2 +Environment="DAEMON_ARGS=-k {concurrency_library} -b {bind_address}:{bind_port} --workers 1 --threads 10 --graceful-timeout 10 --timeout 30 --log-config /etc/st2/logging.stream.gunicorn.conf --error-logfile /var/log/st2/st2stream.log" +EnvironmentFile=-/etc/default/st2stream +ExecStart=/opt/stackstorm/st2/bin/gunicorn st2stream.wsgi:application $DAEMON_ARGS +TimeoutSec=60 +PrivateTmp=true +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +""" + +socket_contents = f"""[Unit] +# Generated by {sys.argv[0]} at {time.strftime(ISO8601, EXEC_TIME)} Description=StackStorm {ST2SVC} Socket. PartOf={ST2SVC}.service SourcePath={ST2CFG} @@ -50,7 +77,8 @@ ListenStream={bind_address}:{bind_port} WantedBy=sockets.target """ -with open(f"{NORMAL_DIR}/{ST2SVC}.socket", "w") as f: - f.write(contents) +for ext, contents in (("socket", socket_contents), ("service", service_contents)): + with open(f"{NORMAL_DIR}/{ST2SVC}.{ext}", "w") as f: + f.write(contents) LOG.info(f"{ST2SVC} generated.") diff --git a/packages/st2/debian/st2stream.service b/packages/st2/debian/st2stream.service deleted file mode 100644 index ade3ba5d..00000000 --- a/packages/st2/debian/st2stream.service +++ /dev/null @@ -1,19 +0,0 @@ -[Unit] -Description=StackStorm service st2stream -After=network.target st2stream.socket -Requires=st2stream.socket - -[Service] -Type=simple -User=st2 -Group=st2 -Environment="DAEMON_ARGS=-k eventlet -b 127.0.0.1:9102 --workers 1 --threads 10 --graceful-timeout 10 --timeout 30 --log-config /etc/st2/logging.stream.gunicorn.conf --error-logfile /var/log/st2/st2stream.log" -EnvironmentFile=-/etc/default/st2stream -ExecStart=/opt/stackstorm/st2/bin/gunicorn st2stream.wsgi:application $DAEMON_ARGS -TimeoutSec=60 -PrivateTmp=true -Restart=on-failure -RestartSec=5 - -[Install] -WantedBy=multi-user.target diff --git a/packages/st2/rpm/st2.spec b/packages/st2/rpm/st2.spec index c8dd028c..406da882 100644 --- a/packages/st2/rpm/st2.spec +++ b/packages/st2/rpm/st2.spec @@ -84,7 +84,8 @@ Conflicts: st2common %include rpm/preinst_script.spec %post - %service_post st2actionrunner st2api st2stream st2auth st2notifier st2workflowengine + %service_post st2api st2stream st2auth + %service_post st2actionrunner st2notifier st2workflowengine %service_post st2rulesengine st2timersengine st2sensorcontainer st2garbagecollector %service_post st2scheduler %include rpm/postinst_script.spec @@ -122,9 +123,6 @@ Conflicts: st2common %attr(775, root, %{packs_group}) /opt/stackstorm/virtualenvs %{_unitdir}/st2actionrunner.service %{_unitdir}/%{worker_name}.service - %{_unitdir}/st2api.service - %{_unitdir}/st2stream.service - %{_unitdir}/st2auth.service %{_unitdir}/st2notifier.service %{_unitdir}/st2rulesengine.service %{_unitdir}/st2sensorcontainer.service diff --git a/packages/st2/rpm/st2api.service b/packages/st2/rpm/st2api.service deleted file mode 100644 index 1b59b9b9..00000000 --- a/packages/st2/rpm/st2api.service +++ /dev/null @@ -1,19 +0,0 @@ -[Unit] -Description=StackStorm service st2api -After=network.target st2api.socket -Requires=st2api.socket - -[Service] -Type=simple -User=st2 -Group=st2 -Environment="DAEMON_ARGS=-k eventlet -b 127.0.0.1:9101 --workers 1 --threads 1 --graceful-timeout 10 --timeout 30 --log-config /etc/st2/logging.api.gunicorn.conf --error-logfile /var/log/st2/st2api.log" -EnvironmentFile=-/etc/sysconfig/st2api -ExecStart=/opt/stackstorm/st2/bin/gunicorn st2api.wsgi:application $DAEMON_ARGS -TimeoutSec=60 -PrivateTmp=true -Restart=on-failure -RestartSec=5 - -[Install] -WantedBy=multi-user.target diff --git a/packages/st2/rpm/st2auth.service b/packages/st2/rpm/st2auth.service deleted file mode 100644 index 260a7853..00000000 --- a/packages/st2/rpm/st2auth.service +++ /dev/null @@ -1,19 +0,0 @@ -[Unit] -Description=StackStorm service st2auth -After=network.target st2auth.socket -Requires=st2auth.socket - -[Service] -Type=simple -User=st2 -Group=st2 -Environment="DAEMON_ARGS=-k eventlet -b 127.0.0.1:9100 --workers 1 --threads 1 --graceful-timeout 10 --timeout 30 --log-config /etc/st2/logging.auth.gunicorn.conf --error-logfile /var/log/st2/st2auth.log" -EnvironmentFile=-/etc/sysconfig/st2auth -ExecStart=/opt/stackstorm/st2/bin/gunicorn st2auth.wsgi:application $DAEMON_ARGS -TimeoutSec=60 -PrivateTmp=true -Restart=on-failure -RestartSec=5 - -[Install] -WantedBy=multi-user.target diff --git a/packages/st2/rpm/st2stream.service b/packages/st2/rpm/st2stream.service deleted file mode 100644 index 742cc203..00000000 --- a/packages/st2/rpm/st2stream.service +++ /dev/null @@ -1,19 +0,0 @@ -[Unit] -Description=StackStorm service st2stream -After=network.target st2stream.socket -Requires=st2stream.socket - -[Service] -Type=simple -User=st2 -Group=st2 -Environment="DAEMON_ARGS=-k eventlet -b 127.0.0.1:9102 --workers 1 --threads 10 --graceful-timeout 10 --timeout 30 --log-config /etc/st2/logging.stream.gunicorn.conf --error-logfile /var/log/st2/st2stream.log" -EnvironmentFile=-/etc/sysconfig/st2stream -ExecStart=/opt/stackstorm/st2/bin/gunicorn st2stream.wsgi:application $DAEMON_ARGS -TimeoutSec=60 -PrivateTmp=true -Restart=on-failure -RestartSec=5 - -[Install] -WantedBy=multi-user.target diff --git a/rpmspec/helpers.spec b/rpmspec/helpers.spec index 767bed69..ed426d10 100644 --- a/rpmspec/helpers.spec +++ b/rpmspec/helpers.spec @@ -2,35 +2,37 @@ # - package # Cat debian/package.dirs, set buildroot prefix and create directories. -%define debian_dirs cat debian/%{name}.dirs | grep -v '^\\s*#' | sed 's~^~%{buildroot}/~' | \ - while read dir_path; do \ - mkdir -p "${dir_path}" \ - done \ +%define debian_dirs \ + grep -v '^\\s*#' debian/%{name}.dirs | sed 's~^~%{buildroot}/~' | \ + while read dir_path; do \ + mkdir -p "${dir_path}" \ + done \ %{nil} # Cat debian/package.links, set buildroot prefix and create symlinks. -%define debian_links cat debian/%{name}.links | grep -v '^\\s*#' | \ - sed -r -e 's~\\b~/~' -e 's~\\s+\\b~ %{buildroot}/~' | \ - while read link_rule; do \ - linkpath=$(echo "$link_rule" | cut -f2 -d' ') && [ -d $(dirname "$linkpath") ] || \ - mkdir -p $(dirname "$linkpath") && ln -s $link_rule \ - done \ +%define debian_links \ + grep -v '^\\s*#' debian/%{name}.links | sed -r -e 's~\\b~/~' -e 's~\\s+\\b~ %{buildroot}/~' | \ + while read link_rule; do \ + linkpath=$(echo "$link_rule" | cut -f2 -d' ') && [ -d $(dirname "$linkpath") ] || \ + mkdir -p $(dirname "$linkpath") && ln -s $link_rule \ + done \ %{nil} # Cat debian/install, set buildroot prefix and copy files. -%define debian_install cat debian/install | grep -v '^\s*#' | sed -r -e 's~ lib/systemd~ usr/lib/systemd~' -e 's~ +~ %{buildroot}/~' | \ - while read copy_rule; do \ - parent=$(echo "$copy_rule" | cut -f2 -d' ') \ - [ -d "$parent" ] || install -d "$parent" && cp -r $copy_rule \ - done \ +%define debian_install \ + grep -v '^\s*#' debian/install | sed -r -e 's~ lib/systemd~ usr/lib/systemd~' -e 's~ +~ %{buildroot}/~' | \ + while read copy_rule; do \ + parent=$(echo "$copy_rule" | cut -f2 -d' ') \ + [ -d "$parent" ] || install -d "$parent" && cp -r $copy_rule \ + done \ %{nil} -# We hate duplication right :)?, so let's use debian files # 2026 FIX: Nothing justifies crossing platform build tools metadata! +# We hate duplication right :)?, so let's use debian files. TODO: Stop using debian metafiles. %define default_install \ - %debian_dirs \ - %debian_install \ - %debian_links \ - %make_install \ + %debian_dirs \ + %debian_install \ + %debian_links \ + %make_install \ %{nil} # Find a supported version of Python. @@ -39,28 +41,28 @@ ## Clean up RECORD and some other files left by python, which may contain # absolute buildroot paths. %define cleanup_python_abspath \ - find %{buildroot} -name RECORD -o -name '*.egg-link' -o -name '*.pth' -o -name 'pyvenv.cfg' | \ - xargs -I{} -n1 sed -i 's@%{buildroot}@@' {} \ + find %{buildroot} -name RECORD -o -name '*.egg-link' -o -name '*.pth' -o -name 'pyvenv.cfg' | \ + xargs -I{} -n1 sed -i 's@%{buildroot}@@' {} \ %{nil} #Cleanup .so files that contain buildroot %define cleanup_so_abspath \ - for f in `find %{venv_dir}/lib -type f -name "*.so" | \ - xargs grep -l %{buildroot} `; do strip $f; done \ + for f in `find %{venv_dir}/lib -type f -name "*.so" | \ + xargs grep -l %{buildroot} `; do strip $f; done \ %{nil} # Define use_systemd to know if we on a systemd system # %if 0%{?_unitdir:1} - %define use_systemd 1 + %define use_systemd 1 %endif ## St2 package version parsing # if package name starts with st2 then it's st2 component. # %if %(PKG=%{package}; [ "${PKG##st2}" != "$PKG" ] && echo 1 || echo 0 ) == 1 -%define st2pkg_version %(%{pyexecutable} -c "from %{package} import __version__; print(__version__),") -# st2 package version parsing + # st2 package version parsing + %define st2pkg_version %(%{pyexecutable} -c "from %{package} import __version__; print(__version__),") %endif # Redefine and to drop python brp bytecompile @@ -73,31 +75,30 @@ %{nil} # Install systemd service into the package -# %define service_install() \ - for svc in %{?*}; do \ - install -D -p -m0644 %{SOURCE0}/rpm/$svc.service %{buildroot}%{_unitdir}/$svc.service \ - [ -f %{SOURCE0}/rpm/$svc.socket ] && install -D -p -m0644 %{SOURCE0}/rpm/$svc.socket %{buildroot}%{_unitdir}/$svc.socket \ - done \ + for svc in %{?*}; do \ + test -f %{SOURCE0}/rpm/$svc.service && install -D -p -m0644 %{SOURCE0}/rpm/$svc.service %{buildroot}%{_unitdir}/$svc.service \ + test -f %{SOURCE0}/rpm/$svc.socket && install -D -p -m0644 %{SOURCE0}/rpm/$svc.socket %{buildroot}%{_unitdir}/$svc.socket \ + done \ %{nil} # Service post stage action # enables used to enforce the policy, which seems to be disabled by default -# +# systemctl --no-reload enable %{?*} >/dev/null 2>&1 || : \ %define service_post() \ - %{expand: %systemd_post %%{?*}} \ - systemctl --no-reload enable %{?*} >/dev/null 2>&1 || : \ + %{expand: %systemd_post %%{?*}} \ + systemctl --no-reload enable %{?*} \ %{nil} # Service preun stage action # %define service_preun() \ - %{expand: %systemd_preun %%{?*}} \ + %{expand: %systemd_preun %%{?*}} \ %{nil} # Service postun stage action # ($1 > 1 on package upgrade) # %define service_postun() \ - %{expand: %systemd_postun_with_restart %%{?*}} \ + %{expand: %systemd_postun_with_restart %%{?*}} \ %{nil}