Merge branch 'systemd'
authorThierry Parmentelat <thierry.parmentelat@inria.fr>
Mon, 3 Feb 2014 09:54:23 +0000 (10:54 +0100)
committerThierry Parmentelat <thierry.parmentelat@inria.fr>
Mon, 3 Feb 2014 09:54:23 +0000 (10:54 +0100)
Makefile
initscript.py
nodemanager-lib.spec
nodemanager-lxc.spec
nodemanager-vs.spec
sliver-systemd/vinit.service [new file with mode: 0644]
sliver_libvirt.py
systemd/conf_files.service [new file with mode: 0644]
systemd/fuse-pl.service [new file with mode: 0644]
systemd/nm.service [new file with mode: 0644]
tools.py

index c84241d..5da2c2a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,11 @@
 # autoconf compatible variables
 datadir := /usr/share
 bindir := /usr/bin
+# call with either WITH_SYSTEMD=true or WITH_INIT=true
+initdir=/etc/rc.d/init.d
+systemddir := /usr/lib/systemd/system
 
+####################
 lib: forward_api_calls
        python setup-lib.py build
 
@@ -23,12 +27,45 @@ forward_api_calls: forward_api_calls.c
        $(CC) -Wall -Os -o $@ $?
        strip $@
 
-install-lib:
+#################### install
+install-lib: install-miscell install-startup
        python setup-lib.py install \
                --install-purelib=$(DESTDIR)/$(datadir)/NodeManager \
                --install-platlib=$(DESTDIR)/$(datadir)/NodeManager \
                --install-scripts=$(DESTDIR)/$(bindir)
