Exemple #1
0
def main():
    """
    The entry point of daemon_factory process
    """
    parser = argparse.ArgumentParser(
        description='Factory process to manage storlet daemons')
    parser.add_argument('sbus_path', help='the path to unix domain socket')
    parser.add_argument('log_level', help='log level')
    parser.add_argument('container_id', help='container id')
    opts = parser.parse_args()

    # Initialize logger
    logger = get_logger("daemon-factory", opts.log_level, opts.container_id)
    logger.debug("Daemon factory started")

    try:
        SBus.start_logger("DEBUG", container_id=opts.container_id)

        # Impersonate the swift user
        pw = pwd.getpwnam('swift')
        os.setresgid(pw.pw_gid, pw.pw_gid, pw.pw_gid)
        os.setresuid(pw.pw_uid, pw.pw_uid, pw.pw_uid)

        # create an instance of daemon_factory
        factory = StorletDaemonFactory(opts.sbus_path, logger,
                                       opts.container_id)

        # Start the main loop
        sys.exit(factory.main_loop())

    except Exception:
        logger.eception('Unhandled exception')
        sys.exit(EXIT_FAILURE)
Exemple #2
0
    def main_loop(self):
        """
        Main loop to run storlet application

        :returns: EXIT_SUCCESS when the loop exists normally
                  EXIT_FAILURE when some error occurd in main loop
        """
        sbus = SBus()
        fd = sbus.create(self.sbus_path)
        if fd < 0:
            self.logger.error("Failed to create SBus. exiting.")
            return EXIT_FAILURE

        while True:
            rc = sbus.listen(fd)
            if rc < 0:
                self.logger.error("Failed to wait on SBus. exiting.")
                return EXIT_FAILURE

            dtg = sbus.receive(fd)
            if dtg is None:
                self.logger.error("Failed to receive message. exiting")
                return EXIT_FAILURE

            if not self.dispatch_command(dtg):
                break

        self.logger.debug('Leaving main loop')
        self._terminate()
        return EXIT_SUCCESS
Exemple #3
0
def main(argv):
    """
    The entry point of daemon_factory process

    :param argv: parameters given from command line
    """
    if (len(argv) != 5):
        usage()
        return EXIT_FAILURE

    storlet_name = argv[0]
    sbus_path = argv[1]
    log_level = argv[2]
    pool_size = argv[3]
    container_id = argv[4]

    # Initialize logger
    logger = start_logger("storlets-daemon", log_level, container_id)
    logger.debug("Storlet Daemon started")
    SBus.start_logger("DEBUG", container_id=container_id)

    # Impersonate the swift user
    pw = pwd.getpwnam('swift')
    os.setresgid(pw.pw_gid, pw.pw_gid, pw.pw_gid)
    os.setresuid(pw.pw_uid, pw.pw_uid, pw.pw_uid)

    # create an instance of storlet daemon
    try:
        daemon = Daemon(storlet_name, sbus_path, logger, pool_size)
    except Exception as e:
        logger.error(e.message)
        return EXIT_FAILURE

    # Start the main loop
    return daemon.main_loop()
Exemple #4
0
    def main_loop(self):
        """
        Main loop to run storlet application
        """

        sbus = SBus()
        fd = sbus.create(self.sbus_path)
        if fd < 0:
            self.logger.error("Failed to create SBus. exiting.")
            return EXIT_FAILURE

        while True:
            rc = sbus.listen(fd)
            if rc < 0:
                self.logger.error("Failed to wait on SBus. exiting.")
                return EXIT_FAILURE

            dtg = sbus.receive(fd)
            if dtg is None:
                self.logger.error("Failed to receive message. exiting")
                return EXIT_FAILURE

            if not self.dispatch_command(dtg):
                break

        self.logger.debug('Leaving main loop')
        self._wait_all_child_processes()
        return EXIT_SUCCESS
Exemple #5
0
def main(argv):
    """
    The entry point of daemon_factory process

    :param argv: parameters given from command line
    """
    if (len(argv) != 3):
        usage()
        return EXIT_FAILURE

    pipe_path = argv[0]
    log_level = argv[1]
    container_id = argv[2]

    # Initialize logger
    logger = start_logger("daemon-factory", log_level, container_id)
    logger.debug("Daemon factory started")
    SBus.start_logger("DEBUG", container_id=container_id)

    # Impersonate the swift user
    pw = pwd.getpwnam('swift')
    os.setresgid(pw.pw_gid, pw.pw_gid, pw.pw_gid)
    os.setresuid(pw.pw_uid, pw.pw_uid, pw.pw_uid)

    # create an instance of daemon_factory
    factory = DaemonFactory(pipe_path, logger, container_id)

    # Start the main loop
    return factory.main_loop()
