From a578cf649c0c41676677cf0a6ede03ea8d6fedb7 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Sat, 11 Oct 2014 13:18:45 -0400 Subject: Added server management library. The PKISubsystem and PKIInstance classes used by the upgrade framework have been converted into a server management library. They have been enhanced to provide the following functionalities: * starting and stopping instances * enabling and disabling subsystems * checking instance and subsystem statuses The validate() invocation has been moved out of the constructors into the upgrade framework such that these objects can be created to represent subsystems and instances that do not exist yet. https://fedorahosted.org/pki/ticket/1183 --- base/server/python/pki/server/__init__.py | 142 ++++++++++++++++++++++++++---- base/server/python/pki/server/upgrade.py | 29 +++--- 2 files changed, 143 insertions(+), 28 deletions(-) (limited to 'base/server/python') diff --git a/base/server/python/pki/server/__init__.py b/base/server/python/pki/server/__init__.py index 3eb6b5f97..3c471071f 100644 --- a/base/server/python/pki/server/__init__.py +++ b/base/server/python/pki/server/__init__.py @@ -19,41 +19,61 @@ # All rights reserved. # -import re +from lxml import etree +import grp import os +import pwd +import re +import subprocess import pki INSTANCE_BASE_DIR = '/var/lib/pki' -REGISTRY_DIR = '/etc/sysconfig/pki' -SUBSYSTEM_TYPES = ['ca', 'kra', 'ocsp', 'tks', 'tps'] +REGISTRY_DIR = '/etc/sysconfig/pki' +SUBSYSTEM_TYPES = ['ca', 'kra', 'ocsp', 'tks', 'tps'] class PKISubsystem(object): def __init__(self, instance, subsystem_name): + self.instance = instance self.name = subsystem_name self.type = instance.type + if self.type >= 10: - self.conf_dir = os.path.join( - INSTANCE_BASE_DIR, - instance.name, 'conf', subsystem_name) - self.base_dir = os.path.join( - INSTANCE_BASE_DIR, - instance.name, subsystem_name) + self.base_dir = os.path.join(self.instance.base_dir, self.name) + self.conf_dir = os.path.join(self.base_dir, 'conf') else: - self.conf_dir = os.path.join(pki.BASE_DIR, instance.name, 'conf') - self.base_dir = os.path.join(pki.BASE_DIR, instance.name) + self.base_dir = instance.base_dir + self.conf_dir = os.path.join(self.base_dir, 'conf') + + self.context_xml_template = os.path.join( + pki.SHARE_DIR, self.name, 'conf', 'Catalina', 'localhost', self.name + '.xml') - self.validate() + self.context_xml = os.path.join( + instance.conf_dir, 'Catalina', 'localhost', self.name + '.xml') + + self.doc_base = os.path.join(self.base_dir, 'webapps', self.name) + + def is_valid(self): + return os.path.exists(self.conf_dir) def validate(self): - if not os.path.exists(self.conf_dir): + if not self.is_valid(): raise pki.PKIException( 'Invalid subsystem: ' + self.__repr__(), None, self.instance) + def is_enabled(self): + return self.instance.is_deployed(self.name) + + def enable(self): + self.instance.deploy(self.name, self.context_xml_template, self.doc_base) + + def disable(self): + self.instance.undeploy(self.name) + def __repr__(self): return str(self.instance) + '/' + self.name @@ -61,22 +81,110 @@ class PKISubsystem(object): class PKIInstance(object): def __init__(self, name, instanceType=10): + self.name = name self.type = instanceType + if self.type >= 10: - self.conf_dir = os.path.join(INSTANCE_BASE_DIR, name, 'conf') self.base_dir = os.path.join(INSTANCE_BASE_DIR, name) + self.conf_dir = os.path.join(self.base_dir, 'conf') else: - self.conf_dir = os.path.join(pki.BASE_DIR, name, 'conf') self.base_dir = os.path.join(pki.BASE_DIR, name) + self.conf_dir = os.path.join(self.base_dir, 'conf') + + self.registry_file = os.path.join( + pki.server.REGISTRY_DIR, 'tomcat', self.name, self.name) - self.validate() + self.service_name = 'pki-tomcatd@%s.service' % self.name + + self.user = None + self.group = None + + def is_valid(self): + return os.path.exists(self.conf_dir) def validate(self): - if not os.path.exists(self.conf_dir): + if not self.is_valid(): raise pki.PKIException( 'Invalid instance: ' + self.__repr__(), None) + def start(self): + subprocess.check_call(['systemctl', 'start', self.service_name]) + + def stop(self): + subprocess.check_call(['systemctl', 'stop', self.service_name]) + + def is_active(self): + rc = subprocess.call(['systemctl', '--quiet', 'is-active', self.service_name]) + return rc == 0 + + def load(self): + with open(self.registry_file, 'r') as registry: + lines = registry.readlines() + + for line in lines: + + m = re.search('^PKI_USER=(.*)$', line) + if m: + self.user = m.group(1) + + m = re.search('^PKI_GROUP=(.*)$', line) + if m: + self.group = m.group(1) + + def is_deployed(self, webapp_name): + context_xml = os.path.join( + self.conf_dir, 'Catalina', 'localhost', webapp_name + '.xml') + return os.path.exists(context_xml) + + def deploy(self, webapp_name, descriptor, doc_base=None): + """ + Deploy a web application into a Tomcat instance. + + This method will copy the specified deployment descriptor into + /conf/Catalina/localhost/.xml and point the docBase + to the specified location. The web application will become available + under "/" URL path. + + See also: http://tomcat.apache.org/tomcat-7.0-doc/config/context.html + + :param webapp_name: Web application name. + :type webapp_name: str + :param descriptor: Path to deployment descriptor (context.xml). + :type descriptor: str + :param doc_base: Path to web application content. + :type doc_base: str + """ + + context_xml = os.path.join( + self.conf_dir, 'Catalina', 'localhost', webapp_name + '.xml') + + # read deployment descriptor + parser = etree.XMLParser(remove_blank_text=True) + document = etree.parse(descriptor, parser) + + if doc_base: + # customize docBase + context = document.getroot() + context.set('docBase', doc_base) + + # write deployment descriptor + with open(context_xml, 'w') as f: + f.write(etree.tostring(document, pretty_print=True)) + + # find uid and gid + uid = pwd.getpwnam(self.user).pw_uid + gid = grp.getgrnam(self.group).gr_gid + + # set deployment descriptor ownership and permission + os.chown(context_xml, uid, gid) + os.chmod(context_xml, 00660) + + def undeploy(self, webapp_name): + context_xml = os.path.join( + self.conf_dir, 'Catalina', 'localhost', webapp_name + '.xml') + os.remove(context_xml) + def __repr__(self): if self.type == 9: return "Dogtag 9 " + self.name diff --git a/base/server/python/pki/server/upgrade.py b/base/server/python/pki/server/upgrade.py index 4cae695d1..db3d968aa 100644 --- a/base/server/python/pki/server/upgrade.py +++ b/base/server/python/pki/server/upgrade.py @@ -182,8 +182,9 @@ class PKIServerUpgrader(pki.upgrade.PKIUpgrader): def instances(self): if self.instanceName and self.instanceType: - return [pki.server.PKIInstance( - self.instanceName, self.instanceType)] + instance = pki.server.PKIInstance(self.instanceName, self.instanceType) + instance.validate() + return [instance] instance_list = [] @@ -192,8 +193,9 @@ class PKIServerUpgrader(pki.upgrade.PKIUpgrader): for instanceName in os.listdir(pki.server.INSTANCE_BASE_DIR): if not self.instanceName or \ self.instanceName == instanceName: - instance_list.append( - pki.server.PKIInstance(instanceName)) + instance = pki.server.PKIInstance(instanceName) + instance.validate() + instance_list.append(instance) if not self.instanceType or self.instanceType == 9: for s in pki.server.SUBSYSTEM_TYPES: @@ -202,8 +204,9 @@ class PKIServerUpgrader(pki.upgrade.PKIUpgrader): os.path.join(pki.server.REGISTRY_DIR, s)): if not self.instanceName or \ self.instanceName == instanceName: - instance_list.append( - pki.server.PKIInstance(instanceName, 9)) + instance = pki.server.PKIInstance(instanceName, 9) + instance.validate() + instance_list.append(instance) instance_list.sort() @@ -212,7 +215,9 @@ class PKIServerUpgrader(pki.upgrade.PKIUpgrader): def subsystems(self, instance): if self.subsystemName: - return [pki.server.PKISubsystem(instance, self.subsystemName)] + subsystem = pki.server.PKISubsystem(instance, self.subsystemName) + subsystem.validate() + return [subsystem] subsystem_list = [] @@ -222,8 +227,9 @@ class PKIServerUpgrader(pki.upgrade.PKIUpgrader): instance.name) for subsystemName in os.listdir(registry_dir): if subsystemName in pki.server.SUBSYSTEM_TYPES: - subsystem_list.append( - pki.server.PKISubsystem(instance, subsystemName)) + subsystem = pki.server.PKISubsystem(instance, subsystemName) + subsystem.validate() + subsystem_list.append(subsystem) else: for subsystemName in pki.server.SUBSYSTEM_TYPES: registry_dir = os.path.join( @@ -231,8 +237,9 @@ class PKIServerUpgrader(pki.upgrade.PKIUpgrader): subsystemName, instance.name) if os.path.exists(registry_dir): - subsystem_list.append( - pki.server.PKISubsystem(instance, subsystemName)) + subsystem = pki.server.PKISubsystem(instance, subsystemName) + subsystem.validate() + subsystem_list.append(subsystem) subsystem_list.sort() -- cgit