#!/usr/bin/python3 import os import sys import time import subprocess OCF_SUCCESS = 0 OCF_ERR_GENERIC = 1 OCF_NOT_RUNNING = 7 action = sys.argv[1] instance_root = os.getenv('OCF_RESKEY_instance_root') or '' instance_root_b = instance_root.encode('utf8') part_id = os.getenv('OCF_RESKEY_part_id') slappart = 'slappart%s' % part_id slappart_b = slappart.encode('utf8') slapuser = 'slapuser%s' % part_id service_list = [] services_text = os.getenv('OCF_RESKEY_services', None) if services_text: service_list = services_text.split(',') #kumofs_gateway,kumofs_manager,kumofs_server,mariadb,zeo,zope,haproxy def splitLine(line): return [item for item in line.split(b' ') if item] def runCommand(*args): return subprocess.run(args, capture_output=True) def runSlapOS(*args): return runCommand('slapos', *args) def checkTheiaStatus(target_status): completed_process = runSlapOS('node') for line in completed_process.stdout.split(b'\n'): if line.startswith(slappart_b): split_line = splitLine(line) if (split_line[0].startswith(slappart_b + b':theia-instance') and split_line[1].decode('utf8') == target_status): return True return False def isTheiaRunning(): return checkTheiaStatus('RUNNING') def isTheiaStopped(): return checkTheiaStatus('STOPPED') def runSlapOSInTheia(*args): return runCommand('sudo', '-u', slapuser, '%s/%s/srv/runner/bin/slapos' % (instance_root, slappart), *args) def checkAppStatus(target_status): completed_process = runSlapOSInTheia('node') if completed_process.stdout == b'unix://%s/%s/srv/runner/instance/sv.sock no such file\n' % (instance_root_b, slappart_b): if target_status == 'STOPPED': return True else: return False error_list = [] service_status_dict = {} for service in service_list: service_status_dict[service] = [] for line in completed_process.stdout.split(b'\n'): if not line: continue split_line = splitLine(line) if split_line[0].decode('utf8') == 'watchdog': continue service_name = split_line[0].split(b':')[1].split(b'-')[0].decode('utf8') current_status = split_line[1].decode('utf8') if service_name in service_status_dict: service_status_dict[service_name].append(current_status) if current_status != target_status: error_list.append(line) if error_list: return False for service in service_status_dict: if set(service_status_dict[service]) != set([target_status]): return False return True def isAppRunning(): return checkAppStatus('RUNNING') def isAppStopped(): return checkAppStatus('STOPPED') def monitor(): result = OCF_ERR_GENERIC if not os.path.exists(instance_root): result = OCF_NOT_RUNNING try: if isTheiaRunning() and isAppRunning(): result = OCF_SUCCESS elif isTheiaStopped() and isAppStopped(): result = OCF_NOT_RUNNING except: pass sys.exit(result) def start(): result = OCF_ERR_GENERIC try: while not isTheiaRunning(): runSlapOS('node', 'start', slappart + ':*') time.sleep(3) while not isAppRunning(): runSlapOSInTheia('node', 'start', 'all') time.sleep(3) result = OCF_SUCCESS except: pass sys.exit(result) def stop(): result = OCF_ERR_GENERIC try: while not isAppStopped(): runSlapOSInTheia('node', 'stop', 'all') time.sleep(3) while not isTheiaStopped(): runSlapOS('node', 'stop', slappart + ':*') time.sleep(3) result = OCF_SUCCESS except: pass sys.exit(result) def metadata(): print ('''\ 1.0 This is the resource agent for SlapOS Theia. Manages SlapOS Theia instance Instance Root Directory Path Instance Root Computer Partition ID, slappartX Partition ID Service names separated by comma Service names ''') sys.exit(OCF_SUCCESS) if action == 'monitor': monitor() elif action == 'start': start() elif action == 'stop': stop() elif action == 'meta-data': metadata()