Exemple #6
0
    def _request(self, command, params=None, task_id=None, extra_fds=None):
        read_fd, write_fd = os.pipe()
        try:
            try:
                sfds = \
                    [SBusFileDescriptor(SBUS_FD_SERVICE_OUT, write_fd)] + \
                    (extra_fds or [])
                datagram = build_datagram(command, sfds, params, task_id)
                rc = SBus.send(self.socket_path, datagram)
                if rc < 0:
                    raise SBusClientSendError(
                        'Faild to send command(%s) to socket %s' %
                        (datagram.command, self.socket_path))
            finally:
                # We already sent the write fd to remote, so should close it
                # in local side before reading response
                os.close(write_fd)

            reply = b''
            while True:
                try:
                    buf = os.read(read_fd, self.chunk_size)
                except IOError:
                    raise SBusClientIOError(
                        'Failed to read data from read pipe')
                if not buf:
                    break
                reply = reply + buf
        finally:
            os.close(read_fd)

        if not isinstance(reply, str):
            reply = reply.decode('utf-8')

        return self._parse_response(reply)
Exemple #7
0
    def wait_for_daemon_to_initialize(self, storlet_name):
        """
        Send a Ping service datagram. Validate that
        Daemon response is correct. Give up after the
        predefined number of attempts (5)

        :param storlet_name: Storlet name we are checking the daemon for
        :returns: daemon status (True, False)
        """
        storlet_pipe_name = self.storlet_name_to_pipe_name[storlet_name]
        self.logger.debug('Send PING command to {0} via {1}'.
                          format(storlet_name, storlet_pipe_name))
        read_fd, write_fd = os.pipe()
        try:
            dtg = SBusDatagram.create_service_datagram(
                SBUS_CMD_PING, write_fd)
            for i in range(self.NUM_OF_TRIES_PINGING_STARTING_DAEMON):
                ret = SBus.send(storlet_pipe_name, dtg)
                if ret >= 0:
                    resp = os.read(read_fd, 128)
                    if resp.startswith('True'):
                        return True
                    time.sleep(1)
            else:
                return False
        finally:
            os.close(read_fd)
            os.close(write_fd)
Exemple #8
0
    def ping(self):
        """
        Ping to daemon factory process inside container

        :returns:  1 when the daemon factory is responsive
                   0 when the daemon factory is not responsive
                  -1 when it fails to send command to the process
        """
        pipe_path = self.paths.host_factory_pipe()

        with _open_pipe() as (read_fd, write_fd):
            dtg = SBusServiceDatagram(
                sbus_cmd.SBUS_CMD_PING,
                [write_fd],
                [FDMetadata(sbus_fd.SBUS_FD_SERVICE_OUT).to_dict()])
            rc = SBus.send(pipe_path, dtg)
            if (rc < 0):
                return -1

            reply = os.read(read_fd, 10)

        res, error_txt = self._parse_sandbox_factory_answer(reply)
        if res is True:
            return 1
        self.logger.error('Failed to ping to daemon factory: %s' % error_txt)
        return 0
Exemple #9
0
    def get_storlet_daemon_status(self, storlet_id):
        """
        Get the status of SDaemon process in the scope's sandbox
        """
        with _open_pipe() as (read_fd, write_fd):
            dtg = SBusServiceDatagram(
                sbus_cmd.SBUS_CMD_DAEMON_STATUS,
                [write_fd],
                [FDMetadata(sbus_fd.SBUS_FD_SERVICE_OUT).to_dict()],
                {'storlet_name': storlet_id})
            pipe_path = self.paths.host_factory_pipe()
            rc = SBus.send(pipe_path, dtg)
            if (rc < 0):
                self.logger.info("Failed to send status command to %s %s" %
                                 (self.scope, storlet_id))
                return -1

            reply = os.read(read_fd, 10)

        res, error_txt = self._parse_sandbox_factory_answer(reply)
        if res is True:
            return 1
        self.logger.error('Failed to get status about storlet daemon: %s' %
                          error_txt)
        return 0
Exemple #10
0
    def start_storlet_daemon(self, spath, storlet_id, language):
        """
        Start SDaemon process in the scope's sandbox

        """
        prms = {'daemon_language': language.lower(),
                'storlet_path': spath,
                'storlet_name': storlet_id,
                'uds_path': self.paths.sbox_storlet_pipe(storlet_id),
                'log_level': self.storlet_daemon_debug_level,
                'pool_size': self.storlet_daemon_thread_pool_size}

        with _open_pipe() as (read_fd, write_fd):
            dtg = SBusDatagram.create_service_datagram(
                sbus_cmd.SBUS_CMD_START_DAEMON,
                write_fd,
                prms)

            pipe_path = self.paths.host_factory_pipe()
            rc = SBus.send(pipe_path, dtg)
            # TODO(takashi): Why we should rond rc into -1?
            if (rc < 0):
                return -1

            reply = os.read(read_fd, 10)

        res, error_txt = self._parse_sandbox_factory_answer(reply)
        if res is True:
            return 1
        self.logger.error('Failed to start storlet daemon: %s' % error_txt)
        return 0
