Ejemplo n.º 1
0
def chat_with_a_client(sock, addr, instance_globals, container):
    connection = ServerCommandConnection(sock)
    instance = {'globals': instance_globals, 'connection': connection}
    try:
        sock.send(b'Papa is home. Type "help" for commands.\n> ')

        while True:
            one_line = connection.readline()
            args = []
            acc = ''
            if one_line:
                for arg in one_line.split(' '):
                    if arg:
                        if arg[-1] == '\\':
                            acc += arg[:-1] + ' '
                        else:
                            acc += arg
                            args.append(acc.strip())
                            acc = ''
                if acc:
                    args.append(acc)

                try:
                    command = lookup_command(args)
                except Error as e:
                    reply = 'Error: {0}\n'.format(e)
                else:
                    try:
                        reply = command(sock, args, instance) or '\n'
                    except CloseSocket as e:
                        if e.final_message:
                            send_with_retry(sock, cast_bytes(e.final_message))
                        break
                    except papa.utils.Error as e:
                        reply = 'Error: {0}\n'.format(e)
                    except Exception as e:
                        reply = 'Error: {0}\n'.format(e)

                if reply[-1] != '\n':
                    reply += '\n> '
                else:
                    reply += '> '
                reply = cast_bytes(reply)
            else:
                reply = b'> '
            send_with_retry(sock, reply)
    except socket.error:
        pass

    try:
        sock.close()
    except socket.error:
        pass

    if container:
        thread_object = container[0]
        instance_globals['active_threads'].remove(thread_object)
        instance_globals['inactive_threads'].append((addr, thread_object))
Ejemplo n.º 2
0
def chat_with_a_client(sock, addr, instance_globals, container):
    connection = ServerCommandConnection(sock)
    instance = {'globals': instance_globals, 'connection': connection}
    try:
        sock.send(b'Papa is home. Type "help" for commands.\n> ')

        while True:
            one_line = connection.readline()
            args = []
            acc = ''
            if one_line:
                for arg in one_line.split(' '):
                    if arg:
                        if arg[-1] == '\\':
                            acc += arg[:-1] + ' '
                        else:
                            acc += arg
                            args.append(acc.strip())
                            acc = ''
                if acc:
                    args.append(acc)

                try:
                    command = lookup_command(args)
                except Error as e:
                    reply = 'Error: {0}\n'.format(e)
                else:
                    try:
                        reply = command(sock, args, instance) or '\n'
                    except CloseSocket as e:
                        if e.final_message:
                            send_with_retry(sock, cast_bytes(e.final_message))
                        break
                    except papa.utils.Error as e:
                        reply = 'Error: {0}\n'.format(e)
                    except Exception as e:
                        reply = 'Error: {0}\n'.format(e)

                if reply[-1] != '\n':
                    reply += '\n> '
                else:
                    reply += '> '
                reply = cast_bytes(reply)
            else:
                reply = b'> '
            send_with_retry(sock, reply)
    except socket.error:
        pass

    try:
        sock.close()
    except socket.error:
        pass

    if container:
        thread_object = container[0]
        instance_globals['active_threads'].remove(thread_object)
        instance_globals['inactive_threads'].append((addr, thread_object))
Ejemplo n.º 3
0
def watch_command(sock, args, instance):
    """Watch a process"""
    instance_globals = instance['globals']
    all_processes = instance_globals['processes']
    with instance_globals['lock']:
        procs = dict((name, {'p': proc, 't': 0, 'closed': False}) for name, proc in wildcard_iter(all_processes, args, True))
    if not procs:
        raise utils.Error('Nothing to watch')
    send_with_retry(sock, cast_bytes('Watching {0}\n'.format(len(procs))))
    return _do_watch(sock, procs, instance)
Ejemplo n.º 4
0
Archivo: proc.py Proyecto: meitham/papa
def _do_watch(sock, procs, instance):
    instance_globals = instance['globals']
    all_processes = instance_globals['processes']
    connection = instance['connection']
    poller = Poller(sock)
    delay = .1
    while True:
        data = []
        for name, proc in procs.items():
            t, l = proc['p'].watch()
            if l:
                for item in l:
                    if item.type == OutputQueue.CLOSED:
                        data.append(
                            cast_bytes('closed:{0}:{1}:{2}'.format(
                                name, item.timestamp, item.data)))
                        proc['closed'] = True
                    else:
                        data.append(
                            cast_bytes('{0}:{1}:{2}:{3}'.format(
                                'out' if item.type == OutputQueue.STDOUT else
                                'err', name, item.timestamp, len(item.data))))
                        data.append(item.data)
                proc['t'] = t
        if data:
            delay = .05
            data.append(b'] ')
            out = b'\n'.join(data)
            send_with_retry(sock, out)

            one_line = connection.readline().lower()
            closed = []
            for name, proc in procs.items():
                t = proc['t']
                if t:
                    proc['p'].remove_output(t)
                    if proc['closed']:
                        closed.append(name)
            if closed:
                with instance_globals['lock']:
                    for name in closed:
                        closed_proc = procs.pop(name, None)
                        if closed_proc and 'p' in closed_proc:
                            log.info('Removed process %s', closed_proc['p'])
                        all_processes.pop(name, None)
            if not procs:
                return 'Nothing left to watch'
            if one_line == 'q':
                return 'Stopped watching'
        else:
            if poller.poll(delay):
                return 'Client closed connection'
            if delay < 1.0:
                delay += .05
