def executeCommand(self, request, context): #TODO: # execute command, capture stdout and return excuted results # Input: common_type.ExecuteCommandRequest # output: common_type.StatusResponse self.LOG.debug('receive executeCommand') token = request.token command = request.command.value timeout = request.command.timeout if not timeout > 0: timeout = None try: self.authenticateToken(token) #throw exception self.LOG.warning('execute command: {}'.format(command)) # parsing command #cmd_list = shlex.split(command) #self.LOG.debug('parse command: {}'.format(cmd_list)) # execute command #raw_output = subprocess.check_output(cmd_list, timeout=timeout) #output = raw_output.decode('utf-8') rc, output, _ = self.exeCommand(command, timeout=timeout, wait=True, print_output=True) status = self._getStatusObject('OK') response = common_type.StatusResponse(result=output, status=status) except subprocess.CalledProcessError as e: output = e.output.decode( 'utf-8') # byte string -> decode -> string code = e.returncode # int status, errcode = self._handleError( 'executeCommand while executing user command', e) response = common_type.StatusResponse(result=output, status=status, error=errcode) except subprocess.TimeoutExpired as e: output = e.output.decode( 'utf-8') # byte string -> decode -> string status, errcode = self._handleError( 'executeCommand while executing user command', e) response = common_type.StatusResponse(result=output, status=status, error=errcode) except Exception as e: status, errcode = self._handleError('executeCommand', e) response = common_type.StatusResponse(status=status, error=errcode) return response
def sendMessage(self, request, context): # Input: common_type.SendMessageRequest # Output: common_type.StatusResponse self.LOG.debug('receive sendMessage request') #token = request.token msg = request.msg try: #self.authenticateToken(token) #throw exception #username = self.getUsernameByToken(token) self.LOG.info('[user unknown]: {}'.format(msg)) if self.sendMessageCallback: self.LOG.debug('calling sendMessageCallback function') self.sendMessageCallback(request, context) status = self._getStatusObject('OK') response = common_type.StatusResponse(status=status) except Exception as e: status, errcode = self._handleError('sendMessage', e) response = common_type.StatusResponse(status=status, error=errcode) return response
def forceShutdownWorkers(self, request, context): self.LOG.debug('receive forceShutdownWorkers request') token = request.token shutdown_all = request.all fullnames = request.fullname try: self.authenticateToken(token) #throw exception username = self.getUsernameByToken(token) if username in self._owner_map: if shutdown_all: worker_list = self._owner_map[username].copy() for worker_uniquename in worker_list: self.LOG.debug( 'shutdown worker: {}'.format(worker_uniquename)) worker = self._worker_map[worker_uniquename] self.forceStopProcess(worker['process']) del self._worker_map[worker_uniquename] self._owner_map[username] = [] for worker_uniquename in fullnames: worker_list = self._owner_map[username].copy() if worker_uniquename in worker_list: self.LOG.debug( 'shutdown worker: {}'.format(worker_uniquename)) worker = self._worker_map[worker_uniquename] self.forceStopProcess(worker['process']) del self._worker_map[worker_uniquename] self._owner_map[username].remove(worker_uniquename) status = self._getStatusObject('OK') response = common_type.StatusResponse(status=status) except Exception as e: status, errcode = self._handleError('forceShutdownWorkers', e) response = common_type.StatusResponse(status=status, error=errcode) return response
def getWelcomeMessage(self, request, context): # Input: common_type.Token # Output: common_type.StatusResponse self.LOG.debug('receive getWelcomeMessage request') try: status = self._getStatusObject('OK') response = common_type.StatusResponse(result=self.welcome_message, status=status) except Exception as e: status, errcode = self._handleError('getWelcomeMessage', e) response = common_type.StatusResponse(status=status, error=errcode) return response
def uploadFile(self, request_iterator, context): # Input: stream common_type.UploadFileRequest # Output: common_type.StatusResponse self.LOG.debug('receive uploadFile request') try: for request_chunk in request_iterator: chunk = request_chunk.chunk key = chunk.key fileinfo = self._getFileInfoFromUploadKeyMap( key) #throw key error filename = fileinfo['name'] filepath = os.path.dirname(fileinfo['name']) self.LOG.debug('upload filename: {} / filepath: {}'.format( fileinfo['name'], filepath)) if not os.path.exists(filepath) and filepath != '': os.makedirs(filepath) if fileinfo['fp'] == None: fileinfo['fp'] = open(filename, 'wb') fileinfo['fp'].write(chunk.buffer) fileinfo['fp'].close() if os.path.getsize(fileinfo['name']) != fileinfo['size']: raise Exception( 'size of the uploaded file does not match to FileInfo.size uploaded by owner: {}' .format(fileinfo['owner'])) status = self._getStatusObject('OK') response = common_type.StatusResponse( result='upload file successfully', status=status) except Exception as e: status, errcode = self._handleError('uploadFile', e) response = common_type.StatusResponse( result='failed to upload file', status=status, error=errcode) return response
def shutdown(self, request, context): self.LOG.debug('receive shutdown request') try: status = self._getStatusObject('OK') response = common_type.StatusResponse(status=status) self.LOG.debug('send interrupt signal to main thread') _thread.interrupt_main() # send KeyboardInterrupt to main thread self.shutdown_event.set() except Exception as e: status, errcode = self._handleError('shutdown', e) response = common_type.StatusResponse(status=status, error=errcode) return response
def checkUserExistance(self, request, context): # Input: common_type.CheckUserExistanceRequest # Output: common_type.StatusResponse self.LOG.debug('receive checkUserExistance request') username = request.username try: result = self.validateUser(username) status = self._getStatusObject('OK') response = common_type.StatusResponse(result=str(result), status=status) except Exception as e: status, errcode = self._handleError('chechUserExistance', e) response = common_type.StatusResponse(status=status, error=errcode) return response
def removeFileOrDirectory(self, request, context): #TODO: # remove file or directory # Input: common_type.RemoveFileOrDirectoryRequest # Output: common_type.StatusResponse try: raise NotImplementedError('removeFileOrDirectory not implemented') except Exception as e: status, errcode = self._handleError('removeFileOrDirectory', e) response = common_type.StatusResponse(status=status, error=errcode) return response
def getFileInfo(self, request, context): #TODO: # return file information # Input: common_type.GetFileInfoRequest # Output: common_type.FileInfoResponse try: raise NotImplementedError('getFileInfo not implemented') except Exception as e: status, errcode = self._handleError('getFileInfo', e) response = common_type.StatusResponse(status=status, error=errcode) return response
def getDirectoryList(self, request, context): #TODO: # return directory list # Input: common_type.GetDirectoryListRequest # Output: common_type.StatusPresponse try: raise NotImplementedError('getDirectoryList not implemented') except Exception as e: status, errcode = self._handleError('getDirectoryList', e) response = common_type.StatusResponse(status=status, error=errcode) return reponse
def createVirtualenv(self, request, context): # Input: common_type.CreateVirtualenvRequest # Output: common_type.StatusResponse self.LOG.debug('receive createVirtualenv request') token = request.token config = request.configuration env_path = config.path params = config.params requirements = config.requirements output = '' try: self.authenticateToken(token) #throw exception def exeCommand(command, env=None): cmds = shlex.split(command) self.LOG.info('execute command: {}'.format(cmds)) # execute command with specified env p = subprocess.Popen(cmds, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output = '' while True: o = p.stdout.readline().decode('utf-8') if o == '' and p.poll() is not None: break output = output + '\n' + o self.LOG.info(' {}'.format(o)) rc = p.poll() self.LOG.info(' exit code: {}'.format(rc)) if rc != 0: raise subprocess.CalledProcessError(returncode=rc, cmd=cmds, output=output) return rc, output self.LOG.info('creating virtualenv: {}'.format(env_path)) param_string = '' if len(params) > 0: for _param in params: _param = _param.replace(' ', '') _param = "--{}".format(_param) param_string = param_string + _param self.LOG.info(' add param: {}'.format(_param)) rc, o = exeCommand('virtualenv {} {}'.format( param_string, os.path.expanduser(env_path))) output = output + '\n' + o self.LOG.info('copying env') env = os.environ.copy() lib_path = os.path.abspath('{}/lib'.format(env_path)) env["PATH"] = '{}:'.format(lib_path) + env["PATH"] self.LOG.info(' add PATH to env: {}'.format(lib_path)) self.LOG.info('installing dependencies') python_path = os.path.abspath('{}/bin/python'.format(env_path)) pip_path = os.path.abspath('{}/bin/pip'.format(env_path)) for lib in requirements: self.LOG.info('installing dependencies: {}'.format(lib)) rc, o = exeCommand('{} install {}'.format(pip_path, lib)) output = output + '\n' + o status = self._getStatusObject('OK') response = common_type.StatusResponse(result=output, status=status) except subprocess.CalledProcessError as e: output = e.output code = e.returncode # int status, errcode = self._handleError( 'createVirtualenv while doing some stuff', e) response = common_type.StatusResponse(result=output, status=status, error=errcode) except Exception as e: status, errcode = self._handleError('createVirtualenv', e) response = common_type.StatusResponse(result=output, status=status, error=errcode) return response
def launchWorkers(self, request, context): # Input: common_type.LaunchWorkerRequest # Output: common_type.StatusResponse self.LOG.debug('receive launchWorkers request') token = request.token config = request.configuration try: self.authenticateToken(token) username = self.getUsernameByToken(token) master_name = config.master.name master_addr = config.master.addr proxy_config = config.proxy proxy_name = proxy_config.name default_entrypoint = proxy_config.default_entrypoint default_venv = proxy_config.default_venv if default_venv != '': default_venv = os.path.expanduser(default_venv) worker_configs = proxy_config.workers if len(worker_configs) == 0: raise Exception('no worker definition found') for worker in worker_configs: worker_name = worker.name worker_port = worker.port worker_entrypoint = default_entrypoint if worker.entrypoint == '' else worker.entrypoint worker_venv = default_venv if worker.venv == '' else worker.venv worker_envs = {} if worker_name == '': raise Exception('no name specified for worker') if worker_port == '': raise Exception( 'no port number specified for worker={}'.format( worker_name)) if len(worker.environment) > 0: for env in worker.environment: worker_envs[env.variable] = env.value if worker_entrypoint == '': raise Exception( 'no entrypoint specified for worker={}, port={}'. format(worker_name, worker_port)) worker_entrypoint = os.path.abspath(worker_entrypoint) if worker_venv == '': python_path = 'python3' lib_path = '' else: worker_venv = os.path.expanduser(worker_venv) python_path = os.path.abspath( '{}/bin/python'.format(worker_venv)) lib_path = os.path.abspath('{}/lib'.format(worker_venv)) def _get_grpc_cluster_path(): import grpc_cluster fullpath = os.path.abspath(grpc_cluster.__file__) return os.path.dirname(os.path.dirname(fullpath)) def _launch_single_worker(worker_name, worker_uniquename, worker_port): # launch worker env = os.environ.copy() env['GRPC_CLUSTER_ROOT'] = _get_grpc_cluster_path() env['CLUSTER_ROOT'] = str(os.path.abspath('./')) env['CLUSTER_WORKER_ROOT'] = str( os.path.join(env['CLUSTER_ROOT'], worker_name)) env['CLUSTER_WORKER_NAME'] = str(worker_uniquename) env['CLUSTER_WORKER_PORT'] = str(worker_port) env['CLUSTER_MASTER_NAME'] = str(master_name) env['CLUSTER_MASTER_ADDR'] = str(master_addr) # add venv library path, cluster root path env['PATH'] = '{}:{}:'.format( lib_path, env['CLUSTER_ROOT']) + env['PATH'] for e in worker_envs: env[e] = str(worker_envs[e]) current_time = getLogTimeString() output_dirname = '{}_worker_log'.format(proxy_name) output_filename = '{}_{}_{}'.format( worker_name, worker_port, current_time) output_path = os.path.join(output_dirname, output_filename) try: os.makedirs(output_dirname) except OSError: pass stdout_name = '{}.stdout'.format(output_path) stderr_name = '{}.stderr'.format(output_path) self.LOG.debug(' start worker:') self.LOG.debug(' name: {}'.format(worker_name)) self.LOG.debug( ' uniquename: {}'.format(worker_uniquename)) self.LOG.debug(' port: {}'.format(worker_port)) self.LOG.debug( ' entrypoint: {}'.format(worker_entrypoint)) self.LOG.debug(' venv: {}'.format(worker_venv)) self.LOG.debug(' envs: {}'.format(worker_envs)) self.LOG.debug(' stdout: {}'.format(stdout_name)) self.LOG.debug(' stderr: {}'.format(stdout_name)) self.LOG.debug(' owner: {}'.format(username)) # create command command = '{} \"{}\"'.format(python_path, worker_entrypoint) # start worker worker_stdout = open(stdout_name, "wb") # worker_stderr = open(stderr_name, "wb") _, _, process = self.exeCommand(command, env=env, stdout=worker_stdout, stderr=worker_stdout) self._worker_map[worker_uniquename] = { 'name': worker_name, 'fullname': worker_uniquename, 'port': worker_port, 'entrypoint': worker_entrypoint, 'venv': worker_venv, 'envs': worker_envs, 'process': process, 'stdout': worker_stdout, #'stderr': worker_stderr, 'owner': username, } if not username in self._owner_map: self._owner_map[username] = [] self._owner_map[username].append(worker_uniquename) if '-' in worker_port: start_port, end_port = worker_port.split('-') start_port = int(start_port.strip()) end_port = int(end_port.strip()) launch_port = [x for x in range(start_port, end_port + 1)] for port in launch_port: _worker_name = worker_name _worker_port = port _worker_uniquename = '{}@{}:{}'.format( _worker_name, _proxy_name, _worker_port) _launch_single_worker(_worker_name, _worker_uniquename, _worker_port) else: _worker_uniquename = '{}@{}:{}'.format( worker_name, proxy_name, worker_port) _launch_single_worker(worker_name, _worker_uniquename, worker_port) status = self._getStatusObject('OK') response = common_type.StatusResponse(status=status) except Exception as e: status, errcode = self._handleError('launchWorker', e) response = common_type.StatusResponse(status=status, error=errcode) return response