From dd566ed3c64a69801a9edf3b27f11077aa40ecef Mon Sep 17 00:00:00 2001 From: Matthew Harmsen Date: Mon, 23 Apr 2012 13:39:04 -0700 Subject: PKI Deployment Scriptlets * Completed the following six 'scriptlets': * Dogtag 10: Python 'initialization.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/147) * Dogtag 10: Python 'instance_layout.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/75) * Dogtag 10: Python 'webserver_layout.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/140) * Dogtag 10: Python 'subsystem_layout.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/141) * Dogtag 10: Python 'war_explosion.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/76) * Dogtag 10: Python 'finalization.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/148) * Created numerous PKI deployment helper utilities. * Augmented logging to provide indentation. * Generated logic for installation 'manifest'. * Tested logic using '--dry_run' option and '-p' prefix options. * Per initial review, removed numerous "constants" and consolidated logic into "master" dictionary. * Corrected the following ticket: * Dogtag 10: Fix 'build_dogtag_pki' script to account for 'pki-deploy' RPM (https://fedorahosted.org/pki/ticket/138) Resolves Bugzilla Bug #810047 - build_dogtag_pki fails with requirements for pki-deploy (https://bugzilla.redhat.com/show_bug.cgi?id=810047) * Created the following three 'scriptlets' as 'NOT YET IMPLEMENTED' place-holders: * Dogtag 10: Python 'security_databases.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/136) * Dogtag 10: Python 'slot_assignment.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/146) * Dogtag 10: Python 'configuration.py' Configuration Scriptlet (https://fedorahosted.org/pki/ticket/137) --- base/deploy/src/scriptlets/pkihelper.py | 1195 ++++++++++++++++++++++++++----- 1 file changed, 1004 insertions(+), 191 deletions(-) (limited to 'base/deploy/src/scriptlets/pkihelper.py') diff --git a/base/deploy/src/scriptlets/pkihelper.py b/base/deploy/src/scriptlets/pkihelper.py index ee2bdd249..95b5bf0a7 100644 --- a/base/deploy/src/scriptlets/pkihelper.py +++ b/base/deploy/src/scriptlets/pkihelper.py @@ -15,208 +15,1021 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -# Copyright (C) 2011 Red Hat, Inc. +# Copyright (C) 2012 Red Hat, Inc. # All rights reserved. # # System Imports -import ConfigParser -import argparse -import logging +import errno +import sys import os +import shutil +from grp import getgrnam +from pwd import getpwnam +import zipfile # PKI Deployment Imports import pkiconfig as config +from pkiconfig import pki_master_dict as master +import pkimanifest as manifest import pkimessages as log -# PKI Deployment Helper Functions -def process_command_line_arguments(argv): - "Read and process command-line options" - description = None - if os.path.basename(argv[0]) == 'pkispawn': - description = 'PKI Instance Installation and Configuration' - elif os.path.basename(argv[0]) == 'pkidestroy': - description = 'PKI Instance Removal' - parser = argparse.ArgumentParser( - description=description, - add_help=False, - formatter_class=argparse.RawDescriptionHelpFormatter, - epilog=config.PKI_DEPLOYMENT_VERBOSITY) - mandatory = parser.add_argument_group('mandatory arguments') - mandatory.add_argument('-s', - dest='pki_subsystem', action='store', - nargs=1, choices=config.PKI_SUBSYSTEMS, - required=True, metavar='', - help='where is ' - 'CA, KRA, OCSP, RA, TKS, or TPS') - optional = parser.add_argument_group('optional arguments') - optional.add_argument('--dry_run', - dest='pki_dry_run_flag', action='store_true', - help='do not actually perform any actions') - optional.add_argument('-f', - dest='pkideployment_cfg', action='store', - nargs=1, metavar='', - help='overrides default configuration filename') - optional.add_argument('-h', '--help', - dest='help', action='help', - help='show this help message and exit') - optional.add_argument('-p', - dest='pki_root_prefix', action='store', - nargs=1, metavar='', - help='directory prefix to specify local directory') - if os.path.basename(argv[0]) == 'pkispawn': - optional.add_argument('-u', - dest='pki_update_flag', action='store_true', - help='update instance of specified subsystem') - optional.add_argument('-v', - dest='pki_verbosity', action='count', - help='display verbose information (details below)') - custom = parser.add_argument_group('custom arguments ' - '(OVERRIDES configuration file values)') - custom.add_argument('-i', - dest='pki_instance_name', action='store', - nargs=1, metavar='', - help='PKI instance name (MUST specify REQUIRED ports)') - custom.add_argument('--http_port', - dest='pki_http_port', action='store', - nargs=1, metavar='', - help='HTTP port (CA, KRA, OCSP, RA, TKS, TPS)') - custom.add_argument('--https_port', - dest='pki_https_port', action='store', - nargs=1, metavar='', - help='HTTPS port (CA, KRA, OCSP, RA, TKS, TPS)') - custom.add_argument('--ajp_port', - dest='pki_ajp_port', action='store', - nargs=1, metavar='', - help='AJP port (CA, KRA, OCSP, TKS)') - args = parser.parse_args() - - config.pki_subsystem = str(args.pki_subsystem).strip('[\']') - if args.pki_dry_run_flag: - config.pki_dry_run_flag = args.pki_dry_run_flag - if not args.pkideployment_cfg is None: - config.pkideployment_cfg = str(args.pkideployment_cfg).strip('[\']') - if not os.path.exists(config.pkideployment_cfg) or\ - not os.path.isfile(config.pkideployment_cfg): - print "ERROR: " +\ - log.PKI_FILE_MISSING_OR_NOT_A_FILE_1 %\ - config.pkideployment_cfg - print - parser.print_help() - parser.exit(-1); - if not args.pki_root_prefix is None: - config.pki_root_prefix = str(args.pki_root_prefix).strip('[\']') - if config.pki_root_prefix is None or\ - len(config.pki_root_prefix) == 0: - config.pki_root_prefix = "" - elif not os.path.exists(config.pki_root_prefix) or\ - not os.path.isdir(config.pki_root_prefix): - print "ERROR: " +\ - log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 %\ - config.pki_root_prefix - print - parser.print_help() - parser.exit(-1); - if os.path.basename(argv[0]) == 'pkispawn': - if args.pki_update_flag: - config.pki_update_flag = args.pki_update_flag - if args.pki_verbosity == 1: - config.pki_console_log_level = logging.INFO - config.pki_log_level = logging.INFO - elif args.pki_verbosity == 2: - config.pki_console_log_level = logging.INFO - config.pki_log_level = logging.DEBUG - elif args.pki_verbosity == 3: - config.pki_console_log_level = logging.DEBUG - config.pki_log_level = logging.DEBUG - elif args.pki_verbosity > 3: - print "ERROR: " + log.PKI_VERBOSITY_LEVELS_MESSAGE - print - parser.print_help() - parser.exit(-1); - if not args.pki_instance_name is None: - config.pki_instance_name = str(args.pki_instance_name).strip('[\']') - if not args.pki_http_port is None: - config.pki_http_port = str(args.pki_http_port).strip('[\']') - if not args.pki_https_port is None: - config.pki_https_port = str(args.pki_https_port).strip('[\']') - if not args.pki_ajp_port is None: - if config.pki_subsystem in config.PKI_TOMCAT_SUBSYSTEMS: - config.pki_ajp_port = str(args.pki_ajp_port).strip('[\']') - else: - print "ERROR: " +\ - log.PKI_CUSTOM_TOMCAT_AJP_PORT_1 %\ - config.pki_subsystem - print - parser.print_help() - parser.exit(-1); - if not args.pki_instance_name is None or\ - not args.pki_http_port is None or\ - not args.pki_https_port is None or\ - not args.pki_ajp_port is None: - if config.pki_subsystem in config.PKI_APACHE_SUBSYSTEMS: - if args.pki_instance_name is None or\ - args.pki_http_port is None or\ - args.pki_https_port is None: - print "ERROR: " + log.PKI_CUSTOM_APACHE_INSTANCE_1 %\ - config.pki_subsystem - print - parser.print_help() - parser.exit(-1); - elif config.pki_subsystem in config.PKI_TOMCAT_SUBSYSTEMS: - if args.pki_instance_name is None or\ - args.pki_http_port is None or\ - args.pki_https_port is None or\ - args.pki_ajp_port is None: - print "ERROR: " + log.PKI_CUSTOM_TOMCAT_INSTANCE_1 %\ - config.pki_subsystem - print - parser.print_help() - parser.exit(-1); - - -def read_pki_configuration_file(): - "Read configuration file sections into dictionaries" - rv = 0 +# PKI Deployment Functions +def pki_copytree(src, dst, symlinks=False, ignore=None): + """Recursively copy a directory tree using copy2(). + + PATCH: This code was copied from 'shutil.py' and patched to + allow 'The destination directory to already exist.' + + If exception(s) occur, an Error is raised with a list of reasons. + + If the optional symlinks flag is true, symbolic links in the + source tree result in symbolic links in the destination tree; if + it is false, the contents of the files pointed to by symbolic + links are copied. + + The optional ignore argument is a callable. If given, it + is called with the `src` parameter, which is the directory + being visited by pki_copytree(), and `names` which is the list of + `src` contents, as returned by os.listdir(): + + callable(src, names) -> ignored_names + + Since pki_copytree() is called recursively, the callable will be + called once for each directory that is copied. It returns a + list of names relative to the `src` directory that should + not be copied. + + XXX Consider this example code rather than the ultimate tool. + + """ + names = os.listdir(src) + if ignore is not None: + ignored_names = ignore(src, names) + else: + ignored_names = set() + + # PATCH: ONLY execute 'os.makedirs(dst)' if the top-level + # destination directory does NOT exist! + if not os.path.exists(dst): + os.makedirs(dst) + errors = [] + for name in names: + if name in ignored_names: + continue + srcname = os.path.join(src, name) + dstname = os.path.join(dst, name) + try: + if symlinks and os.path.islink(srcname): + linkto = os.readlink(srcname) + os.symlink(linkto, dstname) + elif os.path.isdir(srcname): + pki_copytree(srcname, dstname, symlinks, ignore) + else: + # Will raise a SpecialFileError for unsupported file types + shutil.copy2(srcname, dstname) + # catch the Error from the recursive pki_copytree so that we can + # continue with other files + except Error, err: + errors.extend(err.args[0]) + except EnvironmentError, why: + errors.append((srcname, dstname, str(why))) try: - parser = ConfigParser.ConfigParser() - parser.read(config.pkideployment_cfg) - config.pki_common_dict = dict(parser._sections['Common']) - if config.pki_subsystem == "CA": - config.pki_web_server_dict = dict(parser._sections['Tomcat']) - config.pki_subsystem_dict = dict(parser._sections['CA']) - elif config.pki_subsystem == "KRA": - config.pki_web_server_dict = dict(parser._sections['Tomcat']) - config.pki_subsystem_dict = dict(parser._sections['KRA']) - elif config.pki_subsystem == "OCSP": - config.pki_web_server_dict = dict(parser._sections['Tomcat']) - config.pki_subsystem_dict = dict(parser._sections['OCSP']) - elif config.pki_subsystem == "RA": - config.pki_web_server_dict = dict(parser._sections['Apache']) - config.pki_subsystem_dict = dict(parser._sections['RA']) - elif config.pki_subsystem == "TKS": - config.pki_web_server_dict = dict(parser._sections['Tomcat']) - config.pki_subsystem_dict = dict(parser._sections['TKS']) - elif config.pki_subsystem == "TPS": - config.pki_web_server_dict = dict(parser._sections['Apache']) - config.pki_subsystem_dict = dict(parser._sections['TPS']) - # Insert empty record into dictionaries for "pretty print" statements - config.pki_common_dict[0] = None - config.pki_web_server_dict[0] = None - config.pki_subsystem_dict[0] = None - except ConfigParser.ParsingError, err: - rv = err - return rv - - -def create_pki_master_dictionary(): - "Create a single master PKI dictionary from the sectional dictionaries" - config.pki_master_dict = dict() - config.pki_master_dict.update(config.pki_common_dict) - config.pki_master_dict.update(config.pki_web_server_dict) - config.pki_master_dict.update(config.pki_subsystem_dict) - config.pki_master_dict.update(__name__="PKI Master Dictionary") - return + shutil.copystat(src, dst) + except OSError, why: + if WindowsError is not None and isinstance(why, WindowsError): + # Copying file access times may fail on Windows + pass + else: + errors.extend((src, dst, str(why))) + if errors: + raise Error, errors + + +# PKI Deployment Identity Class +class identity: + def get_uid(self, critical_failure=True): + try: + pki_uid = master['pki_uid'] + except KeyError as exc: + config.pki_log.error(log.PKI_KEYERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return pki_uid + + def get_gid(self, critical_failure=True): + try: + pki_gid = master['pki_gid'] + except KeyError as exc: + config.pki_log.error(log.PKI_KEYERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return pki_gid + + def set_uid(self, name, critical_failure=True): + try: + config.pki_log.debug(log.PKIHELPER_USER_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + # id -u + pki_uid = getpwnam(name)[2] + master['pki_uid']=pki_uid + config.pki_log.debug(log.PKIHELPER_UID_2, name, pki_uid, + extra=config.PKI_INDENTATION_LEVEL_3) + except KeyError as exc: + config.pki_log.error(log.PKI_KEYERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return pki_uid + + def set_gid(self, name, critical_failure=True): + try: + config.pki_log.debug(log.PKIHELPER_GROUP_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + # id -g + pki_gid = getgrnam(name)[2] + master['pki_gid']=pki_gid + config.pki_log.debug(log.PKIHELPER_GID_2, name, pki_gid, + extra=config.PKI_INDENTATION_LEVEL_3) + except KeyError as exc: + config.pki_log.error(log.PKI_KEYERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return pki_gid + + +# PKI Deployment Instance Class +class instance: + def apache_instances(self, name): + rv = 0 + try: + if not os.path.exists(name) or not os.path.isdir(name): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # count number of PKI subsystems present + # within the specfied Apache instance + for subsystem in config.PKI_APACHE_SUBSYSTEMS: + path = name + "/" + subsystem.lower() + if os.path.exists(path) and os.path.isdir(path): + rv = rv + 1 + # always display correct information (even during dry_run) + if config.pki_dry_run_flag and rv > 0: + config.pki_log.debug(log.PKIHELPER_APACHE_INSTANCES_2, + name, rv - 1, + extra=config.PKI_INDENTATION_LEVEL_2) + else: + config.pki_log.debug(log.PKIHELPER_APACHE_INSTANCES_2, name, + rv, extra=config.PKI_INDENTATION_LEVEL_2) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + return rv + + def pki_subsystem_instances(self, name): + rv = 0 + try: + if not os.path.exists(name) or not os.path.isdir(name): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # count total number of PKI subsystems present + # within the specfied PKI instance + for subsystem in config.PKI_SUBSYSTEMS: + path = name + "/" + subsystem.lower() + if os.path.exists(path) and os.path.isdir(path): + rv = rv + 1 + # always display correct information (even during dry_run) + if config.pki_dry_run_flag and rv > 0: + config.pki_log.debug(log.PKIHELPER_PKI_SUBSYSTEM_INSTANCES_2, + name, rv - 1, + extra=config.PKI_INDENTATION_LEVEL_2) + else: + config.pki_log.debug(log.PKIHELPER_PKI_SUBSYSTEM_INSTANCES_2, + name, rv, + extra=config.PKI_INDENTATION_LEVEL_2) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + return rv + + def tomcat_instances(self, name): + rv = 0 + try: + if not os.path.exists(name) or not os.path.isdir(name): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # count number of PKI subsystems present + # within the specfied Tomcat instance + for subsystem in config.PKI_TOMCAT_SUBSYSTEMS: + path = name + "/" + subsystem.lower() + if os.path.exists(path) and os.path.isdir(path): + rv = rv + 1 + # always display correct information (even during dry_run) + if config.pki_dry_run_flag and rv > 0: + config.pki_log.debug(log.PKIHELPER_TOMCAT_INSTANCES_2, + name, rv - 1, + extra=config.PKI_INDENTATION_LEVEL_2) + else: + config.pki_log.debug(log.PKIHELPER_TOMCAT_INSTANCES_2, name, + rv, extra=config.PKI_INDENTATION_LEVEL_2) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + return rv + + +# PKI Deployment Directory Class +class directory: + def create(self, name, uid=None, gid=None, + perms=config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS, + acls=None, critical_failure=True): + try: + if not os.path.exists(name): + # mkdir -p + config.pki_log.info(log.PKIHELPER_MKDIR_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + os.makedirs(name) + # chmod + config.pki_log.debug(log.PKIHELPER_CHMOD_2, perms, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chmod(name, perms) + # chown : + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chown(name, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_DIRECTORY + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = perms + record.acls = acls + manifest.database.append(record) + elif not os.path.isdir(name): + config.pki_log.error( + log.PKI_DIRECTORY_ALREADY_EXISTS_NOT_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + else: + config.pki_log.error(log.PKI_DIRECTORY_ALREADY_EXISTS_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + if exc.errno == errno.EEXIST: + pass + else: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def modify(self, name, uid=None, gid=None, + perms=config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS, + acls=None, silent=False, critical_failure=True): + try: + if os.path.exists(name): + if not os.path.isdir(name): + config.pki_log.error( + log.PKI_DIRECTORY_ALREADY_EXISTS_NOT_A_DIRECTORY_1, + name, extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + # Always re-process each directory whether it needs it or not + if not silent: + config.pki_log.info(log.PKIHELPER_MODIFY_DIR_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + # chmod + if not silent: + config.pki_log.debug(log.PKIHELPER_CHMOD_2, perms, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chmod(name, perms) + # chown : + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + if not silent: + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chown(name, uid, gid) + # Store record in installation manifest + if not silent: + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_DIRECTORY + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = perms + record.acls = acls + manifest.database.append(record) + else: + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def delete(self, name, recursive_flag=True, critical_failure=True): + try: + if not os.path.exists(name) or not os.path.isdir(name): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + else: + if recursive_flag == True: + # rm -rf + config.pki_log.info(log.PKIHELPER_RM_RF_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + shutil.rmtree(name) + else: + # rmdir + config.pki_log.info(log.PKIHELPER_RMDIR_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + os.rmdir(name) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def is_empty(self, name): + try: + if not os.listdir(name): + config.pki_log.debug(log.PKIHELPER_DIRECTORY_IS_NOT_EMPTY_1, + name, extra=config.PKI_INDENTATION_LEVEL_2) + return False + else: + config.pki_log.debug(log.PKIHELPER_DIRECTORY_IS_EMPTY_1, + name, extra=config.PKI_INDENTATION_LEVEL_2) + return True + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + + def set_mode(self, name, uid=None, gid=None, + dir_perms=config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS, + file_perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS, + symlink_perms=\ + config.PKI_DEPLOYMENT_DEFAULT_SYMLINK_PERMISSIONS, + dir_acls=None, file_acls=None, symlink_acls=None, + recursive_flag=True, critical_failure=True): + try: + if config.pki_dry_run_flag: + config.pki_log.info( + log.PKIHELPER_SET_MODE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + elif not os.path.exists(name) or not os.path.isdir(name): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + else: + config.pki_log.info( + log.PKIHELPER_SET_MODE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + if recursive_flag == True: + for root, dirs, files in os.walk(name): + for name in files: + if not os.path.islink(name): + file = os.path.join(root, name) + config.pki_log.debug( + log.PKIHELPER_IS_A_FILE_1, file, + extra=config.PKI_INDENTATION_LEVEL_3) + # chmod + config.pki_log.debug(log.PKIHELPER_CHMOD_2, + file_perms, file, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chmod(file, file_perms) + # chown : + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, file, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chown(file, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_FILE + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = file_perms + record.acls = file_acls + manifest.database.append(record) + else: + symlink = os.path.join(root, name) + config.pki_log.debug( + log.PKIHELPER_IS_A_SYMLINK_1, symlink, + extra=config.PKI_INDENTATION_LEVEL_3) + # REMINDER: Due to POSIX compliance, 'lchmod' + # is NEVER implemented on Linux + # systems since 'chmod' CANNOT be + # run directly against symbolic + # links! + # chown -h : + config.pki_log.debug(log.PKIHELPER_CHOWN_H_3, + uid, gid, link, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.lchown(link, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_SYMLINK + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = symlink_perms + record.acls = symlink_acls + manifest.database.append(record) + for name in dirs: + dir = os.path.join(root, name) + config.pki_log.debug( + log.PKIHELPER_IS_A_DIRECTORY_1, dir, + extra=config.PKI_INDENTATION_LEVEL_3) + # chmod + config.pki_log.debug(log.PKIHELPER_CHMOD_2, + dir_perms, dir, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chmod(dir, dir_perms) + # chown : + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, dir, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chown(dir, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_DIRECTORY + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = dir_perms + record.acls = dir_acls + manifest.database.append(record) + else: + config.pki_log.debug( + log.PKIHELPER_IS_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_3) + name = os.path.join(root, name) + # chmod + config.pki_log.debug(log.PKIHELPER_CHMOD_2, + dir_perms, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chmod(name, dir_perms) + # chown : + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chown(name, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_DIRECTORY + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = dir_perms + record.acls = dir_acls + manifest.database.append(record) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + + def copy(self, old_name, new_name, uid=None, gid=None, + dir_perms=config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS, + file_perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS, + symlink_perms=config.PKI_DEPLOYMENT_DEFAULT_SYMLINK_PERMISSIONS, + dir_acls=None, file_acls=None, symlink_acls=None, + recursive_flag=True, overwrite_flag=False, critical_failure=True): + try: + if not os.path.exists(old_name) or not os.path.isdir(old_name): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, old_name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + elif config.pki_dry_run_flag: + if recursive_flag == True: + # cp -rp + config.pki_log.info(log.PKIHELPER_CP_RP_2, + old_name, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + else: + # cp -p + config.pki_log.info(log.PKIHELPER_CP_P_2, + old_name, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + config.pki_log.info( + log.PKIHELPER_SET_MODE_1, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + else: + if os.path.exists(new_name): + if not overwrite_flag: + config.pki_log.error( + log.PKI_DIRECTORY_ALREADY_EXISTS_1, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + if recursive_flag == True: + # cp -rp + config.pki_log.info(log.PKIHELPER_CP_RP_2, + old_name, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + # Due to a limitation in the 'shutil.copytree()' + # implementation which requires that + # 'The destination directory must not already exist.', + # an OSError exception is always thrown due to the + # implementation's unchecked call to 'os.makedirs(dst)'. + # Consequently, a 'patched' local copy of this routine has + # been included in this file with the appropriate fix. + pki_copytree(old_name, new_name) + else: + # cp -p + config.pki_log.info(log.PKIHELPER_CP_P_2, + old_name, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + shutil.copy2(old_name, new_name) + # set ownerships, permissions, and acls + # of newly created top-level directory + self.modify(new_name, uid, gid, dir_perms, dir_acls, + True, critical_failure) + # set ownerships, permissions, and acls + # of contents of newly created top-level directory + self.set_mode(new_name, uid, gid, + dir_perms, file_perms, symlink_perms, + dir_acls, file_acls, symlink_acls, + recursive_flag, critical_failure) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except shutil.Error as exc: + config.pki_log.error(log.PKI_SHUTIL_ERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + +# PKI Deployment File Class (also used for executables) +class file: + def create(self, name, uid=None, gid=None, + perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS, + acls=None, critical_failure=True): + try: + if not os.path.exists(name): + # touch + config.pki_log.info(log.PKIHELPER_TOUCH_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + open(name, "w").close() + # chmod + config.pki_log.debug(log.PKIHELPER_CHMOD_2, perms, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chmod(name, perms) + # chown : + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chown(name, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_FILE + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = perms + record.acls = acls + manifest.database.append(record) + elif not os.path.isfile(name): + config.pki_log.error( + log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + else: + config.pki_log.error(log.PKI_FILE_ALREADY_EXISTS_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + if exc.errno == errno.EEXIST: + pass + else: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def modify(self, name, uid=None, gid=None, + perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS, + acls=None, silent=False, critical_failure=True): + try: + if os.path.exists(name): + if not os.path.isfile(name): + config.pki_log.error( + log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1, + name, extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + # Always re-process each file whether it needs it or not + if not silent: + config.pki_log.info(log.PKIHELPER_MODIFY_FILE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + # chmod + if not silent: + config.pki_log.debug(log.PKIHELPER_CHMOD_2, perms, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chmod(name, perms) + # chown : + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + if not silent: + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chown(name, uid, gid) + # Store record in installation manifest + if not silent: + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_FILE + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = perms + record.acls = acls + manifest.database.append(record) + else: + config.pki_log.error( + log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def delete(self, name, critical_failure=True): + try: + if not os.path.exists(name) or not os.path.isfile(name): + config.pki_log.error( + log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + else: + # rm -f + config.pki_log.info(log.PKIHELPER_RM_F_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + os.remove(name) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def copy(self, old_name, new_name, uid=None, gid=None, + perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS, acls=None, + overwrite_flag=False, critical_failure=True): + try: + if not os.path.exists(old_name) or not os.path.isfile(old_name): + config.pki_log.error( + log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, old_name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + elif config.pki_dry_run_flag: + # cp -p + config.pki_log.info(log.PKIHELPER_CP_P_2, + old_name, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + # chmod + config.pki_log.debug(log.PKIHELPER_CHMOD_2, + perms, new_name, + extra=config.PKI_INDENTATION_LEVEL_3) + # chown : + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, new_name, + extra=config.PKI_INDENTATION_LEVEL_3) + else: + if os.path.exists(new_name): + if not overwrite_flag: + config.pki_log.error( + log.PKI_FILE_ALREADY_EXISTS_1, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # cp -p + config.pki_log.info(log.PKIHELPER_CP_P_2, + old_name, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + shutil.copy2(old_name, new_name) + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + # chmod + config.pki_log.debug(log.PKIHELPER_CHMOD_2, + perms, new_name, + extra=config.PKI_INDENTATION_LEVEL_3) + os.chmod(new_name, perms) + # chown : + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, new_name, + extra=config.PKI_INDENTATION_LEVEL_3) + os.chown(new_name, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = new_name + record.type = manifest.RECORD_TYPE_FILE + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = perms + record.acls = acls + manifest.database.append(record) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except shutil.Error as exc: + config.pki_log.error(log.PKI_SHUTIL_ERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + +# PKI Deployment Symbolic Link Class +class symlink: + def create(self, name, link, uid=None, gid=None, + acls=None, allow_dangling_symlink=False, critical_failure=True): + try: + if not os.path.exists(link): + if not config.pki_dry_run_flag: + if not os.path.exists(name): + config.pki_log.warning( + log.PKIHELPER_DANGLING_SYMLINK_2, link, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if not allow_dangling_symlink: + sys.exit(1) + # ln -s + config.pki_log.info(log.PKIHELPER_LINK_S_2, name, link, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + os.symlink(name, link) + # REMINDER: Due to POSIX compliance, 'lchmod' is NEVER + # implemented on Linux systems since 'chmod' + # CANNOT be run directly against symbolic links! + # chown -h : + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + config.pki_log.debug(log.PKIHELPER_CHOWN_H_3, + uid, gid, link, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.lchown(link, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = link + record.type = manifest.RECORD_TYPE_SYMLINK + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions =\ + config.PKI_DEPLOYMENT_DEFAULT_SYMLINK_PERMISSIONS + record.acls = acls + manifest.database.append(record) + elif not os.path.islink(link): + config.pki_log.error( + log.PKI_SYMLINK_ALREADY_EXISTS_NOT_A_SYMLINK_1, link, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + else: + config.pki_log.error(log.PKI_SYMLINK_ALREADY_EXISTS_1, link, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + if exc.errno == errno.EEXIST: + pass + else: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def modify(self, link, uid=None, gid=None, + acls=None, silent=False, critical_failure=True): + try: + if os.path.exists(link): + if not os.path.islink(link): + config.pki_log.error( + log.PKI_SYMLINK_ALREADY_EXISTS_NOT_A_SYMLINK_1, + link, extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + # Always re-process each link whether it needs it or not + if not silent: + config.pki_log.info(log.PKIHELPER_MODIFY_SYMLINK_1, link, + extra=config.PKI_INDENTATION_LEVEL_2) + # REMINDER: Due to POSIX compliance, 'lchmod' is NEVER + # implemented on Linux systems since 'chmod' + # CANNOT be run directly against symbolic links! + # chown -h : + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + if not silent: + config.pki_log.debug(log.PKIHELPER_CHOWN_H_3, + uid, gid, link, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.lchown(link, uid, gid) + # Store record in installation manifest + if not silent: + record = manifest.record() + record.name = link + record.type = manifest.RECORD_TYPE_SYMLINK + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions =\ + config.PKI_DEPLOYMENT_DEFAULT_SYMLINK_PERMISSIONS + record.acls = acls + manifest.database.append(record) + else: + config.pki_log.error( + log.PKI_SYMLINK_MISSING_OR_NOT_A_SYMLINK_1, link, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def delete(self, link, critical_failure=True): + try: + if not os.path.exists(link) or not os.path.islink(link): + config.pki_log.error( + log.PKI_SYMLINK_MISSING_OR_NOT_A_SYMLINK_1, link, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + else: + # rm -f + config.pki_log.info(log.PKIHELPER_RM_F_1, link, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + os.remove(link) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + +# PKI Deployment War File Class +class war: + def explode(self, name, path, critical_failure=True): + try: + if os.path.exists(name) and os.path.isfile(name): + if not zipfile.is_zipfile(name): + config.pki_log.error( + log.PKI_FILE_NOT_A_WAR_FILE_1, + name, extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + if not config.pki_dry_run_flag: + if not os.path.exists(path) or not os.path.isdir(path): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, + path, extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + # jar -xf -C + config.pki_log.info(log.PKIHELPER_JAR_XF_C_2, name, path, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + # Open war file + war = zipfile.ZipFile(name, 'r') + # Extract contents of war file to path + war.extractall(path) + else: + config.pki_log.error( + log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except zipfile.BadZipfile as exc: + config.pki_log.error(log.PKI_BADZIPFILE_ERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except zipfile.LargeZipFile as exc: + config.pki_log.error(log.PKI_LARGEZIPFILE_ERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + +# PKI Deployment Helper Class Instances +identity = identity() +instance = instance() +directory = directory() +file = file() +symlink = symlink() +war = war() -- cgit