Exemple #11
0
    def ping(self):
        """
        Ping to daemon factory process inside container

        :returns:  1 when the daemon factory is responsive
                   0 when the daemon factory is not responsive
                  -1 when it fails to send command to the process
        """
        pipe_path = self.paths.host_factory_pipe()

        with _open_pipe() as (read_fd, write_fd):
            dtg = SBusDatagram.create_service_datagram(
                sbus_cmd.SBUS_CMD_PING,
                write_fd)
            rc = SBus.send(pipe_path, dtg)
            if (rc < 0):
                return -1

            reply = os.read(read_fd, 10)

        res, error_txt = self._parse_sandbox_factory_answer(reply)
        if res is True:
            return 1
        self.logger.error('Failed to ping to daemon factory: %s' % error_txt)
        return 0
Exemple #12
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")
Exemple #13
0
def main():
    """
    The entry point of daemon_factory process
    """
    parser = argparse.ArgumentParser(
        description='Daemon process to execute storlet applications')
    parser.add_argument('storlet_name', help='storlet name')
    parser.add_argument('sbus_path', help='the path to unix domain socket')
    parser.add_argument('log_level', help='log level')
    parser.add_argument('pool_size',
                        type=int,
                        help='the maximun thread numbers used swapns for '
                        'one storlet application')
    parser.add_argument('container_id', help='container id')
    opts = parser.parse_args()

    # Initialize logger
    logger = get_logger("storlets-daemon", opts.log_level, opts.container_id)
    logger.debug("Storlet Daemon started")

    try:
        SBus.start_logger("DEBUG", container_id=opts.container_id)

        # Impersonate the swift user
        pw = pwd.getpwnam('swift')
        os.setresgid(pw.pw_gid, pw.pw_gid, pw.pw_gid)
        os.setresuid(pw.pw_uid, pw.pw_uid, pw.pw_uid)

        # create an instance of storlet daemon
        daemon = StorletDaemon(opts.storlet_name, opts.sbus_path, logger,
                               opts.pool_size)

        # Start the main loop
        sys.exit(daemon.main_loop())

    except Exception:
        logger.error('Unhandled exception')
        sys.exit(EXIT_FAILURE)
Exemple #14
0
    def _send_execute_command(self):
        """
        Send execute command to the remote daemon factory to invoke storlet
        execution
        """
        dtg = SBusDatagram(
            sbus_cmd.SBUS_CMD_EXECUTE,
            self.remote_fds,
            self.remote_fds_metadata,
            self.srequest.params)
        rc = SBus.send(self.storlet_pipe_path, dtg)

        if (rc < 0):
            raise StorletRuntimeException("Failed to send execute command")
Exemple #15
0
    def main_loop(self):
        """
        The 'internal' loop. Listen to SBus, receive datagram,
        dispatch command, report back.

        :returns: exit status (SUCCESS/FAILURE)
        """

        # Create SBus. Listen and process requests
        sbus = SBus()
        fd = sbus.create(self.pipe_path)
        if fd < 0:
            self.logger.error("Failed to create SBus. exiting.")
            return EXIT_FAILURE

        while True:
            rc = sbus.listen(fd)
            if rc < 0:
                self.logger.error("Failed to wait on SBus. exiting.")
                return EXIT_FAILURE
            self.logger.debug("Wait returned")

            dtg = sbus.receive(fd)
            # TODO(eranr):
            # Should we really be exitting here.
            # If so should we exit the container altogether, so
            # that it gets restarted?
            if dtg is None:
                self.logger.error("Failed to receive message. exiting.")
                return EXIT_FAILURE

            if not self.dispatch_command(dtg):
                break

        # We left the main loop for some reason. Terminating.
        self.logger.debug('Leaving main loop')
        return EXIT_SUCCESS
