>From 0f025a60fcfa718de75c9c850cdf5c181feb1c8e Mon Sep 17 00:00:00 2001
From: Ade Lee <alee@redhat.com>
Date: Wed, 6 May 2015 16:06:34 -0400
Subject: [PATCH] Patches to get nuxwdog working with systemd

This patch adds some new unit files and targets for starting instances
with nuxwdog, as well as logic within the pki-server nuxwdog module to
switch to/from the old and new systemd unit files.

It also corrects some issues found in additional testing of the nuxwdog
change scripts.

To use nuxwdog to start the instance, a user needs to do the following:

1. Create an instance normally.
2. Run: pki-server instance-nuxwdog-enable <instance_name>
3. Start the instance using:
   systemctl start pki-tomcatd-nuxwdog@<instance_name>.service

To revert the instance, simply do the following:

1. Run: pki-server instance-nuxwdog-disable <instance_name>
2. Start the instance using:
   systemctl start pki-tomcatd@<instance_name>.service
---
 base/common/CMakeLists.txt                         |   6 +
 base/server/python/pki/server/cli/nuxwdog.py       | 132 +++++++++++++++++++++
 base/server/python/pki/server/cli/subsystem.py     |   3 +-
 .../lib/systemd/system/pki-tomcatd-nuxwdog.target  |   7 ++
 .../systemd/system/pki-tomcatd-nuxwdog@.service    |  15 +++
 specs/pki-core.spec                                |   4 +
 6 files changed, 166 insertions(+), 1 deletion(-)
 create mode 100644 base/server/share/lib/systemd/system/pki-tomcatd-nuxwdog.target
 create mode 100644 base/server/share/lib/systemd/system/pki-tomcatd-nuxwdog@.service

