[plague] Some fixes for systemd compatibility, e.g. patch daemonize.py double-fork to let parent die only aft
Michael Schwendt
mschwendt at fedoraproject.org
Tue Nov 8 23:57:52 UTC 2011
commit b2cf34e0eca1faae1579f65543019efd91d5b0b7
Author: Michael Schwendt <mschwendt at fedoraproject.org>
Date: Wed Nov 9 00:57:44 2011 +0100
Some fixes for systemd compatibility, e.g. patch daemonize.py double-fork
to let parent die only after second child has written PID file.
Add systemd unit files and related package scriptlets.
plague-0.4.5.8-systemd-compat.patch | 126 +++++++++++++++++++++++++++++++++++
plague-builder.service | 11 +++
plague-server.service | 11 +++
plague.spec | 88 +++++++++++++++++++++---
4 files changed, 225 insertions(+), 11 deletions(-)
---
diff --git a/plague-0.4.5.8-systemd-compat.patch b/plague-0.4.5.8-systemd-compat.patch
new file mode 100644
index 0000000..08555bf
--- /dev/null
+++ b/plague-0.4.5.8-systemd-compat.patch
@@ -0,0 +1,126 @@
+diff -Nur plague-0.4.5.8-orig/builder/builder.py plague-0.4.5.8/builder/builder.py
+--- plague-0.4.5.8-orig/builder/builder.py 2010-05-05 12:45:20.000000000 +0200
++++ plague-0.4.5.8/builder/builder.py 2011-11-09 00:45:33.011902281 +0100
+@@ -838,18 +838,15 @@
+ log("No useable mock buildroots configured. Exiting...\n")
+ sys.exit(1)
+
++ if opts.pidfile and os.path.exists(opts.pidfile):
++ os.unlink(opts.pidfile)
++
+ if opts.daemon:
+- ret=daemonize.createDaemon()
++ ret=daemonize.createDaemon(opts.pidfile)
+ if ret:
+ log("Daemonizing failed!\n")
+ sys.exit(2)
+
+- if opts.pidfile:
+- f = open(opts.pidfile, 'w', 1)
+- f.write('%d\n' % os.getpid())
+- f.flush()
+- f.close()
+-
+ if opts.logfile:
+ logf=open(opts.logfile, 'a')
+ sys.stdout=logf
+@@ -921,7 +918,7 @@
+ break
+ log(" done.\n");
+ sys.stdout.flush()
+- time.sleep(2)
++
+ os._exit(0)
+
+
+diff -Nur plague-0.4.5.8-orig/common/daemonize.py plague-0.4.5.8/common/daemonize.py
+--- plague-0.4.5.8-orig/common/daemonize.py 2008-01-31 14:48:41.000000000 +0100
++++ plague-0.4.5.8/common/daemonize.py 2011-11-09 00:46:31.708713648 +0100
+@@ -22,12 +22,22 @@
+ import os # Miscellaneous OS interfaces.
+ import sys # System-specific parameters and functions.
+ import signal # Set handlers for asynchronous events.
++import time
+
+-def createDaemon():
++parentcanexit = False
++
++def grandparenthandler(signum, frame):
++ if signum == signal.SIGUSR1:
++ global parentcanexit
++ parentcanexit = True
++
++def createDaemon(pidfile):
+ """Detach a process from the controlling terminal and run it in the
+ background as a daemon.
+ """
+
++ signal.signal(signal.SIGUSR1, grandparenthandler)
++
+ try:
+ # Fork a child process so the parent can exit. This will return control
+ # to the command line or shell. This is required so that the new process
+@@ -41,6 +51,8 @@
+
+ if (pid == 0): # The first child.
+
++ ppid = os.getppid()
++
+ # Next we call os.setsid() to become the session leader of this new
+ # session. The process also becomes the process group leader of the
+ # new process group. Since a controlling terminal is associated with a
+@@ -70,9 +82,20 @@
+ os.chdir("/")
+ # Give the child complete control over permissions.
+ os.umask(0002)
++
++ if pidfile:
++ f = open(pidfile, 'w', 1)
++ f.write('%d\n' % os.getpid())
++ f.flush()
++ f.close()
++
++ os.kill(ppid,signal.SIGUSR1)
+ else:
+ os._exit(0) # Exit parent (the first child) of the second child.
+ else:
++ global parentcanexit
++ while not parentcanexit:
++ time.sleep(0.01)
+ os._exit(0) # Exit parent of the first child.
+
+ # Close all open files. Try the system configuration variable, SC_OPEN_MAX,
+diff -Nur plague-0.4.5.8-orig/server/main.py plague-0.4.5.8/server/main.py
+--- plague-0.4.5.8-orig/server/main.py 2008-01-31 14:28:05.000000000 +0100
++++ plague-0.4.5.8/server/main.py 2011-11-09 00:46:24.729092809 +0100
+@@ -87,15 +87,15 @@
+ print "Must specify a config file."
+ sys.exit(1)
+
++ if opts.pidfile and os.path.exists(opts.pidfile):
++ os.unlink(opts.pidfile)
++
+ if opts.daemon:
+- ret=daemonize.createDaemon()
++ ret=daemonize.createDaemon(opts.pidfile)
+ if ret:
+ print "Daemonizing failed!"
+ sys.exit(2)
+
+- if opts.pidfile:
+- open(opts.pidfile, 'w').write('%d\n' % os.getpid())
+-
+ if opts.logfile:
+ # 1 == line buffer the log file
+ log=open(opts.logfile, 'a', 1)
+@@ -186,10 +186,6 @@
+ if use_tbs:
+ tbs.stop()
+
+- if opts.pidfile:
+- os.unlink(opts.pidfile)
+-
+- time.sleep(2)
+ print "Done."
+ os._exit(0)
+
diff --git a/plague-builder.service b/plague-builder.service
new file mode 100644
index 0000000..6a766bb
--- /dev/null
+++ b/plague-builder.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Plague builder daemon for build-system slave machines
+After=syslog.target network.target
+
+[Service]
+Type=forking
+EnvironmentFile=/etc/sysconfig/plague-builder
+ExecStart=/usr/bin/plague-builder -d -c ${CONFIG} -p ${PIDFILE} $OPTIONS
+
+[Install]
+WantedBy=multiuser.target
diff --git a/plague-server.service b/plague-server.service
new file mode 100644
index 0000000..9aafd07
--- /dev/null
+++ b/plague-server.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Plague server daemon for build-system master machines
+After=syslog.target network.target
+
+[Service]
+Type=forking
+EnvironmentFile=/etc/sysconfig/plague-server
+ExecStart=/usr/bin/plague-server -d -c ${CONFIG} -p ${PIDFILE} $OPTIONS
+
+[Install]
+WantedBy=multiuser.target
diff --git a/plague.spec b/plague.spec
index 0184090..bd40319 100644
--- a/plague.spec
+++ b/plague.spec
@@ -3,14 +3,22 @@ BuildArch: noarch
Summary: Distributed build system for RPMs
Name: plague
Version: 0.4.5.8
-Release: 2%{?dist}
+Release: 3%{?dist}
License: GPLv2+
Group: Development/Tools
#Source: http://fedoraproject.org/projects/plague/releases/%{name}-%{version}.tar.bz2
Source: http://mschwendt.fedorapeople.org/plague/%{name}-%{version}.tar.bz2
+Source1: plague-builder.service
+Source2: plague-server.service
URL: http://www.fedoraproject.org/wiki/Projects/Plague
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+
+# some fixes for systemd compatibility - it doesn't like double-fork daemons,
+# where the parent process exits before the main PID is known
+Patch0: plague-0.4.5.8-systemd-compat.patch
+
BuildRequires: python
+BuildRequires: systemd-units
Requires: createrepo >= 0.4.7
# get the version of the sqlite api thats available to us
%if 0%{?rhel}
@@ -20,10 +28,13 @@ Requires: python-sqlite2
%endif
Requires: %{name}-common = %{version}-%{release}
-Requires(post): /sbin/chkconfig
-Requires(post): /sbin/service
-Requires(preun): /sbin/chkconfig
-Requires(preun): /sbin/service
+Requires(post): systemd-units
+Requires(preun): systemd-units
+Requires(postun): systemd-units
+# This is actually needed for the %triggerun script but Requires(triggerun)
+# is not valid. We can use %post because this particular %triggerun script
+# should fire just after this package is installed.
+Requires(post): systemd-sysv
%description
@@ -79,6 +90,7 @@ the interface to the build server.
%prep
%setup -q
+%patch0 -p1 -b .systemd-compat
%build
@@ -88,6 +100,9 @@ make
%install
rm -rf $RPM_BUILD_ROOT
make DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p" install
+mkdir -p $RPM_BUILD_ROOT%{_unitdir}
+install -p -m 0644 %{SOURCE1} $RPM_BUILD_ROOT%{_unitdir}
+install -p -m 0644 %{SOURCE2} $RPM_BUILD_ROOT%{_unitdir}
chmod +x $RPM_BUILD_ROOT%{_bindir}/*
install -p -D -m 0644 etc/plague-builder.config $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/%{name}-builder
install -p -D -m 0755 etc/plague-builder.init $RPM_BUILD_ROOT%{_initrddir}/%{name}-builder
@@ -105,11 +120,33 @@ rm -rf $RPM_BUILD_ROOT
/sbin/service plague-server condrestart >> /dev/null || :
%preun
-if [ $1 = 0 ]; then
- /sbin/service plague-server stop &> /dev/null
- /sbin/chkconfig --del plague-server
+if [ $1 -eq 0 ] ; then
+ # Package removal, not upgrade
+ /bin/systemctl --no-reload disable plague-server.service > /dev/null 2>&1 || :
+ /bin/systemctl stop plague-server.service > /dev/null 2>&1 || :
+fi
+
+%postun
+/bin/systemctl daemon-reload >/dev/null 2>&1 || :
+if [ $1 -ge 1 ] ; then
+ # Package upgrade, not uninstall
+ /bin/systemctl try-restart plague-server.service >/dev/null 2>&1 || :
fi
+%triggerun -- plague < 0.4.5.8-3
+# Save the current service runlevel info
+# User must manually run systemd-sysv-convert --apply plague-server
+# to migrate them to systemd targets
+/usr/bin/systemd-sysv-convert --save plague-server >/dev/null 2>&1 ||:
+
+# If the package is allowed to autostart:
+/bin/systemctl --no-reload enable plague-server.service >/dev/null 2>&1 ||:
+
+# Run these because the SysV package being removed won't do them
+/sbin/chkconfig --del plague-server >/dev/null 2>&1 || :
+/bin/systemctl try-restart plague-server.service >/dev/null 2>&1 || :
+
+
%pre builder
/usr/sbin/useradd -G mock -s /sbin/nologin -M -r -d /var/lib/plague/builder plague-builder 2>/dev/null || :
@@ -118,11 +155,33 @@ fi
/sbin/service plague-builder condrestart >> /dev/null || :
%preun builder
-if [ $1 = 0 ]; then
- /sbin/service plague-builder stop &> /dev/null
- /sbin/chkconfig --del plague-builder
+if [ $1 -eq 0 ] ; then
+ # Package removal, not upgrade
+ /bin/systemctl --no-reload disable plague-builder.service > /dev/null 2>&1 || :
+ /bin/systemctl stop plague-builder.service > /dev/null 2>&1 || :
fi
+%postun builder
+/bin/systemctl daemon-reload >/dev/null 2>&1 || :
+if [ $1 -ge 1 ] ; then
+ # Package upgrade, not uninstall
+ /bin/systemctl try-restart plague-builder.service >/dev/null 2>&1 || :
+fi
+
+%triggerun builder -- plague-builder < 0.4.5.8-3
+# Save the current service runlevel info
+# User must manually run systemd-sysv-convert --apply plague-builder
+# to migrate them to systemd targets
+/usr/bin/systemd-sysv-convert --save plague-builder >/dev/null 2>&1 ||:
+
+# If the package is allowed to autostart:
+/bin/systemctl --no-reload enable plague-builder.service >/dev/null 2>&1 ||:
+
+# Run these because the SysV package being removed won't do them
+/sbin/chkconfig --del plague-builder >/dev/null 2>&1 || :
+/bin/systemctl try-restart plague-builder.service >/dev/null 2>&1 || :
+
+
%files
%defattr(-, root, root)
%{_bindir}/%{name}-server
@@ -132,6 +191,7 @@ fi
%dir %{_sysconfdir}/%{name}/server/certs
%config(noreplace) %{_sysconfdir}/sysconfig/%{name}-server
%{_initrddir}/%{name}-server
+%{_unitdir}/%{name}-server.service
%doc www
%files common
@@ -151,6 +211,7 @@ fi
%dir %{_sysconfdir}/%{name}/builder/certs
%config(noreplace) %{_sysconfdir}/sysconfig/%{name}-builder
%{_initrddir}/%{name}-builder
+%{_unitdir}/%{name}-builder.service
%dir /var/lib/plague
%attr(0755, plague-builder, plague-builder) /var/lib/plague/builder
@@ -165,6 +226,11 @@ fi
%changelog
+* Tue Nov 8 2011 Michael Schwendt <mschwendt at fedoraproject.org> - 0.4.5.8-3
+- Some fixes for systemd compatibility, e.g. patch daemonize.py double-fork
+ to let parent die only after second child has written PID file.
+- Add systemd unit files and related package scriptlets.
+
* Wed Feb 09 2011 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 0.4.5.8-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
More information about the scm-commits
mailing list