Ejemplo n.º 5
0
Archivo: proc.py Proyecto: meitham/papa
def process_command(sock, args, instance):
    """Create a process.
You need to specify a name, followed by name=value pairs for the process
options, followed by the command and args to execute. The name must not contain
spaces.

Process options are:
    uid - the username or user ID to use when starting the process
    gid - the group name or group ID to use when starting the process
    working_dir - must be an absolute path if specified
    output - size of each output buffer (default is 1m)

You can also specify environment variables by prefixing the name with 'env.' and
rlimits by prefixing the name with 'rlimit.'

Examples:
    make process sf uid=1001 gid=2000 working_dir=/sf/bin/ output=1m /sf/bin/uwsgi --ini uwsgi-live.ini --socket fd://27 --stats 127.0.0.1:8090
    make process nginx /usr/local/nginx/sbin/nginx
"""
    if not args:
        raise Error('Process requires a name')
    name = args.pop(0)
    env = {}
    rlimits = {}
    kwargs = {}
    for key, value in extract_name_value_pairs(args).items():
        if key.startswith('env.'):
            env[key[4:]] = value
        elif key.startswith('rlimit.'):
            key = key[7:]
            try:
                rlimits[getattr(resource,
                                'RLIMIT_%s' % key.upper())] = int(value)
            except AttributeError:
                raise utils.Error('Unknown rlimit "%s"' % key)
            except ValueError:
                raise utils.Error(
                    'The rlimit value for "%s" must be an integer, not "%s"' %
                    (key, value))
        else:
            kwargs[key] = value
    watch = int(kwargs.pop('watch', 0))
    p = Process(name, args, env, rlimits, instance, **kwargs)
    with instance['globals']['lock']:
        result = p.spawn()
    if watch:
        send_with_retry(sock, cast_bytes('{0}\n'.format(result)))
        return _do_watch(sock, {name: {
            'p': result,
            't': 0,
            'closed': False
        }}, instance)

    return str(result)
Ejemplo n.º 6
0
Archivo: proc.py Proyecto: meitham/papa
def watch_command(sock, args, instance):
    """Watch a process"""
    instance_globals = instance['globals']
    all_processes = instance_globals['processes']
    with instance_globals['lock']:
        procs = dict((name, {
            'p': proc,
            't': 0,
            'closed': False
        }) for name, proc in wildcard_iter(all_processes, args, True))
    if not procs:
        raise utils.Error('Nothing to watch')
    send_with_retry(sock, cast_bytes('Watching {0}\n'.format(len(procs))))
    return _do_watch(sock, procs, instance)
Ejemplo n.º 7
0
def _do_watch(sock, procs, instance):
    instance_globals = instance['globals']
    all_processes = instance_globals['processes']
    connection = instance['connection']
    poller = Poller(sock)
    delay = .1
    while True:
        data = []
        for name, proc in procs.items():
            t, l = proc['p'].watch()
            if l:
                for item in l:
                    if item.type == OutputQueue.CLOSED:
                        data.append(cast_bytes('closed:{0}:{1}:{2}'.format(name, item.timestamp, item.data)))
                        proc['closed'] = True
                    else:
                        data.append(cast_bytes('{0}:{1}:{2}:{3}'.format('out' if item.type == OutputQueue.STDOUT else 'err', name, item.timestamp, len(item.data))))
                        data.append(item.data)
                proc['t'] = t
        if data:
            delay = .05
            data.append(b'] ')
            out = b'\n'.join(data)
            send_with_retry(sock, out)

            one_line = connection.readline().lower()
            closed = []
            for name, proc in procs.items():
                t = proc['t']
                if t:
                    proc['p'].remove_output(t)
                    if proc['closed']:
                        closed.append(name)
            if closed:
                with instance_globals['lock']:
                    for name in closed:
                        closed_proc = procs.pop(name, None)
                        if closed_proc and 'p' in closed_proc:
                            log.info('Removed process %s', closed_proc['p'])
                        all_processes.pop(name, None)
            if not procs:
                return 'Nothing left to watch'
            if one_line == 'q':
                return 'Stopped watching'
        else:
            if poller.poll(delay):
                return 'Client closed connection'
            if delay < 1.0:
                delay += .05
