Beispiel #1
0
 def _cancel(self):
     """
     Cancel on-going storlet execution
     """
     client = SBusClient(self.storlet_pipe_path)
     try:
         resp = client.cancel(self.task_id)
         if not resp.status:
             raise StorletRuntimeException('Failed to cancel task')
     except SBusClientException:
         raise StorletRuntimeException('Failed to cancel task')
Beispiel #2
0
    def activate_storlet_daemon(self, sreq, cache_updated=True):
        storlet_daemon_status = \
            self.get_storlet_daemon_status(sreq.storlet_main)
        if (storlet_daemon_status == -1):
            # We failed to send a command to the factory.
            # Best we can do is execute the container.
            self.logger.debug('Failed to check Storlet daemon status, '
                              'restart Docker container')
            try:
                self.restart()
            except StorletTimeout:
                raise StorletRuntimeException('Docker container is '
                                              'not responsive')
            storlet_daemon_status = 0

        if (cache_updated is True and storlet_daemon_status == 1):
            # The cache was updated while the daemon is running we need to
            # stop it.
            self.logger.debug('The cache was updated, and the storlet daemon '
                              'is running. Stopping daemon')
            res = self.stop_storlet_daemon(sreq.storlet_main)
            if res != 1:
                try:
                    self.restart()
                except StorletTimeout:
                    raise StorletRuntimeException('Docker container is '
                                                  'not responsive')
            else:
                self.logger.debug('Deamon stopped')
            storlet_daemon_status = 0

        if (storlet_daemon_status == 0):
            self.logger.debug('Going to start storlet daemon!')

            # TODO(takashi): This is not needed for python application
            classpath = self._get_storlet_classpath(
                sreq.storlet_main, sreq.storlet_id, sreq.dependencies)

            daemon_status = self.start_storlet_daemon(
                classpath, sreq.storlet_main, sreq.storlet_language,
                sreq.options.get("storlet_language_version"))

            if daemon_status != 1:
                self.logger.error('Daemon start Failed, returned code is %d' %
                                  daemon_status)
                raise StorletRuntimeException('Daemon start failed')
            else:
                self.logger.debug('Daemon started')
Beispiel #3
0
    def _wait_for_read_with_timeout(self, fd):
        """
        Wait while the read file descriptor gets ready

        :param fd: File descriptor to read
        :raises StorletTimeout: Exception raised when it times out to cancel
                                the existing task
        :raises StorletRuntimeException: Exception raised when it fails to
                                         cancel the existing task
        """
        try:
            with StorletTimeout(self.timeout):
                r, w, e = select.select([fd], [], [])
        except StorletTimeout:
            exc_type, exc_value, exc_traceback = sys.exc_info()

            # When there is a task already running, we should cancel it.
            if self.task_id:
                try:
                    self._cancel()
                except StorletRuntimeException:
                    self.logger.warning(
                        'Task %s timed out, but failed to get canceled'
                        % self.task_id)
                    pass

            six.reraise(exc_type, exc_value, exc_traceback)
        if fd not in r:
            raise StorletRuntimeException('Read fd is not ready')
Beispiel #4
0
    def _send_execute_command(self):
        """
        Send execute command to the remote daemon factory to invoke storlet
        execution
        """
        client = SBusClient(self.storlet_pipe_path)
        try:
            resp = client.execute(self.srequest.params, self.remote_fds)
            if not resp.status:
                raise StorletRuntimeException("Failed to send execute command")

            if not resp.task_id:
                raise StorletRuntimeException("Missing task id")
            else:
                self.task_id = resp.task_id
        except SBusClientException:
            raise StorletRuntimeException("Failed to send execute command")
Beispiel #5
0
    def _send_execute_command(self):
        """
        Send execute command to the remote daemon factory to invoke storlet
        execution
        """
        dtg = SBusExecuteDatagram(
            SBUS_CMD_EXECUTE,
            self.remote_fds,
            self.srequest.params)
        rc = SBus.send(self.storlet_pipe_path, dtg)

        if (rc < 0):
            raise StorletRuntimeException("Failed to send execute command")
