diff options
author | Ade Lee <alee@redhat.com> | 2015-05-06 16:06:34 -0400 |
---|---|---|
committer | Ade Lee <alee@redhat.com> | 2015-05-10 16:09:24 -0400 |
commit | 7dca020819b7573cd05bd54482fb5d1afe9bb658 (patch) | |
tree | 871e3a9d350c081e52a26b0583bd02e8f2dd761b /base | |
parent | 2db074c39334a6ec48a6fac52722f684a14bb00a (diff) | |
download | pki-7dca020819b7573cd05bd54482fb5d1afe9bb658.tar.gz pki-7dca020819b7573cd05bd54482fb5d1afe9bb658.tar.xz pki-7dca020819b7573cd05bd54482fb5d1afe9bb658.zip |
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
Diffstat (limited to 'base')
19 files changed, 153 insertions, 35 deletions
diff --git a/base/common/CMakeLists.txt b/base/common/CMakeLists.txt index f82a0df89..37139f78f 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/java-tools/src/com/netscape/cmstools/HttpClient.java b/base/java-tools/src/com/netscape/cmstools/HttpClient.java index 132375298..f0603a4bd 100644 --- a/base/java-tools/src/com/netscape/cmstools/HttpClient.java +++ b/base/java-tools/src/com/netscape/cmstools/HttpClient.java @@ -30,7 +30,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; -import java.net.SocketException; import java.util.StringTokenizer; import org.mozilla.jss.CryptoManager; diff --git a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java index b6750c615..729fb4a80 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java +++ b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java @@ -321,6 +321,7 @@ public class CMSEngine implements ICMSEngine { try { mPasswordStore = (IPasswordStore) Class.forName(pwdClass).newInstance(); mPasswordStore.init(pwdPath); + mPasswordStore.setId(instanceId); } catch (Exception e) { System.out.println("Cannot get password store: " + e); throw new EBaseException(e); @@ -467,6 +468,9 @@ public class CMSEngine implements ICMSEngine { serverStatus = "starting"; + instanceDir = config.getString("instanceRoot"); + instanceId = config.getString("instanceId"); + if (state == 1) { // configuration is complete, initialize password store try { @@ -497,9 +501,6 @@ public class CMSEngine implements ICMSEngine { mTimeSource = new SimpleTimeSource(); } - instanceDir = config.getString("instanceRoot"); - instanceId = config.getString("instanceId"); - loadDynSubsystems(); java.security.Security.addProvider( diff --git a/base/server/cmscore/src/com/netscape/cmscore/base/LDAPConfigStore.java b/base/server/cmscore/src/com/netscape/cmscore/base/LDAPConfigStore.java index a9a6536f0..b7b4ca46e 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/base/LDAPConfigStore.java +++ b/base/server/cmscore/src/com/netscape/cmscore/base/LDAPConfigStore.java @@ -18,13 +18,9 @@ package com.netscape.cmscore.base; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; -import java.util.Enumeration; import java.util.Map; import netscape.ldap.LDAPAttribute; diff --git a/base/server/cmscore/src/com/netscape/cmscore/profile/AbstractProfileSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/profile/AbstractProfileSubsystem.java index 238816ff0..cf5d77f19 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/profile/AbstractProfileSubsystem.java +++ b/base/server/cmscore/src/com/netscape/cmscore/profile/AbstractProfileSubsystem.java @@ -21,7 +21,6 @@ import java.util.Collections; import java.util.Enumeration; import java.util.Hashtable; import java.util.LinkedHashMap; -import java.util.Vector; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.IConfigStore; diff --git a/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java index 199a5576e..83ae5078d 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java +++ b/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java @@ -18,13 +18,10 @@ package com.netscape.cmscore.profile; import java.io.ByteArrayInputStream; -import java.io.IOException; import java.io.InputStream; -import java.lang.Thread; import java.util.Enumeration; import java.util.Hashtable; import java.util.LinkedHashMap; -import java.util.Vector; import netscape.ldap.LDAPAttribute; import netscape.ldap.LDAPConnection; diff --git a/base/server/cmscore/src/com/netscape/cmscore/profile/ProfileSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/profile/ProfileSubsystem.java index 10bc50cda..90d7479e4 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/profile/ProfileSubsystem.java +++ b/base/server/cmscore/src/com/netscape/cmscore/profile/ProfileSubsystem.java @@ -22,7 +22,6 @@ import java.util.Enumeration; import java.util.Hashtable; import java.util.LinkedHashMap; import java.util.StringTokenizer; -import java.util.Vector; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.EBaseException; diff --git a/base/server/python/pki/server/cli/instance.py b/base/server/python/pki/server/cli/instance.py index 37db03988..becad1447 100644 --- a/base/server/python/pki/server/cli/instance.py +++ b/base/server/python/pki/server/cli/instance.py @@ -378,7 +378,7 @@ class InstanceNuxwdogEnableCLI(pki.cli.CLI): module.enable_nuxwdog(instance) # pylint: disable=no-member,maybe-no-member - self.print_message('nuxwdog enabled for instance %s' % instance_name) + self.print_message('Nuxwdog enabled for instance %s.' % instance_name) class InstanceNuxwdogDisableCLI(pki.cli.CLI): @@ -432,4 +432,4 @@ class InstanceNuxwdogDisableCLI(pki.cli.CLI): module.disable_nuxwdog(instance) # pylint: disable=no-member,maybe-no-member - self.print_message('nuxwdog disabled for instance %s' % instance_name) + self.print_message('Nuxwdog disabled for instance %s.' % instance_name) diff --git a/base/server/python/pki/server/cli/nuxwdog.py b/base/server/python/pki/server/cli/nuxwdog.py index d439dd7db..d6ef91e43 100644 --- a/base/server/python/pki/server/cli/nuxwdog.py +++ b/base/server/python/pki/server/cli/nuxwdog.py @@ -48,7 +48,7 @@ class NuxwdogEnableCLI(pki.cli.CLI): def __init__(self): self.parser = etree.XMLParser(remove_blank_text=True) self.nuxwdog_listener_class = ( - 'com.netscape.cms.tomcat.NuxwdogPasswordStoreInitializer' + 'com.netscape.cms.tomcat.PKIListener' ) self.nuxwdog_pwstore_class = ( 'com.netscape.cms.tomcat.NuxwdogPasswordStore' @@ -108,6 +108,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,11 +162,9 @@ class NuxwdogEnableCLI(pki.cli.CLI): with open(sysconfig_file, 'a') as f: f.write("USE_NUXWDOG=\"true\"\n") - def get_conf_file(self, instance): - if not instance.subsystems: - print "Error: Instance has no subsystems." - sys.exit(1) + os.chown(sysconfig_file, instance.uid, instance.gid) + def get_conf_file(self, instance): # return the path to the first instance subsystem = instance.subsystems[0] return os.path.join(subsystem.conf_dir, 'CS.cfg') @@ -192,7 +196,7 @@ class NuxwdogEnableCLI(pki.cli.CLI): # add before GlobalResourcesLifecycleListener if exists if global_naming_resources is not None: - index = list(server).index(global_naming_resources) + index = list(server).index(global_naming_resources) - 1 else: index = 0 @@ -208,13 +212,49 @@ class NuxwdogEnableCLI(pki.cli.CLI): with open(filename, 'w') as f: f.write(etree.tostring(document, pretty_print=True)) + os.chown(filename, instance.uid, instance.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): + 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, instance.uid, instance.gid) + class NuxwdogDisableCLI(pki.cli.CLI): def __init__(self): self.parser = etree.XMLParser(remove_blank_text=True) self.nuxwdog_listener_class = ( - 'com.netscape.cms.tomcat.NuxwdogPasswordStoreInitializer' + 'com.netscape.cms.tomcat.PKIListener' ) self.plain_pwstore_class = ( 'org.apache.tomcat.util.net.jss.PlainPasswordFile' @@ -271,6 +311,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 +336,8 @@ class NuxwdogDisableCLI(pki.cli.CLI): sys.stdout.write(line) + os.chown(sysconfig_file, instance.uid, instance.gid) + def remove_nuxwdog_link(self, instance): instance_jar_path = os.path.join( instance.base_dir, @@ -312,13 +358,6 @@ class NuxwdogDisableCLI(pki.cli.CLI): server = document.getroot() - children = list(server) - for child in children: - if child.tag == 'Listener': - class_name = child.get('className') - if class_name == self.nuxwdog_listener_class: - server.remove(child) - connectors = server.findall('Service/Connector') for connector in connectors: if connector.get('secure') == 'true': @@ -327,3 +366,39 @@ class NuxwdogDisableCLI(pki.cli.CLI): with open(filename, 'w') as f: f.write(etree.tostring(document, pretty_print=True)) + + os.chown(filename, instance.uid, instance.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): + 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, instance.uid, instance.gid) diff --git a/base/server/python/pki/server/cli/subsystem.py b/base/server/python/pki/server/cli/subsystem.py index 3aad00a05..43eb564ee 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 000000000..06a7dcdea --- /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 000000000..3a0ca6538 --- /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/base/server/tomcat/src/com/netscape/cms/tomcat/NuxwdogPasswordStore.java b/base/server/tomcat/src/com/netscape/cms/tomcat/NuxwdogPasswordStore.java index 33cfc8a85..61329d80f 100644 --- a/base/server/tomcat/src/com/netscape/cms/tomcat/NuxwdogPasswordStore.java +++ b/base/server/tomcat/src/com/netscape/cms/tomcat/NuxwdogPasswordStore.java @@ -23,6 +23,7 @@ public class NuxwdogPasswordStore implements org.apache.tomcat.util.net.jss.IPas private ArrayList<String> tags = null; private final String PROMPT_PREFIX = "Please provide the password for "; + private String instanceId; @Override public void init(String confFile) throws IOException { @@ -62,6 +63,8 @@ public class NuxwdogPasswordStore implements org.apache.tomcat.util.net.jss.IPas tags.add("hardware-" + token); } } + + instanceId = props.getProperty("instanceId"); } private void addTag(String tag) { @@ -76,6 +79,10 @@ public class NuxwdogPasswordStore implements org.apache.tomcat.util.net.jss.IPas } String prompt = PROMPT_PREFIX + tag + ":"; + if (StringUtils.isNotEmpty(instanceId)) { + prompt = "[" + instanceId + "] " + prompt; + } + String pwd = WatchdogClient.getPassword(prompt, iteration); if (pwd != null) { diff --git a/base/server/tomcat/src/com/netscape/cms/tomcat/NuxwdogPasswordStoreInitializer.java b/base/server/tomcat/src/com/netscape/cms/tomcat/PKIListener.java index a4c25306d..abd88c1a6 100644 --- a/base/server/tomcat/src/com/netscape/cms/tomcat/NuxwdogPasswordStoreInitializer.java +++ b/base/server/tomcat/src/com/netscape/cms/tomcat/PKIListener.java @@ -6,7 +6,7 @@ import org.apache.commons.lang.StringUtils; import com.redhat.nuxwdog.WatchdogClient; -public class NuxwdogPasswordStoreInitializer implements LifecycleListener { +public class PKIListener implements LifecycleListener { private boolean startedByWD = false; diff --git a/base/server/tomcat7/conf/server.xml b/base/server/tomcat7/conf/server.xml index 8b6e40473..e6c4bd201 100644 --- a/base/server/tomcat7/conf/server.xml +++ b/base/server/tomcat7/conf/server.xml @@ -79,6 +79,8 @@ Tomcat Port = [TOMCAT_SERVER_PORT] (for shutdown) <!-- has been EXCLUDED from the Tomcat 7 'tomcat-lib' RPM! --> <!-- Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" --> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> + + <Listener className="com.netscape.cms.tomcat.PKIListener"/> <!-- Global JNDI resources Documentation at /docs/jndi-resources-howto.html @@ -94,8 +96,6 @@ Tomcat Port = [TOMCAT_SERVER_PORT] (for shutdown) pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> - <Listener className="com.netscape.cms.tomcat.NuxwdogPasswordStoreInitializer"/> - <!-- A "Service" is a collection of one or more "Connectors" that share a single "Container" Note: A "Service" is not itself a "Container", so you may not define subcomponents such as "Valves" at this level. diff --git a/base/server/tomcat8/conf/server.xml b/base/server/tomcat8/conf/server.xml index 2f4d470be..648423903 100644 --- a/base/server/tomcat8/conf/server.xml +++ b/base/server/tomcat8/conf/server.xml @@ -80,6 +80,7 @@ Tomcat Port = [TOMCAT_SERVER_PORT] (for shutdown) <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> + <Listener className="com.netscape.cms.tomcat.PKIListener"/> <!-- Global JNDI resources Documentation at /docs/jndi-resources-howto.html @@ -95,8 +96,6 @@ Tomcat Port = [TOMCAT_SERVER_PORT] (for shutdown) pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> - <Listener className="com.netscape.cms.tomcat.NuxwdogPasswordStoreInitializer"/> - <!-- A "Service" is a collection of one or more "Connectors" that share a single "Container" Note: A "Service" is not itself a "Container", so you may not define subcomponents such as "Valves" at this level. diff --git a/base/util/src/com/netscape/cmsutil/password/IPasswordStore.java b/base/util/src/com/netscape/cmsutil/password/IPasswordStore.java index 00ec4ccdf..2bae4a5c7 100644 --- a/base/util/src/com/netscape/cmsutil/password/IPasswordStore.java +++ b/base/util/src/com/netscape/cmsutil/password/IPasswordStore.java @@ -31,4 +31,6 @@ public interface IPasswordStore { public void commit() throws IOException, ClassCastException, NullPointerException; + + public void setId(String id); } diff --git a/base/util/src/com/netscape/cmsutil/password/NuxwdogPasswordStore.java b/base/util/src/com/netscape/cmsutil/password/NuxwdogPasswordStore.java index 2a22d9ef6..6db207939 100644 --- a/base/util/src/com/netscape/cmsutil/password/NuxwdogPasswordStore.java +++ b/base/util/src/com/netscape/cmsutil/password/NuxwdogPasswordStore.java @@ -22,6 +22,7 @@ public class NuxwdogPasswordStore implements IPasswordStore { private ArrayList<String> tags = null; private final String PROMPT_PREFIX = "Please provide the password for "; + private String id; @Override public void init(String confFile) throws IOException { @@ -61,6 +62,8 @@ public class NuxwdogPasswordStore implements IPasswordStore { tags.add("hardware-" + token); } } + + id = props.getProperty("instanceId"); } private void addTag(String tag) { @@ -76,6 +79,9 @@ public class NuxwdogPasswordStore implements IPasswordStore { } String prompt = PROMPT_PREFIX + tag + ":"; + if (StringUtils.isNotEmpty(id)) { + prompt = "[" + id + "] " + prompt; + } String pwd = WatchdogClient.getPassword(prompt, iteration); if (pwd != null) { @@ -100,4 +106,8 @@ public class NuxwdogPasswordStore implements IPasswordStore { // Nothing required here } + public void setId(String id) { + this.id = id; + } + } diff --git a/base/util/src/com/netscape/cmsutil/password/PlainPasswordFile.java b/base/util/src/com/netscape/cmsutil/password/PlainPasswordFile.java index a3cd598c5..55f6db041 100644 --- a/base/util/src/com/netscape/cmsutil/password/PlainPasswordFile.java +++ b/base/util/src/com/netscape/cmsutil/password/PlainPasswordFile.java @@ -28,6 +28,7 @@ public class PlainPasswordFile implements IPasswordStore { private String mPwdPath = ""; private Properties mPwdStore; private static final String PASSWORD_WRITER_HEADER = ""; + private String id; public PlainPasswordFile() { mPwdStore = new Properties(); @@ -78,4 +79,8 @@ public class PlainPasswordFile implements IPasswordStore { } } } + + public void setId(String id) { + this.id = id; + } } |