Ejemplo n.º 8
0
def process_command(sock, args, instance):
    """Create a process.
You need to specify a name, followed by name=value pairs for the process
options, followed by the command and args to execute. The name must not contain
spaces.

Process options are:
    uid - the username or user ID to use when starting the process
    gid - the group name or group ID to use when starting the process
    working_dir - must be an absolute path if specified
    output - size of each output buffer (default is 1m)

You can also specify environment variables by prefixing the name with 'env.' and
rlimits by prefixing the name with 'rlimit.'

Examples:
    make process sf uid=1001 gid=2000 working_dir=/sf/bin/ output=1m /sf/bin/uwsgi --ini uwsgi-live.ini --socket fd://27 --stats 127.0.0.1:8090
    make process nginx /usr/local/nginx/sbin/nginx
"""
    if not args:
        raise Error('Process requires a name')
    name = args.pop(0)
    env = {}
    rlimits = {}
    kwargs = {}
    for key, value in extract_name_value_pairs(args).items():
        if key.startswith('env.'):
            env[key[4:]] = value
        elif key.startswith('rlimit.'):
            key = key[7:]
            try:
                rlimits[getattr(resource, 'RLIMIT_%s' % key.upper())] = int(value)
            except AttributeError:
                raise utils.Error('Unknown rlimit "%s"' % key)
            except ValueError:
                raise utils.Error('The rlimit value for "%s" must be an integer, not "%s"' % (key, value))
        else:
            kwargs[key] = value
    watch = int(kwargs.pop('watch', 0))
    p = Process(name, args, env, rlimits, instance, **kwargs)
    with instance['globals']['lock']:
        result = p.spawn()
    if watch:
        send_with_retry(sock, cast_bytes('{0}\n'.format(result)))
        return _do_watch(sock, {name: {'p': result, 't': 0, 'closed': False}}, instance)

    return str(result)
Ejemplo n.º 9
0
    def close(self):
        if self.connection:
            # if the server is waiting for an ack, we can
            if self._need_ack:
                send_with_retry(self.connection.sock, b'q\n')
                self._need_ack = False
                self.connection.get_full_response()

                # we can only recover the connection if we were able to send
                # the quit ack. otherwise close the connection and let the
                # socket die
                if not self.papa_object.connection:
                    self.papa_object.connection = self.connection
                else:
                    self.connection.close()
            else:
                self.connection.close()
            self.connection = None
Ejemplo n.º 10
0
    def close(self):
        if self.connection:
            # if the server is waiting for an ack, we can
            if self._need_ack:
                send_with_retry(self.connection.sock, b'q\n')
                self._need_ack = False
                self.connection.get_full_response()

                # we can only recover the connection if we were able to send
                # the quit ack. otherwise close the connection and let the
                # socket die
                if not self.papa_object.connection:
                    self.papa_object.connection = self.connection
                else:
                    self.connection.close()
            else:
                self.connection.close()
            self.connection = None
Ejemplo n.º 11
0
 def acknowledge(self):
     if self._need_ack:
         send_with_retry(self.connection.sock, b'\n')
         self._need_ack = False
Ejemplo n.º 12
0
 def send_command(self, command):
     if isinstance(command, list):
         command = ' '.join(c.replace(' ', '\ ').replace('\n', '\ ') for c in command if c)
     command = b(command)
     send_with_retry(self.sock, command + b'\n')
Ejemplo n.º 13
0
import sys
import socket
from papa.utils import cast_string, send_with_retry, recv_with_retry

__author__ = 'Scott Maxwell'

if len(sys.argv) != 2:
    sys.stderr.write('Need one port number\n')
    sys.exit(1)

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('127.0.0.1', int(sys.argv[1])))

send_with_retry(sock, b'howdy\n')
data = recv_with_retry(sock)
sys.stdout.write(cast_string(data))

sock.close()
Ejemplo n.º 14
0
import sys
import socket
from papa.utils import cast_string, send_with_retry, recv_with_retry

__author__ = 'Scott Maxwell'

if len(sys.argv) != 2:
    sys.stderr.write('Need one file descriptor\n')
    sys.exit(1)

listen_socket = socket.fromfd(int(sys.argv[1]), socket.AF_INET, socket.SOCK_STREAM)
sock, address = listen_socket.accept()

while True:
    data = recv_with_retry(sock)
    if data:
        send_with_retry(sock, data)
        sys.stdout.write(cast_string(data))
    else:
        break

sock.close()
Ejemplo n.º 15
0
 def acknowledge(self):
     if self._need_ack:
         send_with_retry(self.connection.sock, b'\n')
         self._need_ack = False
Ejemplo n.º 16
0
 def send_command(self, command):
     if isinstance(command, list):
         command = ' '.join(
             c.replace(' ', '\ ').replace('\n', '\ ') for c in command if c)
     command = b(command)
     send_with_retry(self.sock, command + b'\n')