#!/usr/bin/python3 """Wait until pki-tomcatd is up The script polls on Dogtag's HTTP port and wait until the admin interface reports status 'running' for the CA sub system. /etc/systemd/system/pki-tomcatd@pki-tomcat.service.d/ipa.conf [Service] ExecStartPost=/usr/libexec/ipa/ipa-pki-wait-running """ import os import logging import sys import time from xml.etree import ElementTree from ipalib import api from ipaplatform.paths import paths from pki.client import PKIConnection from pki.system import SystemStatusClient from requests.exceptions import ConnectionError, Timeout, RequestException logger = logging.getLogger('ipa-pki-wait-running') # check the CA subsystem. All pki-tomcatd instances in IPA have a CA SUBSYSTEM = 'ca' # time out for TCP connection attempts CONNECTION_TIMEOUT = 1.0 EXIT_SUCCESS = 0 EXIT_FAILURE = 1 if hasattr(time, 'monotonic'): curtime = time.monotonic else: curtime = time.time def check_installed(subsystem): """Check if the subsystem is configured """ catalina_base = os.environ.get( 'CATALINA_BASE', '/var/lib/pki/pki-tomcat' ) # /var/lib/pki/pki-tomcat/conf -> /etc/pki/pki-tomcat cs_cfg = os.path.join(catalina_base, 'conf', subsystem, 'CS.cfg') if os.path.isfile(cs_cfg): logger.debug("File %s exists.", cs_cfg) return True else: logger.info("File %s does not exist.", cs_cfg) return False def get_conn(hostname, subsystem): """Create a connection object """ conn = PKIConnection( hostname=hostname, subsystem=subsystem, cert_paths=paths.IPA_CA_CRT ) logger.info( "Created connection %s://%s:%s/%s", conn.protocol, conn.hostname, conn.port, conn.subsystem ) return conn def get_status(conn, timeout): """Get status from subsystem and return parsed (status, error) """ client = SystemStatusClient(conn) response = client.get_status(timeout=timeout) root = ElementTree.fromstring(response) status = root.findtext("Status") error = root.findtext("Error") logging.debug("Got status '%s', error '%s'", status, error) return status, error def main(): if not check_installed(SUBSYSTEM): logger.info( "subsystem %s is not installed, exiting", SUBSYSTEM ) sys.exit(EXIT_SUCCESS) # bootstrap ipalib.api to parse config file api.bootstrap(confdir=paths.ETC_IPA, log=None) timeout = api.env.startup_timeout conn = get_conn(api.env.host, subsystem=SUBSYSTEM) end = curtime() + timeout while curtime() < end: try: status, error = get_status(conn, CONNECTION_TIMEOUT) except (ConnectionError, Timeout) as e: logger.info("Connection failed: %s", e) except RequestException as e: logger.error("Request failed unexpectedly, %s ", e) else: if status == 'running': logger.info("Success, subsystem %s is running!", SUBSYSTEM) sys.exit(EXIT_SUCCESS) elif error is not None: logger.info( "Subsystem %s failed with error '%s', giving up!", SUBSYSTEM, error ) sys.exit(EXIT_FAILURE) else: logger.info("Status is '%s', waiting...", status) # wait and try again time.sleep(1) # giving up logger.error( "Reached end of wait timeout %s, giving up", timeout ) sys.exit(EXIT_FAILURE) if __name__ == '__main__': logging.basicConfig( format='%(name)s: %(message)s', level=logging.INFO ) main()