diff --git a/base/common/CMakeLists.txt b/base/common/CMakeLists.txt
index f82a0df8918064b8cbf3bb0842b0347b3e931f6f..df9feacf3f3fabbff176e3c04243216040676ae5 100644
--- a/base/common/CMakeLists.txt
+++ b/base/common/CMakeLists.txt
@@ -89,6 +89,12 @@ install(
 
 install(
     DIRECTORY
+    DESTINATION 
+        ${SYSTEMD_ETC_INSTALL_DIR}/pki-tomcatd-nuxwdog.target.wants
+)
+
+install(
+    DIRECTORY
         man/
     DESTINATION
         ${MAN_INSTALL_DIR}
diff --git a/base/server/python/pki/server/cli/nuxwdog.py b/base/server/python/pki/server/cli/nuxwdog.py
index d439dd7dbb2608269600507b2267c38a322b91bf..8068c220de016be84084cc52cf75fad0670fb95b 100644
--- a/base/server/python/pki/server/cli/nuxwdog.py
+++ b/base/server/python/pki/server/cli/nuxwdog.py
@@ -22,6 +22,7 @@
 import getopt
 import fileinput
 import os
+import pwd
 import re
 import struct
 import subprocess
@@ -56,6 +57,8 @@ class NuxwdogEnableCLI(pki.cli.CLI):
         super(NuxwdogEnableCLI, self).__init__(
             'enable',
             'Enable nuxwdog')
+        self.uid = 0
+        self.gid = 0
 
     def print_help(self):
         print 'Usage: pki-server nuxwdog-enable [OPTIONS]'
@@ -95,6 +98,9 @@ class NuxwdogEnableCLI(pki.cli.CLI):
         self.print_message('Nuxwdog enabled for system.')
 
     def enable_nuxwdog(self, instance):
+        # get pkiuser
+        self.get_tomcat_uid_gid(instance)
+
         # add nuxwdog link
         self.add_nuxwdog_link(instance)
 
@@ -108,6 +114,12 @@ class NuxwdogEnableCLI(pki.cli.CLI):
         server_xml = os.path.join(instance.conf_dir, 'server.xml')
         self.enable_nuxwdog_server_xml(server_xml, instance)
 
+        # change systemd links
+        self.change_systemd_links(instance)
+
+        # modify CS.cfg
+        self.modify_password_class_in_cs_cfg(instance)
+
     def add_nuxwdog_link(self, instance):
         nuxwdog_jar_path = '/usr/lib/java/nuxwdog.jar'
         if not os.path.exists(nuxwdog_jar_path):
@@ -156,6 +168,8 @@ class NuxwdogEnableCLI(pki.cli.CLI):
             with open(sysconfig_file, 'a') as f:
                 f.write("USE_NUXWDOG=\"true\"\n")
 
+        os.chown(sysconfig_file, self.uid, self.gid)
+
     def get_conf_file(self, instance):
         if not instance.subsystems:
             print "Error: Instance has no subsystems."
@@ -208,6 +222,60 @@ class NuxwdogEnableCLI(pki.cli.CLI):
         with open(filename, 'w') as f:
             f.write(etree.tostring(document, pretty_print=True))
 
+        os.chown(filename, self.uid, self.gid)
+
+    def change_systemd_links(self, instance):
+        old_systemd_unit_file = 'pki-tomcatd@' + instance.name + '.service'
+        old_systemd_link = os.path.join(
+            '/etc/systemd/system/pki-tomcatd.target.wants',
+            old_systemd_unit_file)
+
+        new_systemd_unit_file = ('pki-tomcatd-nuxwdog@' + instance.name
+                                 + '.service')
+        new_systemd_link = os.path.join(
+            '/etc/systemd/system/pki-tomcatd-nuxwdog.target.wants',
+            new_systemd_unit_file)
+        new_systemd_source = '/lib/systemd/system/pki-tomcatd-nuxwdog@.service'
+
+        if os.path.exists(old_systemd_link):
+            os.unlink(old_systemd_link)
+
+        if os.path.exists(new_systemd_link):
+            os.unlink(new_systemd_link)
+        os.symlink(new_systemd_source, new_systemd_link)
+
+        subprocess.check_call(['systemctl', 'daemon-reload'])
+
+    def modify_password_class_in_cs_cfg(self, instance):
+        if not instance.subsystems:
+            print "Error: Instance has no subsystems."
+            sys.exit(1)
+
+        pclass = "com.netscape.cmsutil.password.NuxwdogPasswordStore"
+
+        for subsystem in instance.subsystems:
+            cs_cfg = os.path.join(subsystem.conf_dir, 'CS.cfg')
+            for line in fileinput.input(cs_cfg, inplace=1):
+                match = re.search("^passwordClass=(.*)", line)
+                if match:
+                    line = "passwordClass=" + pclass + "\n"
+                sys.stdout.write(line)
+            os.chown(cs_cfg, self.uid, self.gid)
+
+    def get_tomcat_uid_gid(self, instance):
+        user = "pkiuser"
+        sysconfig_file = os.path.join('/etc/sysconfig', instance.name)
+        for line in fileinput.input(sysconfig_file):
+            match = re.search("^TOMCAT_USER=\"(.*)\"", line)
+            if match:
+                user = match.group(1)
+
+        user_pwd = pwd.getpwnam(user)
+
+        if user_pwd:
+            self.uid = user_pwd.pw_uid
+            self.gid = user_pwd.pw_gid
+
 
 class NuxwdogDisableCLI(pki.cli.CLI):
 
@@ -222,6 +290,8 @@ class NuxwdogDisableCLI(pki.cli.CLI):
         super(NuxwdogDisableCLI, self).__init__(
             'disable',
             'Disable nuxwdog')
+        self.uid = 0
+        self.gid = 0
 
     def print_help(self):
         print 'Usage: pki-server nuxwdog-disable [OPTIONS]'
@@ -261,6 +331,8 @@ class NuxwdogDisableCLI(pki.cli.CLI):
         self.print_message('Nuxwdog disabled for system.')
 
     def disable_nuxwdog(self, instance):
+        self.get_tomcat_uid_gid(instance)
+
         self.disable_nuxwdog_sysconfig_file(instance)
         self.remove_nuxwdog_link(instance)
 
@@ -271,6 +343,10 @@ class NuxwdogDisableCLI(pki.cli.CLI):
         server_xml = os.path.join(instance.conf_dir, 'server.xml')
         self.disable_nuxwdog_server_xml(server_xml, instance)
 
+        self.change_systemd_links(instance)
+
+        self.modify_password_class_in_cs_cfg(instance)
+
     def disable_nuxwdog_sysconfig_file(self, instance):
         sysconfig_file = os.path.join('/etc/sysconfig', instance.name)
 
@@ -292,6 +368,8 @@ class NuxwdogDisableCLI(pki.cli.CLI):
 
             sys.stdout.write(line)
 
+        os.chown(sysconfig_file, self.uid, self.gid)
+
     def remove_nuxwdog_link(self, instance):
         instance_jar_path = os.path.join(
             instance.base_dir,
@@ -327,3 +405,57 @@ class NuxwdogDisableCLI(pki.cli.CLI):
 
         with open(filename, 'w') as f:
             f.write(etree.tostring(document, pretty_print=True))
+
+        os.chown(filename, self.uid, self.gid)
+
+    def change_systemd_links(self, instance):
+        old_systemd_unit_file = ('pki-tomcatd-nuxwdog@' + instance.name
+                                 + '.service')
+        old_systemd_link = os.path.join(
+            '/etc/systemd/system/pki-tomcatd-nuxwdog.target.wants',
+            old_systemd_unit_file)
+
+        new_systemd_unit_file = 'pki-tomcatd@' + instance.name + '.service'
+        new_systemd_link = os.path.join(
+            '/etc/systemd/system/pki-tomcatd.target.wants',
+            new_systemd_unit_file)
+        new_systemd_source = '/lib/systemd/system/pki-tomcatd@.service'
+
+        if os.path.exists(old_systemd_link):
+            os.unlink(old_systemd_link)
+
+        if os.path.exists(new_systemd_link):
+            os.unlink(new_systemd_link)
+        os.symlink(new_systemd_source, new_systemd_link)
+
+        subprocess.check_call(['systemctl', 'daemon-reload'])
+
+    def modify_password_class_in_cs_cfg(self, instance):
+        if not instance.subsystems:
+            print "Error: Instance has no subsystems."
+            sys.exit(1)
+
+        pclass = "com.netscape.cmsutil.password.PlainPasswordFile"
+
+        for subsystem in instance.subsystems:
+            cs_cfg = os.path.join(subsystem.conf_dir, 'CS.cfg')
+            for line in fileinput.input(cs_cfg, inplace=1):
+                match = re.search("^passwordClass=(.*)", line)
+                if match:
+                    line = "passwordClass=" + pclass + "\n"
+                sys.stdout.write(line)
+                os.chown(cs_cfg, self.uid, self.gid)
+
+    def get_tomcat_uid_gid(self, instance):
+        user = "pkiuser"
+        sysconfig_file = os.path.join('/etc/sysconfig', instance.name)
+        for line in fileinput.input(sysconfig_file):
+            match = re.search("^TOMCAT_USER=\"(.*)\"", line)
+            if match:
+                user = match.group(1)
+
+        user_pwd = pwd.getpwnam(user)
+
+        if user_pwd:
+            self.uid = user_pwd.pw_uid
+            self.gid = user_pwd.pw_gid
diff --git a/base/server/python/pki/server/cli/subsystem.py b/base/server/python/pki/server/cli/subsystem.py
index 3aad00a05a36d2b92224f13a7ce3658081c11569..43eb564ee462ce0bad5646c151bcf8aa81d0724b 100644
--- a/base/server/python/pki/server/cli/subsystem.py
+++ b/base/server/python/pki/server/cli/subsystem.py
@@ -30,7 +30,8 @@ import pki.server
 class SubsystemCLI(pki.cli.CLI):
 
     def __init__(self):
-        super(SubsystemCLI, self).__init__('subsystem', 'Subsystem management commands')
+        super(SubsystemCLI, self).__init__('subsystem',
+                                           'Subsystem management commands')
 
         self.add_module(SubsystemDisableCLI())
         self.add_module(SubsystemEnableCLI())
diff --git a/base/server/share/lib/systemd/system/pki-tomcatd-nuxwdog.target b/base/server/share/lib/systemd/system/pki-tomcatd-nuxwdog.target
new file mode 100644
index 0000000000000000000000000000000000000000..06a7dcdea871b52e353ac7ee57dd1ee4ed0a3fc3
--- /dev/null
+++ b/base/server/share/lib/systemd/system/pki-tomcatd-nuxwdog.target
@@ -0,0 +1,7 @@
+[Unit]
+Description=PKI Tomcat Server Started by Nuxwdog
+Wants=dirsrv.target
+After=syslog.target network.target dirsrv.target
+
+[Install]
+WantedBy=multi-user.target
diff --git a/base/server/share/lib/systemd/system/pki-tomcatd-nuxwdog@.service b/base/server/share/lib/systemd/system/pki-tomcatd-nuxwdog@.service
new file mode 100644
index 0000000000000000000000000000000000000000..2bdf1250391c5e37aae035dd92375f4fe7d06fa6
--- /dev/null
+++ b/base/server/share/lib/systemd/system/pki-tomcatd-nuxwdog@.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=PKI Tomcat Server %i Started by Nuxwdog
+PartOf=pki-tomcatd-nuxwdog.target
+
+[Service]
+Type=forking
+EnvironmentFile=/etc/tomcat/tomcat.conf
+Environment="NAME=%i"
+Environment="STARTED_BY_SYSTEMD=1"
+EnvironmentFile=-/etc/sysconfig/%i
+ExecStartPre=/usr/bin/pkidaemon start tomcat %i
+ExecStart=/bin/nuxwdog -f /etc/pki/%i/nuxwdog.conf
+SuccessExitStatus=143
+TimeoutStartSec=180
+PidFile=/var/lib/pki/%i/logs/wd-%i.pid
diff --git a/specs/pki-core.spec b/specs/pki-core.spec
index 98f8365ba2fccd96121f10749087eff0cd82c11f..c82eee2f452003cab38e11fdf89fc79b5ffbc6f6 100644
--- a/specs/pki-core.spec
+++ b/specs/pki-core.spec
@@ -857,6 +857,9 @@ systemctl daemon-reload
 %dir %{_sysconfdir}/systemd/system/pki-tomcatd.target.wants
 %{_unitdir}/pki-tomcatd@.service
 %{_unitdir}/pki-tomcatd.target
+%dir %{_sysconfdir}/systemd/system/pki-tomcatd-nuxwdog.target.wants
+%{_unitdir}/pki-tomcatd-nuxwdog@.service
+%{_unitdir}/pki-tomcatd-nuxwdog.target
 %{_javadir}/pki/pki-cms.jar
 %{_javadir}/pki/pki-cmsbundle.jar
 %{_javadir}/pki/pki-cmscore.jar
@@ -939,6 +942,7 @@ systemctl daemon-reload
 %changelog
 * Thu Apr 23 2015 Dogtag Team <pki-devel@redhat.com> 10.2.4-0.1
 - Updated version number to 10.2.4-0.1
+- Added nuxwdog systemd files
 
 * Thu Apr 23 2015 Dogtag Team <pki-devel@redhat.com> 10.2.3-1
 - Update release number for release build
-- 
1.9.3

