Example #1
0
    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
Example #3
0
    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
Example #4
0
    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
Example #5
0
    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
Example #6
0
 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
Example #7
0
    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
Example #8
0
    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
Example #9
0
    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
Example #10
0
    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
Example #11
0
    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
Example #12
0
    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