Beispiel #1
0
def remove_progs():
    log.info('Removing programs')
    log.debug('Removing programs: {}'.format(dashboard.prog_to_remove))
    stop_programs(None, dashboard.prog_to_remove)
    for prog_name in dashboard.prog_to_remove:
        prog = dashboard.programs.pop(prog_name, None)
        for process in prog.processes:
            dashboard.name_procs.pop(process.name)
Beispiel #2
0
def launch_manager():
    """
    Launches all programs in the list contained in the dashboard
    :return:
    """
    log.info('starting launch_manager')
    # kill old programs in reload or create reload_manager
    log.info('debug: fds_buff: {0}'.format(dashboard.fds_buff.keys()))
    for program in dashboard.programs.values():
        launch_program(program)
Beispiel #3
0
def serve_relaod(cs, query_list):
    log.info('serving: reload: {0}'.format(query_list))
    if len(query_list) < 2:
        utils.socket_send(cs, 'err: config file is required')
        return
    config_server = tm_config.ConfigServer(query_list[1])
    if not config_server.valid:
        log.debug('invalid config has occurred')
        utils.socket_send(cs, 'warn: the config is invalid')
        return
    new_programs = mod_dash.load_programs(config_server.data)
    utils.thread_start(reload_launch_manager, (new_programs, ))
Beispiel #4
0
def serve_status(cs, query_list):
    log.info('serving: status: {0}'.format(query_list))
    if len(query_list) > 1:
        prog_names = query_list[1:]
    else:
        prog_names = list(dashboard.programs.keys())
        log.debug('something good')
    for prog_name in prog_names:
        utils.socket_send(cs, 'program status: {0}'.format(prog_name))
        program = dashboard.programs.get(prog_name)
        for process in program.processes:
            utils.socket_send(
                cs, '\t{0} status {1}'.format(process.name, process.state))
def serve_client(cs, addr, configServer):
    while True:
        # query = cs.recv(1024).decode('utf-8')
        query = utils.socket_recv(cs)
        if query == '':
            continue
        query_list = query.split()
        log.info('query: {0}'.format(query_list))
        # utils.socket_send(cs, 'something from server')
        if query_list[0] in services.keys():
            log.info('found service')
            service = services.get(query_list[0])
            service(cs, query_list)
        utils.socket_send(cs, '\r')
Beispiel #6
0
def reload_launch_manager(new_programs: {str: Program}):
    log.info('starting reload launch manager')
    old_programs = dashboard.programs
    nprog_names = list(new_programs.keys())
    oprog_names = list(old_programs.keys())
    for oprog_name, oprog in old_programs.items():
        if oprog_name not in nprog_names:
            dashboard.prog_to_remove.append(oprog_name)
        else:
            nprog = new_programs.get(oprog_name)
            if nprog.cmd is not oprog.cmd \
                or nprog.numprocs is not oprog.numprocs\
                or nprog.argv is not oprog.argv\
                or nprog.wdir is not oprog.wdir:
                dashboard.prog_to_remove.append(oprog_name)
                remove_progs()
                dashboard.programs[oprog_name] = nprog
                launch_program(nprog)
Beispiel #7
0
 def authenticate(self) -> bool:
     if not self.config.username:
         self.config.username = input("Enter username: "******"Enter password: "******"Enter password: ")
     query = 'auth\r\n{0}\r\n{1}\r\n'\
         .format(self.config.username, self.config.password)
     self.csocket.send(query.encode('utf-8'))
     response = self.csocket.recv(1024).decode('utf-8')
     log.debug('received {0} from server'.format(response))
     response = response.rsplit('\r\n')
     log.debug('response list {0}'.format(response))
     if response[0] != 'OK':
         log.info('failed to authenticate with response: {0}'.format(
             response[0]))
         self.config.password = None
         return False
     return True
