def __del__(self): """ Kill all services for a user. """ logInfo('Killing all services for the current CE.') for user in self._services: proc = self._services[user]['proc'] read_conn = self._services[user]['conn_read'] write_conn = self._services[user]['conn_write'] try: read_conn.close() except Exception as err: logError( 'Cannot close connection: `{}`, exception `{}`!'.format( read_conn, err)) try: write_conn.close() except Exception as err: logError( 'Cannot close connection: `{}`, exception `{}`!'.format( write_conn, err)) try: proc.terminate() except Exception as err: logError('Cannot stop service: `{}`, exception `{}`!'.format( proc, err)) try: time.sleep(0.1) os.killpg(proc.pid, signal.SIGTERM) time.sleep(0.1) proc.kill() except: pass
def __init__(self): FsBorg.__init__(self) self.name = 'Local' if os.getuid(): logError( '{} FS: Central Engine must run as ROOT in order to start the User Service!' .format(self.name)) logInfo('Created {} FS.'.format(self.name))
def __init__(self, project): logInfo('Starting TestBeds Allocator...') ti = time.time() self.project = project self.resources = constant_dictionary self.reservedResources = dict() self.lockedResources = dict() self.acc_lock = thread.allocate_lock() # Task change lock self.ren_lock = thread.allocate_lock() # Rename lock self.imp_lock = thread.allocate_lock() # Import lock self.save_lock = thread.allocate_lock() # Save lock self.load_lock = thread.allocate_lock() # Save lock self.res_file = '{}/config/resources.json'.format(TWISTER_PATH) self._loadedUsers = dict() self.load_tb(verbose=True) logInfo('TestBeds Allocator initialization took `{:.4f}` sec.'.format(time.time()-ti))
logDebug('---- PROJ LOCALFS CLOSED') PROJ.ip_port = ('127.0.0.1', SERVER_PORT) CE.web = PROJ.web CE.tb = PROJ.testbeds CE.sut = PROJ.sut CE.report = PROJ.report # EE Manager is the helper for EPs and Clients # Inject the project as variable for EE RPYC_SERVER.service.inject_object('project', PROJ) RPYC_SERVER.service.inject_object('cherry', CE) # Start rpyc server thread.start_new_thread(RPYC_SERVER.start, ()) logInfo('RPYC Serving on 0.0.0.0:{}'.format(RPYC_PORT)) # Start ! # cherrypy.engine.signal_handler.handlers['SIGTERM'] = close # cherrypy.engine.subscribe('exit', close) cherrypy.quickstart(CE, '/', config=CONF) time.sleep(30) cherrypy.server.stop(); time.sleep(10) cherrypy.engine.exit() time.sleep(30) close() time.sleep(5) # del PROJ
def _usr_service(self, user, oper='read'): """ Launch a user service. """ if oper not in ['read', 'write']: logWarning( 'Invalid FS operation `{}`, for user `{}`! Will reset to "read".' .format(oper, user)) oper = 'read' # Must block here, so more users cannot launch Logs at the same time and lose the PID with self._srv_lock: # Try to re-use the logger server, if available conn = self._services.get(user, {}).get('conn_' + oper, None) if conn: try: conn.ping(data='Hello', timeout=30.0) # logDebug('Reuse old {} User Service connection for `{}` OK.'.format(op, user)) return conn except Exception as exp_err: logWarning( 'Cannot reuse {} User Service for `{}`: `{}`.'.format( oper, user, exp_err)) self._kill(user) else: logInfo('Launching a User Service for `{}`, the first time...'. format(user)) port = None # If the server is not available, search for a free port in the safe range... while 1: port = random.randrange(63000, 65000) try: socket.create_connection((None, port), 1) except Exception: break p_cmd = 'su {} -c "{} -u {}/server/UserService.py {} {}"'.\ format(user, sys.executable, TWISTER_PATH, port, self.name) proc = subprocess.Popen(p_cmd, cwd='{}/twister'.\ format(userHome(user)), shell=True, close_fds=True,\ stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc.poll() time.sleep(2.0) config = { 'allow_pickle': True, 'allow_getattr': True, 'allow_setattr': True, 'allow_delattr': True } retry = 10 delay = 0.5 success = False while retry > 0: if success: break try: stream_r = rpyc.SocketStream.connect('127.0.0.1', port, timeout=5.0) conn_read = rpyc.connect_stream(stream_r, config=config) conn_read.root.hello() logDebug( 'Connected to User Service for `{}`, operation `read`.' .format(user)) success = True except Exception as exp_err: logWarning('Cannot connect to User Service for `{}` - \ Exception: `{}`! Wait {}s...'.format(user, exp_err, delay)) if success: try: stream_w = rpyc.SocketStream.connect('127.0.0.1', port, timeout=5.0) conn_write = rpyc.connect_stream(stream_w, config=config) conn_write.root.hello() logDebug( 'Connected to User Service for `{}`, operation `write`.' .format(user)) break except Exception as exp_err: logWarning('Cannot connect to User Service for `{}` \ - Exception: `{}`! Wait {}s...' .\ format(user, exp_err, delay)) success = False time.sleep(delay) retry -= 1 delay += 0.75 if not success: logError( 'Error on starting User Service for `{}`!'.format(user)) return None # Save the process inside the block. 99% of the time, this block is executed instantly! self._services[user] = { 'proc': proc, 'conn_read': conn_read, 'conn_write': conn_write, 'port': port } logDebug( 'User Service for `{}` launched on `127.0.0.1:{}` - PID `{}`.'. format(user, port, proc.pid)) return self._services[user].get('conn_' + oper, None)
def get_reports(self, db_cfg_role=True): """ Used by Reporting Server. Returns a list with all report fields and queries. """ logFull('dbparser:get_reports') report_queries = OrderedDict() def get_fields(server_data, srv_name): """ All report fields. """ fields = OrderedDict() for field in server_data.xpath('reports_section/field'): data = {} data['id'] = field.get('ID', '') data['type'] = field.get('Type', '') data['label'] = field.get('Label', data['id']) data['sqlquery'] = field.get('SQLQuery', '') data['srv_name'] = srv_name fields[data['id']] = data return fields def get_reps(server_data, srv_name): """ All reports. """ reports = OrderedDict() for report in server_data.xpath('reports_section/report'): data = {} data['id'] = report.get('ID', '') data['type'] = report.get('Type', '') data['path'] = report.get('Path', '') data['folder'] = report.get('Folder', '') data['sqlquery'] = report.get('SQLQuery', '') data['sqltotal'] = report.get('SQLTotal', '') # SQL Total Query data['sqlcompr'] = report.get('SQLCompare', '') # SQL Query Compare side by side data['srv_name'] = srv_name # Save server name here reports[data['id']] = data return reports def get_redirects(server_data, srv_name): """ All redirects. """ redirects = OrderedDict() for redirect in server_data.xpath('reports_section/redirect'): data = {} data['id'] = redirect.get('ID', '') data['path'] = redirect.get('Path', '') data['srv_name'] = srv_name redirects[data['id']] = data return redirects # If the user has the roles AND Use Shared DB is disabled (user DB enabled) if db_cfg_role and not self.use_shared_db: # Insert user DB first and shared DB second db_pair = self.db_config['default_server'] # Reports and Redirects from private db.xml report_queries[db_pair] = { 'fields': get_fields(self.user_xml, 'User'), 'reports': get_reps(self.user_xml, 'User'), 'redirects': get_redirects(self.user_xml, 'User') } if not self.use_shared_db and not db_cfg_role: logInfo('Insufficient privileges to get user reports, for user `{}`!'.format(self.user)) # Valid shared db.xml if self.shared_xml is None: logWarning('Invalid shared DB XML on get reports, for user `{}`!'.format(self.user)) return report_queries # Invalid entry ? if not self.shared_xml.xpath('db_config/server/text()') or \ not self.shared_xml.xpath('db_config/database/text()'): logWarning('Invalid shared DB XML on get reports, for user `{}`!'.format(self.user)) return report_queries # Important MySQL server info db_server = self.shared_xml.xpath('db_config/server')[0].text db_name = self.shared_xml.xpath('db_config/database')[0].text db_user = self.shared_xml.xpath('db_config/user')[0].text db_passwd = self.shared_xml.xpath('db_config/password')[0].text db_pair = (db_server, db_name, db_user, db_passwd, 'S') # Overwrite all private fields, reports or redirects if db_pair in report_queries: report_queries[db_pair]['fields'].update(get_fields(self.shared_xml, 'Shared')) report_queries[db_pair]['reports'].update(get_reps(self.shared_xml, 'Shared')) report_queries[db_pair]['redirects'].update(get_redirects(self.shared_xml, 'Shared')) # Save this info else: report_queries[db_pair] = { 'fields': get_fields(self.shared_xml, 'Shared'), 'reports': get_reps(self.shared_xml, 'Shared'), 'redirects': get_redirects(self.shared_xml, 'Shared') } # Return after shared db inserts ! # import pprint ; pprint.pprint(dict(report_queries), width=40) return report_queries
def _usr_service(self, user_view_actv, op='read'): """ Launch a user service. Open a ClearCase view first. """ if user_view_actv.count(':') == 1 and user_view_actv[-1] != ':': user_view_actv += ':' try: user, view, actv = user_view_actv.split(':') except Exception: # We don't really know the user in here ! msg = 'Invalid ClearCase user-view-activity parameter: `{}`!'.format( user_view_actv) logWarning(msg) return '*ERROR* ' + msg if op not in ['read', 'write']: logWarning( 'Invalid CC operation `{}`, for user `{}`! Will reset to "read".' .format(op, user)) op = 'read' view = view.strip() actv = actv.strip() user_view = user + ':' + view if not view: # We don't know the view in here ! msg = 'Empty view in `{}`!'.format(user_view_actv) logWarning(msg) return '*ERROR* ' + msg def pread(): """ Read proc stdout """ while 1: try: line = proc.readline().strip() if not line: continue plog.append(line) except: break # Must block here, so more users cannot launch Logs at the same time and lose the PID with self._srv_lock: # Try to re-use the FS, if available conn = self._services.get(user_view, {}).get('conn_' + op, None) if conn: try: conn.ping(data='Hello', timeout=30.0) # logDebug('Reuse old {} ClearCase Service connection for `{}` OK.'.format(op, user_view)) proc = self._services.get(user_view, {}).get('proc', None) old_actv = self._services.get(user_view, {}).get('actv', None) if actv != old_actv: logInfo('Changing activity to `{}`, for `{}`.'.format( actv, user_view)) # Set cc activity again ! proc.sendline('cleartool setactivity {}'.format(actv)) time.sleep(1.0) pread() self._services.get(user_view, {})['actv'] = actv return conn except Exception as exp_err: logWarning('Cannot connect to `{}` ClearCase Service \ for `{}`: `{}`.'.format(op, user_view, exp_err)) self._kill(user) proc = self._services.get(user_view, {}).get('proc', None) PID = proc.pid proc.terminate() logInfo('Terminated CC User Service `{}` for user `{}`.'.\ format(PID, user)) else: logInfo('Launching a ClearCase Service for `{}`, the first \ time...'.format(user_view)) proc = pexpect.spawn(['bash'], timeout=2.5, maxread=2048) time.sleep(1.0) plog = [] proc.sendline('su {}'.format(user)) time.sleep(1.0) pread() # User's home folder proc.sendline('cd ~/twister') pread() # Set cc view only the first time ! proc.sendline('cleartool setview {}'.format(view)) time.sleep(2.0) pread() # Empty line after set view proc.sendline('') pread() if actv: # Set cc activity for the first time ! proc.sendline('cleartool setactivity {}'.format(actv)) time.sleep(1.0) pread() port = None # If the server is not available, search for a free port in the safe range... while 1: port = random.randrange(63000, 65000) try: socket.create_connection((None, port), 1) except Exception: break # Launching 1 UserService inside the SSH terminal, with ClearCase View open p_cmd = '{} -u {}/server/UserService.py {} {} & '.format( sys.executable, TWISTER_PATH, port, self.name) proc.sendline(p_cmd) time.sleep(2.0) pread() # Empty line after proc start proc.sendline('') pread() logDebug( 'ClearCase startup log \n:: -------\n{}\n:: -------'.format( '\n'.join(plog))) config = { 'allow_pickle': True, 'allow_getattr': True, 'allow_setattr': True, 'allow_delattr': True } retry = 10 delay = 0.5 success = False while retry > 0: if success: break try: stream_r = rpyc.SocketStream.connect('127.0.0.1', port, timeout=5.0) conn_read = rpyc.connect_stream(stream_r, config=config) conn_read.root.hello() logDebug( 'Connected to ClearCase Service for `{}`, operation `read`.' .format(user_view)) success = True except Exception as exp_err: logWarning('Cannot connect to ClearCase Service for `{}`!'\ 'Exception: `{}`! Retry...'.format(user_view, exp_err)) if success: try: stream_w = rpyc.SocketStream.connect('127.0.0.1', port, timeout=5.0) conn_write = rpyc.connect_stream(stream_w, config=config) conn_write.root.hello() logDebug( 'Connected to ClearCase Service for `{}`, operation `write`.' .format(user_view)) break except Exception as exp_err: logWarning('Cannot connect to ClearCase Service \ for `{}`! Exception: `{}`! Retry...' .\ format(user_view, exp_err)) success = False time.sleep(delay) retry -= 1 delay += 0.75 if not success: logError( 'Error on starting ClearCase Service for `{}`!'.format( user_view)) return None # Save the process inside the block. self._services[user_view] = {'proc': proc, 'port': port,\ 'conn_read': conn_read, 'conn_write': conn_write, 'actv': actv} logDebug( 'ClearCase Service for `{}` launched on `127.0.0.1:{}`.'.format( user_view, port)) return self._services[user_view].get('conn_' + op, None)