Beispiel #6
0
    def _wait_for_write_with_timeout(self, fd):
        """
        Wait while the write file descriptor gets ready

        :param fd: File descriptor to write
        :raises StorletTimeout: Exception raised when it times out to cancel
                                the existing task
        :raises StorletRuntimeException: Exception raised when it fails to
                                         cancel the existing task
        """
        with StorletTimeout(self.timeout):
            r, w, e = select.select([], [fd], [])
        if fd not in w:
            raise StorletRuntimeException('Write fd is not ready')
Beispiel #7
0
    def _read_metadata(self):
        """
        Read metadata in the storlet execution result from fd

        :returns: a dict of metadata
        """
        self._wait_for_read_with_timeout(self.metadata_read_fd)
        flat_json = os.read(self.metadata_read_fd, MAX_METADATA_SIZE)
        os.close(self.metadata_read_fd)
        try:
            return json.loads(flat_json)
        except ValueError:
            self.logger.exception('Failed to load metadata from json')
            raise StorletRuntimeException('Got invalid format about metadata')
Beispiel #8
0
    def _parse_sandbox_factory_answer(self, str_answer):
        """
        Parse answer string received from container side

        :param str_answer: answer string
        :returns: (status, message)
        """
        two_tokens = str_answer.split(':', 1)
        if len(two_tokens) != 2:
            self.logger.error('Got wrong format about answer over sbus: %s' %
                              str_answer)
            raise StorletRuntimeException('Got wrong answer')
        status = (two_tokens[0] == 'True')
        return status, two_tokens[1]
Beispiel #9
0
 def _cancel(self):
     """
     Cancel on-going storlet execution
     """
     with _open_pipe() as (read_fd, write_fd):
         dtg = SBusServiceDatagram(
             sbus_cmd.SBUS_CMD_CANCEL,
             [write_fd],
             [FDMetadata(sbus_fd.SBUS_FD_SERVICE_OUT).to_dict()],
             None,
             self.task_id)
         rc = SBus.send(self.storlet_pipe_path, dtg)
         if (rc < 0):
             raise StorletRuntimeException('Failed to cancel task')
         # TODO(takashi): Check the response here
         os.read(read_fd, 10)
Beispiel #10
0
    def _restart(self, docker_image_name):
        """
        Restarts the scope's sandbox using the specified docker image

        :param docker_image_name: name of the docker image to start
        :raises StorletRuntimeException: when failed to restart the container
        """
        if self.docker_repo:
            docker_image_name = '%s/%s' % (self.docker_repo,
                                           docker_image_name)

        docker_container_name = '%s_%s' % (self.docker_image_name_prefix,
                                           self.scope)

        pipe_mount = '%s:%s' % (self.paths.host_pipe_dir,
                                self.paths.sandbox_pipe_dir)
        storlet_mount = '%s:%s:ro' % (self.paths.host_storlet_base_dir,
                                      self.paths.sandbox_storlet_base_dir)
        storlet_native_lib_mount = '%s:%s:ro' % (
            self.paths.host_storlet_native_lib_dir,
            self.paths.sandbox_storlet_native_lib_dir)
        storlet_native_bin_mount = '%s:%s:ro' % (
            self.paths.host_storlet_native_bin_dir,
            self.paths.sandbox_storlet_native_bin_dir)

        cmd = [os.path.join(self.paths.host_restart_script_dir,
                            'restart_docker_container'),
               docker_container_name, docker_image_name, pipe_mount,
               storlet_mount, storlet_native_lib_mount,
               storlet_native_bin_mount]

        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        stdout, stderr = proc.communicate()

        if stdout:
            if not isinstance(stdout, str):
                stdout = stdout.decode("utf-8")
            self.logger.debug('STDOUT: %s' % stdout.replace('\n', '#012'))
        if stderr:
            if not isinstance(stderr, str):
                stderr = stderr.decode("utf-8")
            self.logger.error('STDERR: %s' % stderr.replace('\n', '#012'))

        if proc.returncode:
            raise StorletRuntimeException('Failed to restart docker container')
Beispiel #11
0
 def dummy_wait_failure(*args, **kwargs):
     raise StorletRuntimeException()