Beispiel #8
0
def launch_program(program: Program, force_start=False):
    """
    Launches a program by launching all the processes created by this program
    if the start is forced by client or autostart is enabled then
    Otherwise, all processes will be moved to STOPPED state.
    :param program: Program object to be launched.
    :param force_start: True if client requesting a start.
    :return:
    """
    if not program or not isinstance(program, Program):
        return
    log.info('launching program {0}, umask={1}'.format(program.name,
                                                       program.umask))
    log.info('launching {0}'.format(program.cmd.split(' ')))
    for process in program.processes:
        log.debug('Starting new process !')
        # dashboard.name_procs[process.name] = process # move to higher level
        log.debug('AUTO_START -------- {} === {}'.format(
            program.autostart, configmap.Start.NO))
        if program.autostart is False:
            process.state = ProcessState.STOPPED
        else:
            launch_process(program, process)
Beispiel #9
0
def state_manager():
    # os.mkdir('/tmp/statedir')
    log.info('starting state_manager')

    while True:
        log.info('checking processes state')
        for pid_exit in list(dashboard.pid_wexit):
            log.info('updating state of pid: {0}'.format(pid_exit[0]))
            process = dashboard.pid_procs.get(pid_exit[0])
            program = dashboard.programs.get(process.program_name)

            try:
                process.control_starting_state(program)
                if process.to_remove:
                    clean_proccess(process, ProcessState.REMOVED)
                    program.processes.pop(process.name)
                if process.state == ProcessState.RUNNING:
                    log.info('process {0} exited with code {1}'.format(
                        pid_exit[0], pid_exit[1]))
                    clean_proccess(process, ProcessState.EXITED)
                    log.info('process {0} has been cleaned'.format(
                        pid_exit[0]))
                    if pid_exit[1] in program.exitcodes:
                        if program.autorestart == 'true':
                            launch_process(program, process)
                    elif program.autorestart == 'unexpected':
                        launch_process(program, process)
                elif process.state == ProcessState.STOPPING:
                    clean_proccess(process, ProcessState.STOPPED)
                elif process.state == ProcessState.BACKOFF:
                    clean_proccess(process, ProcessState.FATAL)
                    launch_process(program, process, retry=True)
            except OSError as err:
                process.state = ProcessState.UNKNOWN

            dashboard.pid_wexit.remove(pid_exit)
        time.sleep(1)
Beispiel #10
0
def serve_restart(cs, query_list):
    log.info('serving: restart: {0}'.format(query_list))
    prog_names = query_list[1:]
    for prog_name in prog_names:
        if prog_name not in dashboard.programs.keys():
            utils.socket_send(cs, 'program {0} not found'.format(prog_name))
        else:
            utils.socket_send(cs, 'restarting {0}'.format(prog_name))
            program = dashboard.programs.get(prog_name)
            for process in program.process:
                utils.socket_send(
                    cs, 'process {0} is in {1} state'.format(
                        process.name, process.state))
                if process.state == ProcessState.STARTING \
                        or process.state == ProcessState.BACKOFF \
                        or process.state == ProcessState.RUNNING:
                    utils.socket_send(
                        cs, 'stopping process {0}'.format(process.name))
                    #kill process
                    utils.thread_start(kill_process,
                                       (process, program.stopsig))
                    utils.socket_send(
                        cs, 'starting process: {0}'.format(process.name))
                    launch_process(program, process)
Beispiel #11
0
def serve_start(cs, query_list):
    log.info('serving: start: {0}'.format(query_list))
    # utils.socket_send(cs, 'something there from start')
    # utils.socket_send(cs, '\r')
    prog_names = query_list[1:]
    log.debug('prog_names: {0}'.format(prog_names))
    for prog_name in prog_names:
        if prog_name not in dashboard.programs.keys():
            utils.socket_send(cs, 'program {0} not found'.format(prog_name))
        else:
            utils.socket_send(cs, 'starting {0}'.format(prog_name))
            program = dashboard.programs.get(prog_name)
            changed = 0
            for process in program.processes:
                utils.socket_send(
                    cs, 'process {0} is in {1} state'.format(
                        process.name, process.state))
                if process.state != ProcessState.STARTING \
                        and process.state != ProcessState.BACKOFF \
                        and process.state != ProcessState.RUNNING:
                    # see if it needs to reset retries
                    utils.socket_send(
                        cs, 'starting process: {0}'.format(process.name))
                    launch_process(program, process)
