Hi,

This patch makes sure that all edits to CS.cfg configuration file
are performed while pki-tomcatd service is stopped.

Introduces a new contextmanager stopped_service for handling
a general problem of performing a task that needs certain service
being stopped.

https://fedorahosted.org/freeipa/ticket/3804

Tomas
>From d15a580496be21cd44f36edbfaa8a6c49e540b03 Mon Sep 17 00:00:00 2001
From: Tomas Babej <tba...@redhat.com>
Date: Thu, 1 Aug 2013 14:47:52 +0200
Subject: [PATCH] Make CS.cfg edits with CA instance stopped

This patch makes sure that all edits to CS.cfg configuration file
are performed while pki-tomcatd service is stopped.

Introduces a new contextmanager stopped_service for handling
a general problem of performing a task that needs certain service
being stopped.

https://fedorahosted.org/freeipa/ticket/3804
---
 ipaserver/install/cainstance.py   | 176 +++++++++++++++++++++-----------------
 ipaserver/install/installutils.py |  32 +++++++
 2 files changed, 129 insertions(+), 79 deletions(-)

diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index ca3ee69fbce8bea512ff402b196b457cedad86c8..0ad87bd721fd8330128e33f051901ea9da8d6888 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -53,6 +53,7 @@ from ipaserver.install import service
 from ipaserver.install import installutils
 from ipaserver.install import dsinstance
 from ipaserver.install import certs
+from ipaserver.install.installutils import stopped_service
 from ipaserver.plugins import ldap2
 from ipapython.ipa_log_manager import *
 
@@ -775,13 +776,16 @@ class CAInstance(service.Service):
 
     def __disable_nonce(self):
         # Turn off Nonces
-        update_result = installutils.update_file(
-            self.dogtag_constants.CS_CFG_PATH, 'ca.enableNonces=true',
-            'ca.enableNonces=false')
-        if update_result != 0:
-            raise RuntimeError("Disabling nonces failed")
-        pent = pwd.getpwnam(PKI_USER)
-        os.chown(self.dogtag_constants.CS_CFG_PATH, pent.pw_uid, pent.pw_gid)
+        with stopped_service('pki_tomcatd',
+                        instance_name=self.dogtag_constants.PKI_INSTANCE_NAME):
+            update_result = installutils.update_file(
+                self.dogtag_constants.CS_CFG_PATH, 'ca.enableNonces=true',
+                'ca.enableNonces=false')
+            if update_result != 0:
+                raise RuntimeError("Disabling nonces failed")
+            pent = pwd.getpwnam(PKI_USER)
+            os.chown(self.dogtag_constants.CS_CFG_PATH,
+                     pent.pw_uid, pent.pw_gid)
 
     def __issue_ra_cert(self):
         # The CA certificate is in the agent DB but isn't trusted
@@ -1216,48 +1220,51 @@ class CAInstance(service.Service):
 
         publishdir = self.prepare_crl_publish_dir()
 
-        # Enable file publishing, disable LDAP
-        installutils.set_directive(caconfig, 'ca.publish.enable', 'true', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.ldappublish.enable', 'false', quotes=False, separator='=')
+        with stopped_service('pki_tomcatd',
+                        instance_name=self.dogtag_constants.PKI_INSTANCE_NAME):
 
-        # Create the file publisher, der only, not b64
-        installutils.set_directive(caconfig, 'ca.publish.publisher.impl.FileBasedPublisher.class','com.netscape.cms.publish.publishers.FileBasedPublisher', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.crlLinkExt', 'bin', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.directory', publishdir, quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.latestCrlLink', 'true', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.pluginName', 'FileBasedPublisher', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.timeStamp', 'LocalTime', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.zipCRLs', 'false', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.zipLevel', '9', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.Filename.b64', 'false', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.Filename.der', 'true', quotes=False, separator='=')
+            # Enable file publishing, disable LDAP
+            installutils.set_directive(caconfig, 'ca.publish.enable', 'true', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.ldappublish.enable', 'false', quotes=False, separator='=')
 
-        # The publishing rule
-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.enable', 'true', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.mapper', 'NoMap', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.pluginName', 'Rule', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.predicate=', '', quotes=False, separator='')
-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.publisher', 'FileBaseCRLPublisher', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.type', 'crl', quotes=False, separator='=')
+            # Create the file publisher, der only, not b64
+            installutils.set_directive(caconfig, 'ca.publish.publisher.impl.FileBasedPublisher.class','com.netscape.cms.publish.publishers.FileBasedPublisher', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.crlLinkExt', 'bin', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.directory', publishdir, quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.latestCrlLink', 'true', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.pluginName', 'FileBasedPublisher', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.timeStamp', 'LocalTime', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.zipCRLs', 'false', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.zipLevel', '9', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.Filename.b64', 'false', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.Filename.der', 'true', quotes=False, separator='=')
 
-        # Now disable LDAP publishing
-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.LdapCaCertRule.enable', 'false', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.LdapCrlRule.enable', 'false', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.LdapUserCertRule.enable', 'false', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.LdapXCertRule.enable', 'false', quotes=False, separator='=')
+            # The publishing rule
+            installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.enable', 'true', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.mapper', 'NoMap', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.pluginName', 'Rule', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.predicate=', '', quotes=False, separator='')
+            installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.publisher', 'FileBaseCRLPublisher', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.type', 'crl', quotes=False, separator='=')
 