-       install -m 444 README $(DESTDIR)/$(datadir)/NodeManager
+
+# might be better in setup.py ?
+# NOTE: the sliver-initscripts/ and sliver-systemd stuff, being, well, for slivers,
+# need to ship on all nodes regardless of WITH_INIT and WITH_SYSTEMD that 
+# impacts how nodemanager itself gets started
+install-miscell:
+       install -d -m 755 $(DESTDIR)/var/lib/nodemanager
+       install -D -m 444 README $(DESTDIR)/$(datadir)/NodeManager/README
+       install -D -m 644 logrotate/nodemanager $(DESTDIR)/etc/logrotate.d/nodemanager
+       install -D -m 755 sshsh $(DESTDIR)/bin/sshsh
+       mkdir -p $(DESTDIR)/$(datadir)/NodeManager/sliver-initscripts
+       rsync -av sliver-initscripts/ $(DESTDIR)/$(datadir)/NodeManager/sliver-initscripts/
+       chmod 755 $(DESTDIR)/$(datadir)/NodeManager/sliver-initscripts/
+       mkdir -p $(DESTDIR)/$(datadir)/NodeManager/sliver-systemd
+       rsync -av sliver-systemd/ $(DESTDIR)/$(datadir)/NodeManager/sliver-systemd/
+       chmod 755 $(DESTDIR)/$(datadir)/NodeManager/sliver-systemd/
+
+# this now is for the startup of nodemanager itself
+ifneq "$(WITH_SYSTEMD)" ""
+install-startup: install-systemd
+endif
+ifneq "$(WITH_INIT)" ""
+install-startup: install-init
+endif
+
+install-init:
+       mkdir -p $(DESTDIR)$(initdir)
+       chmod 755 initscripts/*
+       rsync -av initscripts/ $(DESTDIR)$(initdir)/
+
+install-systemd:
+       mkdir -p $(DESTDIR)/$(systemddir)
+       rsync -av systemd/ $(DESTDIR)/$(systemddir)
 
 install-vs:
        python setup-vs.py install \
@@ -44,21 +81,7 @@ install-lxc:
                --install-scripts=$(DESTDIR)/$(bindir)
        install -m 444 README $(DESTDIR)/$(datadir)/NodeManager
 
-install-scripts: 
-       mkdir -p $(DESTDIR)/$(datadir)/NodeManager/sliver-initscripts
-       rsync -av sliver-initscripts/ $(DESTDIR)/$(datadir)/sliver-initscripts/
-       chmod 755 $(DESTDIR)/$(datadir)/sliver-initscripts/
-
-       mkdir -p $(DESTDIR)/etc/init.d
-       chmod 755 initscripts/*
-       rsync -av initscripts/ $(DESTDIR)/etc/init.d/
-
-       install -d -m 755 $(DESTDIR)/var/lib/nodemanager
-
-       install -D -m 644 logrotate/nodemanager $(DESTDIR)/etc/logrotate.d/nodemanager
-       install -D -m 755 sshsh $(DESTDIR)/bin/sshsh
-
-
+#################### clean
 clean:
        python setup-lib.py clean
        python setup-vs.py clean
@@ -113,7 +136,7 @@ else
        @echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        +$(RSYNC) --exclude sshsh $(LXC_EXCLUDES) --delete-excluded ./ $(NODEURL)/usr/share/NodeManager/
        +$(RSYNC) ./sshsh $(NODEURL)/bin/
-#      +$(RSYNC) ./initscripts/nm $(NODEURL)/etc/init.d/nm
+#      +$(RSYNC) ./initscripts/ $(NODEURL)/etc/init.d/
        +$(RSYNC) ./systemd/ $(NODEURL)/usr/lib/systemd/system/
 #      ssh -i $(NODE).key.rsa root@$(NODE) service nm restart
 endif
index 5dd15c8..52096eb 100644 (file)
@@ -1,5 +1,3 @@
-# Restarting nm (via systemctl):  Warning: Unit file of created job changed on disk, 'systemctl --system daemon-reload' recommended.
-
 import os, os.path
 import tools
 
@@ -20,25 +18,60 @@ class Initscript:
             #self.initscriptchanged = True
             self.refresh_slice_vinit()
 
+    def install_and_enable_vinit (self):
+        "prepare sliver rootfs init and systemd so the vinit service kicks in"
+        # the fact that systemd attempts to run old-style services 
+        # says we should do either one or the other and not both
+        # but actually if that was true we could just do it for init and be fine
+        # which is not what we've seen starting with f18
+        # so we try for a systemd system, and if it fails it means 
+        # one of the dir does not exist and so we are dealing with an init-based rootfs
+        try:    self.install_and_enable_vinit_for_systemd ()
+        except: self.install_and_enable_vinit_for_init ()
+
     # unconditionnally install and enable the generic vinit script
     # mimicking chkconfig for enabling the generic vinit script
     # this is hardwired for runlevel 3
-    def install_and_enable_vinit (self):
+    def install_and_enable_vinit_for_init (self):
+        "suitable for init-based VMs"
         vinit_source="/usr/share/NodeManager/sliver-initscripts/vinit"
         vinit_script="/vservers/%s/etc/rc.d/init.d/vinit"%self.name
-        rc3_link="/vservers/%s/etc/rc.d/rc3.d/S99vinit"%self.name
-        rc3_target="../init.d/vinit"
+        enable_link="/vservers/%s/etc/rc.d/rc3.d/S99vinit"%self.name
+        enable_target="../init.d/vinit"
         # install in sliver
         code=file(vinit_source).read()
         if tools.replace_file_with_string(vinit_script,code,chmod=0755):
             logger.log("Initscript: %s: installed generic vinit rc script"%self.name)
         # create symlink for runlevel 3
-        if not os.path.islink(rc3_link):
+        if not os.path.islink(enable_link):
+            try:
+                logger.log("Initscript: %s: creating runlevel3 symlink %s"%(self.name,enable_link))
+                os.symlink(enable_target,enable_link)
+            except:
+                logger.log_exc("Initscript: %s: failed to create runlevel3 symlink %s"%enable_link)
+
+    # very similar but with systemd unit files - we target 'multi-user' in this context
+    def install_and_enable_vinit_for_systemd(self):
+        "suitable for systemd-based VMs"
+        vinit_source="/usr/share/NodeManager/sliver-systemd/vinit.service"
+        vinit_unit_file="/vservers/%s/usr/lib/systemd/system/vinit.service"%self.name
+        enable_link="/vservers/%s/etc/systemd/system/multi-user.target.wants/vinit.service"%self.name
+        enable_target="/usr/lib/systemd/system/vinit.service"
+        # install in sliver
+        code=file(vinit_source).read()
+        if tools.replace_file_with_string(vinit_unit_file,code,chmod=0755):
+            logger.log("Initscript: %s: installed vinit.service unit file"%self.name)
+        # create symlink for enabling this unit
+        if not os.path.islink(enable_link):
             try:
-                logger.log("Initscript: %s: creating runlevel3 symlink %s"%(self.name,rc3_link))
-                os.symlink(rc3_target,rc3_link)
+                logger.log("Initscript: %s: creating enabling symlink %s"%(self.name,enable_link))
+                os.symlink(enable_target,enable_link)
             except:
-                logger.log_exc("Initscript: %s: failed to create runlevel3 symlink %s"%rc3_link)
+                logger.log_exc("Initscript: %s: failed to create enabling symlink %s"%enable_link)
+
+
+#ln -s '/usr/lib/systemd/system/vinit.service' '/etc/systemd/system/multi-user.target.wants/vinit.service'
+
 
     # install or remove the slice inistscript, as instructed by the initscript tag
     def refresh_slice_vinit(self):
index 7687c9e..2db3276 100644 (file)
@@ -6,6 +6,15 @@
 
 %define release %{taglevel}%{?pldistro:.%{pldistro}}%{?date:.%{date}}
 
+########## use initscripts or systemd unit files to start installed services
+%if "%{distro}" == "Fedora" && %{distrorelease} >= 18
+%define make_options WITH_SYSTEMD=true
+%define initdir /usr/lib/systemd/system
+%else
+%define make_options WITH_INIT=true
+%define initdir %{_initrddir}
+%endif
+
 Summary: PlanetLab Node Manager Library
 Name: %{name}
 Version: %{version}
@@ -23,8 +32,13 @@ URL: %{SCMURL}
 # not possible because of forward_api_calls
 #BuildArch: noarch
 
+# make sure we can invoke systemctl in post install script
+%if "%{initdir}" != "%{_initrddir}"
+Requires: systemd
+%endif
+
 # Uses function decorators
-Requires: python >= 2.4
+Requires: python >= 2.7
 # connecting PLC
 Requires: python-pycurl
 # Signed tickets
@@ -45,55 +59,24 @@ local operations on slices.
 nodemanager-lib only provides a skeleton and needs as a companion
 either nodemanager-vs or nodemanager-lxc
 
+##############################
 %prep
 %setup -q
 
 %build
 # make manages the C and Python stuff
-%{__make} %{?_smp_mflags} lib
+%{__make} %{?_smp_mflags} %{make_options} lib 
 
 %install
 # make manages the C and Python stuff
 rm -rf $RPM_BUILD_ROOT
-%{__make} %{?_smp_mflags} install-lib DESTDIR="$RPM_BUILD_ROOT"
-
-# install the sliver initscript (that triggers the slice initscript if any)
-mkdir -p $RPM_BUILD_ROOT/usr/share/NodeManager/sliver-initscripts/
-rsync -av sliver-initscripts/ $RPM_BUILD_ROOT/usr/share/NodeManager/sliver-initscripts/
-chmod 755 $RPM_BUILD_ROOT/usr/share/NodeManager/sliver-initscripts/
-
-mkdir -p $RPM_BUILD_ROOT/%{_initrddir}/
-rsync -av initscripts/ $RPM_BUILD_ROOT/%{_initrddir}/
-chmod 755 $RPM_BUILD_ROOT/%{_initrddir}/*
-
-install -d -m 755 $RPM_BUILD_ROOT/var/lib/nodemanager
+%{__make} %{?_smp_mflags} %{make_options} install-lib DESTDIR="$RPM_BUILD_ROOT"
 
-install -D -m 644 logrotate/nodemanager $RPM_BUILD_ROOT/%{_sysconfdir}/logrotate.d/nodemanager
-install -D -m 755 sshsh $RPM_BUILD_ROOT/bin/sshsh
-
-##########
+##############################
 %post
-# tmp - handle file renamings; old names are from 2.0-8
-renamings="
-/var/lib/misc/bwmon.dat@/var/lib/nodemanager/bwmon.pickle
-/root/sliver_mgr_db.pickle@/var/lib/nodemanager/database.pickle
-/var/log/getslivers.txt@/var/lib/nodemanager/getslivers.txt
-/var/log/nm@/var/log/nodemanager
-/var/log/nm.daemon@/var/log/nodemanager.daemon
-/var/run/nm.pid@/var/run/nodemanager.pid
-/tmp/sliver_mgr.api@/tmp/nodemanager.api
-/etc/logrotate.d/nm@/etc/logrotate.d/nodemanager
-"
-for renaming in $renamings; do
-  old=$(echo $renaming | cut -d@ -f1)
-  new=$(echo $renaming | cut -d@ -f2)
-  newdir=$(dirname $new)
-  if [ -e "$old" -a ! -e "$new" ] ; then
-      mkdir -p $newdir
-      mv -f $old $new
-  fi
-done
-#
+########## traditional init
+%if "%{initdir}" == "%{_initrddir}"
+##########
 chkconfig --add conf_files
 chkconfig conf_files on
 chkconfig --add nm
@@ -101,13 +84,29 @@ chkconfig nm on
 chkconfig --add fuse-pl
 chkconfig fuse-pl on
 if [ "$PL_BOOTCD" != "1" ] ; then
-       service nm restart
-       service fuse-pl restart
+    service nm restart
+    service fuse-pl restart
 fi
-
 ##########
+%else
+########## systemd
+systemctl enable nm.service
+systemctl enable conf_files.service
+# empty
+#systemctl enable fuse-pl.service
+if [ "$PL_BOOTCD" != "1" ] ; then
+    systemctl restart nm.service
+#    systemctl restart fuse-pl.service
+fi
+##########
+%endif
+
+##############################
 %preun
 # 0 = erase, 1 = upgrade
+########## traditional init
+%if "%{initdir}" == "%{_initrddir}"
+##########
 if [ $1 -eq 0 ] ; then
     chkconfig fuse-pl off
     chkconfig --del fuse-pl
@@ -116,7 +115,18 @@ if [ $1 -eq 0 ] ; then
     chkconfig conf_files off
     chkconfig --del conf_files
 fi
+##########
+%else
+########## systemd
+if [ $1 -eq 0 ] ; then
+#    systemctl disable fuse-pl.service
+    systemctl disable conf_files.service
+    systemctl disable nm.service
+fi
+##########
+%endif
 
+##############################
 %clean
 rm -rf $RPM_BUILD_ROOT
 
@@ -124,9 +134,9 @@ rm -rf $RPM_BUILD_ROOT
 %defattr(-,root,root,-)
 %{_datadir}/NodeManager/
 %{_bindir}/forward_api_calls
-%{_initrddir}/
+%{initdir}/
 %{_sysconfdir}/logrotate.d/nodemanager
-/var/lib/
+/var/lib/nodemanager/
 /bin/sshsh
 
 %changelog
index 4846c08..94434dd 100644 (file)
@@ -23,13 +23,16 @@ Packager: PlanetLab Central <support@planet-lab.org>
 Distribution: PlanetLab %{plrelease}
 URL: %{SCMURL}
 
+# for nodeupdate 
+Provides: nodemanager
+
 # we use libvirt
 Requires: libvirt
 Requires: libvirt-python
 # cgroups.py needs this
 Requires: python-inotify
 # the common package for nodemanager
-Requires: nodemanager-lib
+Requires: nodemanager-lib = %{version}
 # the lxc-specific tools for using slice images
 Requires: lxc-sliceimage
 Requires: openvswitch
index f71bc83..095da1e 100644 (file)
@@ -25,13 +25,15 @@ URL: %{SCMURL}
 
 # old name, when all came as a single package with vserver wired in
 Obsoletes: NodeManager
+# for nodeupdate 
+Provides: nodemanager
 
 # our interface to the vserver patch
 Requires: util-vserver >= 0.30.208-17
 # and the planetlab utilities
 Requires: util-vserver-python > 0.3-16
 # the common package for nodemanager
-Requires: nodemanager-lib
+Requires: nodemanager-lib = %{version}
 # the vserver-specific tools for using slice images
 Requires: vserver-sliceimage
 
diff --git a/sliver-systemd/vinit.service b/sliver-systemd/vinit.service
new file mode 100644 (file)
index 0000000..5e3cb62
--- /dev/null
@@ -0,0 +1,10 @@
+[Unit]
+Description=User-defined initscript manager
+After=network.target
+
+[Service]
+Type=forking
+ExecStart=/bin/bash -c '/etc/rc.d/init.d/vinit.slice start $(cat /etc/slicename) >> /var/log/vinit 2>&1 &'
+
+[Install]
+WantedBy=multi-user.target
index cad14cb..6ae8eeb 100644 (file)
@@ -110,7 +110,7 @@ class Sliver_Libvirt(Account):
                 logger.verbose('sliver_libvirt: %s is RUNNING'%self.name)
                 return True
             else:
-                info = debuginfo(self.dom)
+                info = Sliver_Libvirt.debuginfo(self.dom)
                 logger.verbose('sliver_libvirt: %s is ' \
                                'NOT RUNNING...\n%s'%(self.name, info))
                 return False
diff --git a/systemd/conf_files.service b/systemd/conf_files.service
new file mode 100644 (file)
index 0000000..5a6ecc8
--- /dev/null
@@ -0,0 +1,10 @@
+[Unit]
+Description=Fetch configuration files as defined by controlling MyPLC
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/env python /usr/share/NodeManager/conf_files.py
+Before=lxc-sliceimage
+
+[Install]
+WantedBy=multi-user.target
diff --git a/systemd/fuse-pl.service b/systemd/fuse-pl.service
new file mode 100644 (file)
index 0000000..f98ddfe
--- /dev/null
@@ -0,0 +1,2 @@
+# This is placeholder for fuse-pl in a lxc/systemd setup
+# needs to be rewritten as the initscript version seems to rely on vservers
diff --git a/systemd/nm.service b/systemd/nm.service
new file mode 100644 (file)
index 0000000..f279894
--- /dev/null
@@ -0,0 +1,12 @@
+[Unit]
+Description=PlanetLab NodeManager
+After=libvirtd.target
+
+[Service]
+EnvironmentFile=/etc/sysconfig/nodemanager
+Type=forking
+PIDFile=/var/run/nodemanager.pid
+ExecStart=/usr/bin/env python /usr/share/NodeManager/nodemanager.py -d $OPTIONS
+
+[Install]
+WantedBy=multi-user.target
index f081826..862efc6 100644 (file)
--- a/tools.py
+++ b/tools.py
@@ -333,7 +333,7 @@ def command_in_slice (slicename, argv):
 def init_signals ():
     def handler (signum, frame):
         logger.log("Received signal %d - exiting"%signum)
-        exit(1)
+        os._exit(1)
     signal.signal(signal.SIGHUP,handler)
     signal.signal(signal.SIGQUIT,handler)
     signal.signal(signal.SIGINT,handler)