from xml_marshaller import xml_marshaller import os import signal import slapos.slap import socket import subprocess import sys import time process_group_pid_list = [] process_pid_file_list = [] process_command_list = [] def sigterm_handler(signal, frame): for pgpid in process_group_pid_list: try: os.killpg(pgpid, signal.SIGTERM) except: pass for pid_file in process_pid_file_list: try: os.kill(int(open(pid_file).read().strip()), signal.SIGTERM) except: pass for p in process_command_list: try: subprocess.call(p) except: pass sys.exit(1) signal.signal(signal.SIGTERM, sigterm_handler) def run(args): config = args[0] for k,v in config['environment'].iteritems(): os.environ[k] = v proxy = None slapgrid = None supervisord_pid_file = os.path.join(config['instance_root'], 'var', 'run', 'supervisord.pid') if os.path.exists(config['proxy_database']): os.unlink(config['proxy_database']) try: proxy = subprocess.Popen([config['slapproxy_binary'], config['slapos_config']], close_fds=True, preexec_fn=os.setsid) process_group_pid_list.append(proxy.pid) slap = slapos.slap.slap() slap.initializeConnection(config['master_url']) while True: try: slap.registerSupply().supply(config['profile_url'], computer_guid=config['computer_id']) except socket.error: time.sleep(1) pass else: break while True: slapgrid = subprocess.Popen([config['slapgrid_software_binary'], '-vc', config['slapos_config']], close_fds=True, preexec_fn=os.setsid) process_group_pid_list.append(slapgrid.pid) slapgrid.wait() if slapgrid.returncode == 0: print 'Software installed properly' break print 'Problem with software installation, trying again' time.sleep(600) computer = slap.registerComputer(config['computer_id']) partition_reference = config['partition_reference'] partition_path = os.path.join(config['instance_root'], partition_reference) if not os.path.exists(partition_path): os.mkdir(partition_path) os.chmod(partition_path, 0750) computer.updateConfiguration(xml_marshaller.dumps({ 'address': config['ipv4_address'], 'instance_root': config['instance_root'], 'netmask': '255.255.255.255', 'partition_list': [{'address_list': [{'addr': config['ipv4_address'], 'netmask': '255.255.255.255'}, {'addr': config['ipv6_address'], 'netmask': 'ffff:ffff:ffff::'}, ], 'path': partition_path, 'reference': partition_reference, 'tap': {'name': partition_reference}, } ], 'reference': config['computer_id'], 'software_root': config['software_root']})) slap.registerOpenOrder().request(config['profile_url'], partition_reference='testing partition', partition_parameter_kw=config['instance_dict']) slapgrid = subprocess.Popen([config['slapgrid_partition_binary'], '-vc', config['slapos_config']], close_fds=True, preexec_fn=os.setsid) slapgrid.wait() if slapgrid.returncode != 0: raise ValueError('Slapgrid instance failed') runUnitTest = os.path.join(partition_path, 'bin', 'runUnitTest') if not os.path.exists(runUnitTest): raise ValueError('No %r provided' % runUnitTest) except: try: if os.path.exists(supervisord_pid_file): os.kill(int(open(supervisord_pid_file).read().strip()), signal.SIGTERM) except: pass raise finally: # Nice way to kill *everything* generated by run process -- process # groups working only in POSIX compilant systems # Exceptions are swallowed during cleanup phase if proxy is not None: os.killpg(proxy.pid, signal.SIGTERM) if os.path.exists(config['proxy_database']): os.unlink(config['proxy_database']) if slapgrid is not None and slapgrid.returncode is None: os.killpg(slapgrid.pid, signal.SIGTERM) try: bot_env = os.environ.copy() bot_env['PATH'] = ':'.join([config['bin_directory']] + bot_env['PATH'].split(':')) for l in config['bot_environment'].split(): k, v = l.split('=') bot_env[k] = v if subprocess.call([config['buildbot_binary'], 'create-slave', '-f', config['working_directory'], config['buildbot_host'], config['slave_name'], config['slave_password']]) != 0: raise ValueError('Buildbot call failed') process_command_list.append([config['buildbot_binary'], 'stop', config['working_directory']]) if os.path.exists(os.path.join(config['working_directory'], 'buildbot.tac.new')): tac = os.path.join(config['working_directory'], 'buildbot.tac') if os.path.exists(tac): os.unlink(tac) os.rename(os.path.join(config['working_directory'], 'buildbot.tac.new'), tac) if subprocess.call([config['buildbot_binary'], 'start', config['working_directory']], env=bot_env) != 0: raise ValueError('Issue during starting buildbot') while True: time.sleep(3600) finally: try: subprocess.call([config['buildbot_binary'], 'stop', config['working_directory']]) except: pass try: if os.path.exists(supervisord_pid_file): os.kill(int(open(supervisord_pid_file).read().strip()), signal.SIGTERM) except: pass