Beispiel #12
0
def buff_manager():
    """\
    Buffer Manager is responsible for dispatching
    standard out/err flow of running processes by
    by selecting open fds which are ready to read from
    and transport the data to the appropriate files.
    """
    log.info('starting buff_manager')

    while 1:
        time.sleep(TIME_SLEEP)
        log.debug('checking fds')
        fds = list(dashboard.fds_buff.keys())
        if not len(fds):
            log.debug('empty fd list')
            continue
        rfds = []
        try:  # select open fds which are ready to read from
            rfds, wfds, xfds = select(fds, [], [])
        except OSError:
            log.error('error occurred upon select fds')
            continue
        log.info('found some fds: {0}'.format(rfds))
        for fd in rfds:  # transporting data from each open fd
            log.info('fd={0} ready to write in {1}'.format(
                fd, dashboard.fds_buff.get(fd)))
            data = None
            try:
                data = os.read(fd, BUFF_SIZE)
            except OSError as err:
                log.error('Failed to read from fd={0}'.format(fd))
            if not data:
                if fd in dashboard.fds_zombie:  # close and remove the fd if it's in zombie list
                    dashboard.fds_zombie.remove(fd)
                    os.close(fd)
                    dashboard.fds_buff.pop(fd)
                continue
            file = dashboard.fds_buff.get(
                fd)  # get the linked file from the dashboard
            if isinstance(file, pathlib.Path):
                if not file.exists():
                    file.touch(exist_ok=True)
                with file.open('a') as f:
                    f.write(data.decode(DECODE_FORMAT))
Beispiel #13
0
def launch_process(program: Program, process: Process, retry: bool = False):
    """
    Launches a process and update the dashboard by the pid of the launched process
    and the opened file descriptors.
    :param program: Parent program of the process.
    :param process: The process to be launched.
    :param retry: True if the process is being restarted from a retry
    :return:
    """
    log.info('launching process: {0}'.format(process.name))
    if retry:
        process.retries = process.retries - 1
        if process.retries < 1:
            return
    while process.state == ProcessState.STOPPING:  # recheck
        time.sleep(1)
    pid, fds = process.exec(program)
    dashboard.pid_procs[pid] = process
    dashboard.fds_buff.update(fds)
    log.info('process {0} has been executed with pid={1}'.format(
        process.name, pid))
    for fd, file in fds.items():
        log.info('fd={0} file={1}'.format(fd, file))
    dashboard.name_procs[process.name] = process  # move to higher level
Beispiel #14
0
def serve_stop(cs, query_list):
    log.info('serving: stop: {0}'.format(query_list))
    prog_names = query_list[1:]
    stop_programs(cs, prog_names)
Beispiel #15
0
def serve_shutdown(cs, query_list):
    log.info("Shutting down !")
    stop_programs(cs, dashboard.programs.keys())
    utils.socket_send(cs, 'Shutting down all programs!')
Beispiel #16
0
def service_manager(cs: socket.socket, addr, config):
    username, auth = authenticate_client(cs, addr, config)
    if not auth:
        log.info('client {0} failed to authenticate'.format(username))
        return
    serve_client(cs, addr, config)
Beispiel #17
0
    def run(self):
        log.info('running the server daemon')

        log.info('binding the server socket')
        self.socket_bound = socket_bind(self.socket,
                                        (self.config.host, self.config.port))

        log.info('starting thread: state_handler')
        thread_start(state_manager, ())  # not none
        # thread	-> buff_handler
        log.info('starting thread: buff_manager')
        thread_start(buff_manager, ())  # not none

        # thread	-> launch_handler
        log.info('starting thread: launch_manager')
        thread_start(launch_manager, ())  # not none

        log.info('starting thread: clients_manager')
        thread_start(clients_manager, (self, ))

        time.sleep(20)
        log.info('Server Daemon run ends !')