-        # If we are the initial master then we are the CRL generator, otherwise
-        # we point to that master for CRLs.
-        if not self.clone:
-            # These next two are defaults, but I want to be explicit that the
-            # initial master is the CRL generator.
-            installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLCache', 'true', quotes=False, separator='=')
-            installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLUpdates', 'true', quotes=False, separator='=')
-            installutils.set_directive(caconfig, 'ca.listenToCloneModifications', 'true', quotes=False, separator='=')
-        else:
-            installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLCache', 'false', quotes=False, separator='=')
-            installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLUpdates', 'false', quotes=False, separator='=')
-            installutils.set_directive(caconfig, 'ca.listenToCloneModifications', 'false', quotes=False, separator='=')
+            # Now disable LDAP publishing
+            installutils.set_directive(caconfig, 'ca.publish.rule.instance.LdapCaCertRule.enable', 'false', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.rule.instance.LdapCrlRule.enable', 'false', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.rule.instance.LdapUserCertRule.enable', 'false', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.publish.rule.instance.LdapXCertRule.enable', 'false', quotes=False, separator='=')
+
+            # If we are the initial master then we are the CRL generator, otherwise
+            # we point to that master for CRLs.
+            if not self.clone:
+                # These next two are defaults, but I want to be explicit that the
+                # initial master is the CRL generator.
+                installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLCache', 'true', quotes=False, separator='=')
+                installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLUpdates', 'true', quotes=False, separator='=')
+                installutils.set_directive(caconfig, 'ca.listenToCloneModifications', 'true', quotes=False, separator='=')
+            else:
+                installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLCache', 'false', quotes=False, separator='=')
+                installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLUpdates', 'false', quotes=False, separator='=')
+                installutils.set_directive(caconfig, 'ca.listenToCloneModifications', 'false', quotes=False, separator='=')
 
     def __set_subject_in_config(self):
         # dogtag ships with an IPA-specific profile that forces a subject
@@ -1272,36 +1279,40 @@ class CAInstance(service.Service):
         """
         caconfig = dogtag.install_constants.CS_CFG_PATH
 
-        # Enable file publishing, disable LDAP
-        installutils.set_directive(caconfig,
-            'authz.instance.DirAclAuthz.ldap.ldapauth.authtype',
-            'SslClientAuth', quotes=False, separator='=')
-        installutils.set_directive(caconfig,
-            'authz.instance.DirAclAuthz.ldap.ldapauth.bindDN',
-            'uid=pkidbuser,ou=people,o=ipa-ca', quotes=False, separator='=')
-        installutils.set_directive(caconfig,
-            'authz.instance.DirAclAuthz.ldap.ldapauth.clientCertNickname',
-            'subsystemCert cert-pki-ca', quotes=False, separator='=')
-        installutils.set_directive(caconfig,
-            'authz.instance.DirAclAuthz.ldap.ldapconn.port',
-            str(dogtag.install_constants.DS_SECURE_PORT),
-            quotes=False, separator='=')
-        installutils.set_directive(caconfig,
-            'authz.instance.DirAclAuthz.ldap.ldapconn.secureConn',
-            'true', quotes=False, separator='=')
+        with stopped_service('pki_tomcatd',
+                        instance_name=self.dogtag_constants.PKI_INSTANCE_NAME):
 
-        installutils.set_directive(caconfig, 'internaldb.ldapauth.authtype',
-            'SslClientAuth', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'internaldb.ldapauth.bindDN',
-            'uid=pkidbuser,ou=people,o=ipa-ca', quotes=False, separator='=')
-        installutils.set_directive(caconfig,
-            'internaldb.ldapauth.clientCertNickname',
-            'subsystemCert cert-pki-ca', quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'internaldb.ldapconn.port',
-            str(dogtag.install_constants.DS_SECURE_PORT),
-            quotes=False, separator='=')
-        installutils.set_directive(caconfig, 'internaldb.ldapconn.secureConn',
-            'true', quotes=False, separator='=')
+            # Enable file publishing, disable LDAP
+            installutils.set_directive(caconfig,
+                'authz.instance.DirAclAuthz.ldap.ldapauth.authtype',
+                'SslClientAuth', quotes=False, separator='=')
+            installutils.set_directive(caconfig,
+                'authz.instance.DirAclAuthz.ldap.ldapauth.bindDN',
+                'uid=pkidbuser,ou=people,o=ipa-ca', quotes=False, separator='=')
+            installutils.set_directive(caconfig,
+                'authz.instance.DirAclAuthz.ldap.ldapauth.clientCertNickname',
+                'subsystemCert cert-pki-ca', quotes=False, separator='=')
+            installutils.set_directive(caconfig,
+                'authz.instance.DirAclAuthz.ldap.ldapconn.port',
+                str(dogtag.install_constants.DS_SECURE_PORT),
+                quotes=False, separator='=')
+            installutils.set_directive(caconfig,
+                'authz.instance.DirAclAuthz.ldap.ldapconn.secureConn',
+                'true', quotes=False, separator='=')
+
+            installutils.set_directive(caconfig, 'internaldb.ldapauth.authtype',
+                'SslClientAuth', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'internaldb.ldapauth.bindDN',
+                'uid=pkidbuser,ou=people,o=ipa-ca', quotes=False, separator='=')
+            installutils.set_directive(caconfig,
+                'internaldb.ldapauth.clientCertNickname',
+                'subsystemCert cert-pki-ca', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'internaldb.ldapconn.port',
+                str(dogtag.install_constants.DS_SECURE_PORT),
+                quotes=False, separator='=')
+            installutils.set_directive(caconfig,
+                 'internaldb.ldapconn.secureConn', 'true', quotes=False,
+                 separator='=')
 
     def uninstall(self):
         if self.is_configured():
@@ -1687,7 +1698,7 @@ def install_replica_ca(config, master_ds_port, postinstall=False):
 
     return ca
 
-def update_cert_config(nickname, cert):
+def update_cert_config(nickname, cert, dogtag_constants=None):
     """
     When renewing a CA subsystem certificate the configuration file
     needs to get the new certificate as well.
@@ -1695,6 +1706,10 @@ def update_cert_config(nickname, cert):
     nickname is one of the known nicknames.
     cert is a DER-encoded certificate.
     """
+
+    if dogtag_constants is None:
+        dogtag_constants = dogtag.configured_constants()
+
     # The cert directive to update per nickname
     directives = {'auditSigningCert cert-pki-ca': 'ca.audit_signing.cert',
                   'ocspSigningCert cert-pki-ca': 'ca.ocsp_signing.cert',
@@ -1702,10 +1717,13 @@ def update_cert_config(nickname, cert):
                   'subsystemCert cert-pki-ca': 'ca.subsystem.cert',
                   'Server-Cert cert-pki-ca': 'ca.sslserver.cert'}
 
-    installutils.set_directive(dogtag.configured_constants().CS_CFG_PATH,
-                                directives[nickname],
-                                base64.b64encode(cert),
-                                quotes=False, separator='=')
+    with stopped_service('pki_tomcatd',
+                         instance_name=dogtag_constants.PKI_INSTANCE_NAME):
+
+        installutils.set_directive(dogtag.configured_constants().CS_CFG_PATH,
+                                    directives[nickname],
+                                    base64.b64encode(cert),
+                                    quotes=False, separator='=')
 
 def update_people_entry(uid, dercert):
     """
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 6a6841a110b531be0c8445eaa6f861d627340d30..289728f47c798e13387cfd0233eff60c1fd94bc6 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -42,6 +42,7 @@ from ipapython import config
 from ipalib import errors
 from ipapython.dn import DN
 from ipaserver.install import certs
+from ipapython import services as ipaservices
 
 # Used to determine install status
 IPA_MODULES = [
@@ -786,3 +787,34 @@ def private_ccache(path=None):
 
     if os.path.exists(path):
         os.remove(path)
+
+
+@contextmanager
+def stopped_service(service, instance_name=""):
+    """
+    Ensure that the specified service is stopped while the commands within
+    this context are executed.
+    """
+
+    if instance_name:
+        log_instance_name = "@{instance}".format(instance=instance_name)
+    else:
+        log_instance_name = ""
+
+    root_logger.debug('Ensuring that service %s%s is not running while '
+                      'the next set of commands is being executed.', service,
+                      log_instance_name)
+
+    # Figure out if the service is running, if not, yield
+    if not ipaservices.knownservices[service].is_running(instance_name):
+        root_logger.debug('Service %s%s is not running, continue.', service,
+                          log_instance_name)
+        yield
+        return
+    else:
+        # Stop the service, do the required stuff and start it again
+        root_logger.debug('Stopping %s%s.', service, log_instance_name)
+        ipaservices.knownservices[service].stop(instance_name)
+        yield
+        root_logger.debug('Starting %s%s.', service, log_instance_name)
+        ipaservices.knownservices[service].start(instance_name)
-- 
1.8.3.1

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to