Exemple #16
0
 def _cancel(self):
     """
     Cancel on-going storlet execution
     """
     with _open_pipe() as (read_fd, write_fd):
         dtg = SBusDatagram.create_service_datagram(
             sbus_cmd.SBUS_CMD_CANCEL,
             write_fd,
             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 reponse here
         os.read(read_fd, 10)
Exemple #17
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)
Exemple #18
0
    def shutdown_process(self, storlet_name):
        """
        send HALT command to storlet daemon

        :param storlet_name: Storlet name we are checking the daemon for
        :raises SDaemonError: when wailed to shutdown the storlet daemon
        """
        self.logger.debug(
            'Shutdown the storlet daemon {0}'.format(storlet_name))

        dmn_pid = self.storlet_name_to_pid.get(storlet_name)
        self.logger.debug('Storlet Daemon PID is {0}'.format(dmn_pid))
        if dmn_pid is None:
            raise SDaemonError('{0} is not found'.format(storlet_name))

        storlet_pipe_name = self.storlet_name_to_pipe_name[storlet_name]
        self.logger.debug('Send HALT command to {0} via {1}'.
                          format(storlet_name, storlet_pipe_name))

        read_fd, write_fd = os.pipe()
        try:
            dtg = SBusDatagram.create_service_datagram(
                SBUS_CMD_HALT, write_fd)
            rc = SBus.send(storlet_pipe_name, dtg)
            os.close(write_fd)
            if rc < 0:
                raise SDaemonError(
                    'Failed to send halt to {0}'.format(storlet_name))
            resp = os.read(read_fd, 128)
            if not resp.startswith('True'):
                raise SDaemonError(
                    'Failed to send halt to {0}'.format(storlet_name))
        finally:
            os.close(read_fd)

        try:
            os.waitpid(dmn_pid, 0)
            self.storlet_name_to_pid.pop(storlet_name)
        except OSError:
            self.logger.exception(
                'Error when waiting the storlet daemon {0}'.format(
                    storlet_name))
            raise SDaemonError('Failed to wait {0}'.format(storlet_name))
def main(argv):
    if len(argv) < 2:
        print_usage(argv)
        return

    daemon_factory_pipe_name = argv[1]
    try:
        fi, fo = os.pipe()
        halt_dtg = SBusDatagram.create_service_datagram(
            SBUS_CMD_HALT, fo)
        n_status = SBus.send(daemon_factory_pipe_name, halt_dtg)
        if n_status < 0:
            print('Sending failed')
        else:
            print('Sending succeeded')
            cmd_response = os.read(fi, 256)
            print(cmd_response)
    finally:
        os.close(fi)
        os.close(fo)
Exemple #20
0
def main(argv):
    if len(argv) < 2:
        print_usage(argv)
        return

    daemon_factory_pipe_name = argv[1]
    try:
        fi, fo = os.pipe()
        halt_dtg = SBusServiceDatagram(
            SBUS_CMD_HALT, [fo], [FDMetadata(SBUS_FD_SERVICE_OUT).to_dict()])
        n_status = SBus.send(daemon_factory_pipe_name, halt_dtg)
        if n_status < 0:
            print('Sending failed')
        else:
            print('Sending succeeded')
            cmd_response = os.read(fi, 256)
            print(cmd_response)
    finally:
        os.close(fi)
        os.close(fo)
Exemple #21
0
    def stop_storlet_daemon(self, storlet_id):
        """
        Stop SDaemon process in the scope's sandbox
        """
        with _open_pipe() as (read_fd, write_fd):
            dtg = SBusDatagram.create_service_datagram(
                sbus_cmd.SBUS_CMD_STOP_DAEMON,
                write_fd,
                {'storlet_name': storlet_id})
            pipe_path = self.paths.host_factory_pipe()
            rc = SBus.send(pipe_path, dtg)
            if (rc < 0):
                self.logger.info("Failed to send status command to %s %s" %
                                 (self.scope, storlet_id))
                return -1

            reply = os.read(read_fd, 10)

        res, error_txt = self._parse_sandbox_factory_answer(reply)
        if res is True:
            return 1
        self.logger.error('Failed to stop storlet daemon: %s' % error_txt)
        return 0
Exemple #22
0
    def start_storlet_daemon(
            self, spath, storlet_id, language, language_version=None):
        """
        Start SDaemon process in the scope's sandbox

        """
        prms = {'daemon_language': language.lower(),
                'storlet_path': spath,
                'storlet_name': storlet_id,
                'uds_path': self.paths.sbox_storlet_pipe(storlet_id),
                'log_level': self.storlet_daemon_debug_level,
                'pool_size': self.storlet_daemon_thread_pool_size}

        if language_version:
            prms.update({'daemon_language_version': language_version})

        with _open_pipe() as (read_fd, write_fd):
            dtg = SBusServiceDatagram(
                sbus_cmd.SBUS_CMD_START_DAEMON,
                [write_fd],
                [FDMetadata(sbus_fd.SBUS_FD_SERVICE_OUT).to_dict()],
                prms)

            pipe_path = self.paths.host_factory_pipe()
            rc = SBus.send(pipe_path, dtg)
            # TODO(takashi): Why we should rond rc into -1?
            if (rc < 0):
                return -1

            reply = os.read(read_fd, 10)

        res, error_txt = self._parse_sandbox_factory_answer(reply)
        if res is True:
            return 1
        self.logger.error('Failed to start storlet daemon: %s' % error_txt)
        return 0