def start(self): logger.debug('Starting X11VNC') self.executor = X11VNCExecutor(self.display, self.get_rfbport(), self.clip, self.password) self.executor.start() logger.debug('X11VNC Ready!')
def flush_activity_stack(self): logger.debug('Flushing activity stack') cmd = [ "adb", "-s", "emulator-{}".format(self.port), "shell", "am", "stack", "remove", "1" ] return subprocess.call(cmd, timeout=5)
def on_droid_release(self, data, stat, event): if not event: return node_name = event.path.rsplit('/', 1)[1] if event.type == EventType.DELETED: logger.debug('Droid ({}) was released'.format(node_name)) self.droid.cleanup()
def setup_free_droids(self): running_droids = self.zk.get_children('/droids/running') for droid in running_droids: logger.debug('Setting up running droids') self.zk.create('/droids/free/{}'.format(droid)) DataWatch(self.zk, '/droids/running/{}'.format(droid), self.on_running_droid_change)
def start(self): logger.debug('Starting {}'.format(self.__class__.__name__)) self.stdout_fd = open( os.path.join( VAR_DIR, "{}-{}".format( self.__class__.__name__, self.id)), 'w') self._proc = self._start()
def setup_dirs(self): # setup tmp dir if os.path.isdir(VAR_DIR): shutil.rmtree(VAR_DIR) logger.debug('Setting up temp dir') os.makedirs(VAR_DIR)
def get_endpoint(self, endpoint_id): logger.debug("Getting endpoint for {}".format(endpoint_id)) endpoint = self.coordinator.get_droid(endpoint_id) cp = ConnParams() cp.host = get_public_hostname() cp.port = endpoint.websockify.source_port cp.password = endpoint.x11vnc.password return cp
def goto_home_screen(self): logger.debug('Sending intent to goto home screen') cmd = [ "adb", "-s", "emulator-{}".format(self.port), "shell", "am", "start", "-W", self._get_home_screen_activity_uri() ] return subprocess.call(cmd, timeout=5)
def uninstall_package(self, package): logger.debug('Uninstalling package: {}'.format(package)) cmd = [ "adb", "-s", "emulator-{}".format(self.port), "uninstall", package ] output = subprocess.check_output(cmd, timeout=15) if re.match(r"Success", output): logger.debug('Finished uninstalling apk') return True
def stop(self): logger.debug('Stopping droid') to_stop = [self.websockify, self.x11vnc, self.emulator, self.xvfb] for proc in to_stop: try: proc.stop() except: pass logger.debug('Droid stopped!')
def start_package_activity(self, package, activity): cmd = [ "adb", "-s", "emulator-{}".format(self.port), "shell", "am", "start", "-n", "{}/{}".format(package, activity) ] subprocess.check_call(cmd, timeout=5) logger.debug('Started package activity') # TODO: Check if activity was really started return True
def get_package_name(self, apk_url): logger.debug("getting package name for apk {}".format(apk_url)) try: return get_package_name_from_url(apk_url) except Exception as err: exc = ApplicationException() exc.msg = str(err) if hasattr(err, 'msg'): exc.msg = err.msg raise exc
def netcat_wait(self, proc): logger.debug('Netcat wait') cmd = ["nc", "-w", "2", "-zv", "localhost", str(self.source_port)] while True: try: subprocess.check_call(cmd) except subprocess.CalledProcessError: time.sleep(0.1) else: break
def _install_apk(self, path): logger.debug('Install apk {}'.format(path)) cmd = [ "adb", "-s", "emulator-{}".format(self.port), "install", "-r", path ] output = subprocess.check_output(cmd, timeout=15, universal_newlines=True) if re.match(r"Success", output): logger.debug('Finished installing apk') return True
def cycle_password(self): logger.debug('Cycling passwords for x11vnc') # Set new password self.password = generate_password() # Stop the server self.executor.stop() self.executor = X11VNCExecutor(self.display, self.get_rfbport(), self.clip, self.password) # Start the server again self.executor.start() logger.debug('Password cycle complete!')
def sys_boot_wait(self): logger.debug('Sys boot wait') cmd = [ "adb", "-s", "emulator-{}".format(self.port), "shell", "getprop", "sys.boot_completed" ] pattern = re.compile(r"1") while True: output = subprocess.check_output(cmd, universal_newlines=True) if pattern.match(output): break time.sleep(0.1)
def cleanup_dangling_droids(self): free_droids = self.zk.get_children('/droids/free') running_droids = self.zk.get_children('/droids/running') dangling_droids = (set(free_droids) - set(running_droids)) for droid in dangling_droids: logger.debug('Deleting dangling free droid ({})'.format(droid)) self.zk.delete('/droids/free/{}'.format(droid)) assigned_droids = self.zk.get_children('/droids/assigned') dangling_droids = set(assigned_droids) - set(running_droids) for droid in dangling_droids: logger.debug('Deleting dangling assigned droid ({})'.format(droid)) self.zk.delete('/droids/assigned/{}'.format(droid))
def portfile_wait(self): logger.debug('port file wait') retries = 0 while True: if retries > 10: msg = 'Could not start x11vnc @ {}. Check the logs.'.format( self.display) raise Exception(msg) if os.path.exists(self._portfile_p): break time.sleep(0.5) retries += 1
def setup(self): logger.debug('Setting up dirs') self.setup_dirs() logger.debug('Setting up droids') config = get_config() builder = DroidBuilder() for droid in config['droids']: for key, value in droid.iteritems(): func = getattr(builder, "set_{}".format(key)) func(value) self.coordinator.add_droid(builder.build()) # Start all endpoints now self.coordinator.setup()
def transport(self): transport = TSocket.TSocket(self.host, self.port) transport = TTransport.TBufferedTransport(transport) protocol = TBinaryProtocol.TBinaryProtocol(transport) self.client = DroidKeeper.Client(protocol) logger.debug('opening connection') transport.open() try: yield finally: logger.debug('closing connection') transport.close() self.client = None
def on_running_droid(self, children, event): if not event: return logger.debug('Registering watches on running droids') assigned_droids = self.zk.get_children('/droids/assigned') free_droids = set(children) - set(assigned_droids) for droid in free_droids: # Implies a new droid became available logger.debug('WooHoo! Another droid joins our ranks!') # Create corresponding node in /droids/free free_p = '/droids/free/{}'.format(droid) self.zk.ensure_path(free_p) droid_p = '/droids/running/{}'.format(droid) DataWatch(self.zk, droid_p, self.on_running_droid_change)
def on_assigned_droid_change(self, data, stat, event): if event: node_name = event.path.rsplit('/', 1)[1] if event.type == EventType.DELETED: # Check if droid was lost or freed. if self.zk.exists('/droids/running/{}'.format(node_name)): logger.debug('Droid ({}) was released'.format(node_name)) return logger.error('Uh-oh! An assigned droid ({}) was lost!'.format( node_name)) logger.error( 'Accomodate user ({}) with a new droid'.format(data)) else: logger.debug('These are not the events you are looking for.')
def setup(self): logger.debug('Setting up directories and nodes') self.zk.start() # Initialize nodes self.initialize_nodes() # Register watches self.on_running_droid = ChildrenWatch(self.zk, '/droids/running', self.on_running_droid, send_event=True) self.on_assigned_droid = ChildrenWatch( self.zk, '/droids/assigned', self.on_assigned_droid, )
def xdpyinfo_wait(self): logger.debug('xdpyinfo wait') cmd = ["xdpyinfo", "-display", ":{}".format(self.display)] while True: logger.debug('trying again from xdpyinfo') try: output = subprocess.check_output(cmd, timeout=3, universal_newlines=True) except subprocess.CalledProcessError: time.sleep(0.1) continue if not self.xdpyinfo_p.search(output): break time.sleep(0.1)
def setup(self): logger.debug('Registering onto zookeeper') self.zk.start() config = get_config() value = { 'thrift_host': get_public_hostname(), 'thrift_port': config['thrift_port'], } path = self.zk.create('/droids/running/droid', value=json.dumps(value), sequence=True, makepath=True, ephemeral=True) self.nodename = path.rsplit('/', 1)[1] DataWatch(self.zk, '/droids/assigned/{}'.format(self.nodename), self.on_droid_release)
def stop(self): logger.debug('Stopping {}'.format(self.__class__.__name__)) try: self._proc.terminate() except: pass try: self._proc.kill() except: pass # Really wait for child process to terminate self._proc.wait() # Prevents zombie processes del self._proc self._proc = None # Close file descriptor self.stdout_fd.close()
def run_operation(self, endpoint_id, operation, apk_url): logger.debug("Interacting with Droid({})".format(endpoint_id)) try: endpoint = self.coordinator.get_droid(endpoint_id) if operation == 'install_apk': return endpoint.emulator.install_apk_from_url(apk_url) elif operation == 'install_and_start_apk': endpoint.emulator.install_apk_from_url(apk_url) return endpoint.emulator.start_last_package() else: raise Exception('Unsupported operation - {}'.format(operation)) except Exception as err: exc = ApplicationException() exc.msg = str(err) if hasattr(err, 'msg'): exc.msg = err.msg raise exc
def start(self): logger.debug('Starting droid') started = [] try: self.xvfb.start() started.append(self.xvfb) self.emulator.start() started.append(self.emulator) self.x11vnc.start() started.append(self.x11vnc) self.websockify.start() started.append(self.websockify) logger.debug('Droid ready!') except: logger.error('Failed to start droid. Reverting') for proc in started: try: proc.stop() except: pass raise
def conn_listener(state): if state == KazooState.CONNECTED: logger.debug('connected...') elif state == KazooState.LOST: logger.debug('connection lost...') elif state == KazooState.SUSPENDED: logger.debug('connection suspended...')
def _start(self): # Set DISPLAY variable first env = os.environ.copy() if self.display: env['DISPLAY'] = ':{}'.format(self.display) cmd = [ "emulator", "-port", self.port, "-avd", self.avd, "-no-boot-anim", "-nojni", "-netfast", "-gpu", "swiftshader", "-qemu", "-enable-kvm" ] if os.getenv("NO_WINDOW"): cmd.append("-no-window") proc = subprocess.Popen( cmd, env=env, stdout=self.stdout_fd, stderr=subprocess.STDOUT, universal_newlines=True, ) # Wait till boot logger.debug(self.adb_wait()) self.sys_boot_wait() return proc