def shutdown_process(self, storlet_name): """ send HALT command to storlet daemon :param storlet_name: Storlet name we are checking the daemon for :returns: Status """ b_status = False self.logger.debug('Inside shutdown_process {0}'.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)) # TODO(takashi): We had better use contextmanager read_fd, write_fd = os.pipe() dtg = SBusDatagram.create_service_datagram(SBUS_CMD_HALT, write_fd) SBus.send(storlet_pipe_name, dtg) os.close(read_fd) os.close(write_fd) dmn_pid = self.storlet_name_to_pid.get(storlet_name, -1) self.logger.debug('Storlet Daemon PID is {0}'.format(dmn_pid)) if -1 != dmn_pid: os.waitpid(dmn_pid, 0) self.storlet_name_to_pid.pop(storlet_name) b_status = True return b_status
def main(argv): ''' @summary: main The entry point. - Initialize logger, - impersonate to swift user, - create an instance of daemon_factory, - start the main loop. ''' if (len(argv) != 2): usage() return pipe_path = argv[0] log_level = argv[1] logger = start_logger("daemon_factory", log_level) logger.debug("Daemon factory started") SBus.start_logger("DEBUG") # 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) factory = daemon_factory(pipe_path, logger) factory.main_loop()
def shutdown_process(self, storlet_name): ''' @summary: send HALT command to storlet daemon @param storlet_name: Storlet name we are checking the daemon for @type storlet_name: String @return: Status @rtype: Boolean @return: Description text of possible error @rtype: String ''' b_status = False error_text = '' self.logger.debug('Inside shutdown_process {0}'.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() dtg = SBusDatagram.create_service_datagram(SBUS_CMD_HALT, write_fd) SBus.send(storlet_pipe_name, dtg) os.close(read_fd) os.close(write_fd) dmn_pid = self.storlet_name_to_pid.get(storlet_name, -1) self.logger.debug('Storlet Daemon PID is {0}'.\ format(dmn_pid)) if -1 != dmn_pid: os.waitpid(dmn_pid,0) self.storlet_name_to_pid.pop(storlet_name) b_status = True return b_status
def main(argv): """ The entry point of daemon_factory process :param argv: parameters given from command line """ if (len(argv) != 3): usage() # TODO(takashi): returning non-zero value is better? return 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 = daemon_factory(pipe_path, logger) # Start the main loop factory.main_loop(container_id)
def main_loop(self, container_id): """ The 'internal' loop. Listen to SBus, receive datagram, dispatch command, report back. :param container_id: container id :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. Exitting.") return EXIT_FAILURE outfd = dtg.get_service_out_fd() if outfd is None: self.logger.error("Received message does not have outfd." " continuing.") continue self.logger.debug("Received outfd %d" % outfd) with os.fdopen(outfd, 'w') as outfile: resp = self.dispatch_command(dtg, container_id) self.log_and_report(outfile, resp) if not resp.iterable: break # We left the main loop for some reason. Terminating. self.logger.debug('Leaving main loop') return EXIT_SUCCESS
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 = ClientSBusOutDatagram.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: if os.read(read_fd, 128) == 'OK': return True time.sleep(1) else: return False finally: os.close(read_fd) os.close(write_fd)
def start_storlet_daemon(self, spath, storlet_id): """ Start SDaemon process in the account's sandbox """ prms = {} prms['daemon_language'] = 'java' prms['storlet_path'] = spath prms['storlet_name'] = storlet_id prms['uds_path'] = self.paths.sbox_storlet_pipe(storlet_id) prms['log_level'] = self.storlet_daemon_debug_level prms['pool_size'] = self.storlet_daemon_thread_pool_size with _open_pipe() as (read_fd, write_fd): dtg = SBusDatagram.create_service_datagram(SBUS_CMD_START_DAEMON, write_fd) dtg.set_exec_params(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 return 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: (Status, Description text of possible error) """ 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)) # TODO(takashi): We had better use contextmanager read_fd, write_fd = os.pipe() dtg = SBusDatagram.create_service_datagram(SBUS_CMD_PING, write_fd) b_status = False error_text = "Daemon isn't responding" 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 'OK' == resp: b_status = True error_text = 'OK' break time.sleep(1) os.close(read_fd) os.close(write_fd) return b_status, error_text
def main_loop(self, container_id): """ The 'internal' loop. Listen to SBus, receive datagram, dispatch command, report back. """ # 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 b_iterate = True b_status = True error_text = '' while b_iterate: rc = sbus.listen(fd) if rc < 0: self.logger.error("Failed to wait on SBus. exiting.") return self.logger.debug("Wait returned") dtg = sbus.receive(fd) if not dtg: self.logger.error("Failed to receive message. exiting.") return try: # TODO(takashi): We had better use contextmanager outfd = dtg.get_first_file_of_type(SBUS_FD_OUTPUT_OBJECT) except Exception: self.logger.error("Received message does not have outfd." " continuing.") continue else: self.logger.debug("Received outfd %d" % outfd.fileno()) b_status, error_text, b_iterate = \ self.dispatch_command(dtg, container_id) self.log_and_report(outfd, b_status, error_text) outfd.close() # We left the main loop for some reason. Terminating. self.logger.debug('Leaving main loop')
def _cancel(self): with _open_pipe() as (read_fd, write_fd): dtg = SBusDatagram.create_service_datagram(SBUS_CMD_CANCEL, write_fd) dtg.set_task_id(self.task_id) rc = SBus.send(self.storlet_pipe_path, dtg) if (rc < 0): raise StorletRuntimeException('Failed to cancel task') os.read(read_fd, 10)
def _invoke(self): dtg = ClientSBusOutDatagram( 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") self._wait_for_read_with_timeout(self.execution_str_read_fd) self.task_id = os.read(self.execution_str_read_fd, 10) os.close(self.execution_str_read_fd)
def _invoke(self): dtg = SBusDatagram() dtg.set_files(self.fds) dtg.set_metadata(self.fdmd) dtg.set_exec_params(self.srequest.params) dtg.set_command(SBUS_CMD_EXECUTE) rc = SBus.send(self.storlet_pipe_path, dtg) if (rc < 0): raise StorletRuntimeException("Failed to send execute command") self._wait_for_read_with_timeout(self.execution_str_read_fd) self.task_id = os.read(self.execution_str_read_fd, 10) os.close(self.execution_str_read_fd)
def ping(self): pipe_path = self.paths.host_factory_pipe() with _open_pipe() as (read_fd, write_fd): dtg = SBusDatagram.create_service_datagram(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 return 0
def _cancel(self): """ Cancel on-going storlet execution """ with _open_pipe() as (read_fd, write_fd): dtg = ClientSBusOutDatagram.create_service_datagram( 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)
def main(argv): if 2 > len(argv): print_usage(argv) return daemon_factory_pipe_name = argv[1] 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 0 > n_status: print 'Sending failed' else: print 'Sending succeeded' cmd_response = os.read(fi, 256) print cmd_response os.close(fi) os.close(fo)
def main(argv): if 2 > len(argv): print_usage(argv) return daemon_factory_pipe_name = argv[1] fi, fo = os.pipe() halt_dtg = ClientSBusOutDatagram.create_service_datagram(SBUS_CMD_HALT, fo) n_status = SBus.send(daemon_factory_pipe_name, halt_dtg) if 0 > n_status: print('Sending failed') else: print('Sending succeeded') cmd_response = os.read(fi, 256) print(cmd_response) os.close(fi) os.close(fo)
def _invoke(self): """ Send an execution command to the remote daemon factory """ dtg = ClientSBusOutDatagram( 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") self._wait_for_read_with_timeout(self.execution_str_read_fd) # TODO(kota_): need an assertion for task_id format self.task_id = os.read(self.execution_str_read_fd, 10) os.close(self.execution_str_read_fd)
def get_storlet_daemon_status(self, storlet_id): """ Get the status of SDaemon process in the account's sandbox """ with _open_pipe() as (read_fd, write_fd): dtg = SBusDatagram.create_service_datagram(SBUS_CMD_DAEMON_STATUS, write_fd) dtg.add_exec_param('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.account, 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 return 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 = ClientSBusOutDatagram.create_service_datagram( 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 return 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 = ClientSBusOutDatagram.create_service_datagram( 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 return 0