Пример #1
0
    def create(self, image, *command_args, **config):
        command = self.base_command()
        if config is None:
            config = dict()
        if config.get('run') is True:
            command.append('run')
            if config.get('detach') is True:
                command.append('--detach')
        else:
            command.append('create')
        command.append('--name', self.name)

        if config.get('tty') is not None:
            command.append('--tty')
        if config.get('interactive') is not None:
            command.append('--interactive')
        if config.get('privileged') is True:
            command.append('--privileged')
        if config.get('user') is not None:
            command.append('--user', config.get('user'))
        for cap in config.get('capabilities', list()):
            command.append('--cap-add', cap)
        if config.get('device') is not None:
            command.append('--device', config.get('device'))
        for env_var in config.get('environment', dict()):
            value = config.get('environment')[env_var]
            if value is True:
                value = 'true'
            elif value is False:
                value = 'false'
            elif isinstance(value, dict) or isinstance(value, list):
                value = json.dumps(value)
            command.append('--env', '%s=%s' % (env_var, str(value)))
        for exp_port in config.get('expose', list()):
            command.append('--expose', exp_port)
        for link in config.get('links', list()):
            if not re.match(r'.+:.+', link):
                printe('Error: In {name}, the link "{link}" does not contain'
                       ' both a container name and an alias. '
                       'Example = name:alias'.format(
                           name=self.name,
                           link=link,
                       ),
                       terminate=True)
            command.append('--link', link)
        if config.get('net') is not None:
            command.append('--net', config.get('net'))
        if config.get('ports') is not None:
            ip = self.machine.ip() if self.machine is not None else None
            for port in config.get('ports'):
                if not re.match(r'.+:.+', port):
                    printe('Error: In {name}, the port "{port}" does not '
                           'contain both internal and external port.'.format(
                               self.name, port),
                           terminate=True)
                if ip and port.startswith(':'):
                    port = ip + port
                command.append('-p', port)
        if config.get('restart') is True:
            command.append('--restart', 'always')
        for volume in config.get('volumes', list()):
            command.append('--volume', volume)
        if config.get('volumes-from') is not None:
            command.append('--volumes-from', config.get('volumes-from'))
        command.append(image)

        pattern = re.compile(r"{{([\w\-_]+)}}")
        for arg in command_args:
            for match in pattern.finditer(arg):
                name = match.group(1)
                if name == 'machine':
                    if self.machine is not None:
                        ip = self.machine.ip()
                    else:
                        ip = None
                else:
                    try:
                        printe('Looking for machine with name %s' % name)
                        ip = DockerMachine(name).ip()
                    except:
                        printe('Looking for neighboring container with '
                               'name {name}'.format(name))
                        ip = DockerContainer(name, self.machine.name).ip()
                if ip is None:
                    ip = '127.0.0.1'
                arg = arg.replace(match.group(0), ip)
            command.append(arg)
        return command.run()
Пример #2
0
 def __init__(self, name, machine=None):
     self.name = name
     if machine is None:
         self.machine = None
     else:
         self.machine = DockerMachine(machine)
Пример #3
0
class DockerContainer(object):
    def __init__(self, name, machine=None):
        self.name = name
        if machine is None:
            self.machine = None
        else:
            self.machine = DockerMachine(machine)

    def base_command(self):
        return CommandBuilder('docker')

    def create(self, image, *command_args, **config):
        command = self.base_command()
        if config is None:
            config = dict()
        if config.get('run') is True:
            command.append('run')
            if config.get('detach') is True:
                command.append('--detach')
        else:
            command.append('create')
        command.append('--name', self.name)

        if config.get('tty') is not None:
            command.append('--tty')
        if config.get('interactive') is not None:
            command.append('--interactive')
        if config.get('privileged') is True:
            command.append('--privileged')
        if config.get('user') is not None:
            command.append('--user', config.get('user'))
        for cap in config.get('capabilities', list()):
            command.append('--cap-add', cap)
        if config.get('device') is not None:
            command.append('--device', config.get('device'))
        for env_var in config.get('environment', dict()):
            value = config.get('environment')[env_var]
            if value is True:
                value = 'true'
            elif value is False:
                value = 'false'
            elif isinstance(value, dict) or isinstance(value, list):
                value = json.dumps(value)
            command.append('--env', '%s=%s' % (env_var, str(value)))
        for exp_port in config.get('expose', list()):
            command.append('--expose', exp_port)
        for link in config.get('links', list()):
            if not re.match(r'.+:.+', link):
                printe('Error: In {name}, the link "{link}" does not contain'
                       ' both a container name and an alias. '
                       'Example = name:alias'.format(
                           name=self.name,
                           link=link,
                       ),
                       terminate=True)
            command.append('--link', link)
        if config.get('net') is not None:
            command.append('--net', config.get('net'))
        if config.get('ports') is not None:
            ip = self.machine.ip() if self.machine is not None else None
            for port in config.get('ports'):
                if not re.match(r'.+:.+', port):
                    printe('Error: In {name}, the port "{port}" does not '
                           'contain both internal and external port.'.format(
                               self.name, port),
                           terminate=True)
                if ip and port.startswith(':'):
                    port = ip + port
                command.append('-p', port)
        if config.get('restart') is True:
            command.append('--restart', 'always')
        for volume in config.get('volumes', list()):
            command.append('--volume', volume)
        if config.get('volumes-from') is not None:
            command.append('--volumes-from', config.get('volumes-from'))
        command.append(image)

        pattern = re.compile(r"{{([\w\-_]+)}}")
        for arg in command_args:
            for match in pattern.finditer(arg):
                name = match.group(1)
                if name == 'machine':
                    if self.machine is not None:
                        ip = self.machine.ip()
                    else:
                        ip = None
                else:
                    try:
                        printe('Looking for machine with name %s' % name)
                        ip = DockerMachine(name).ip()
                    except:
                        printe('Looking for neighboring container with '
                               'name {name}'.format(name))
                        ip = DockerContainer(name, self.machine.name).ip()
                if ip is None:
                    ip = '127.0.0.1'
                arg = arg.replace(match.group(0), ip)
            command.append(arg)
        return command.run()

    def is_running(self):
        running = self.base_command().append('inspect', '-f',
                                             '{{.State.Running}}',
                                             self.name).run()
        return running == 'true'

    def shell(self, shell='sh'):
        return self.base_command().append('exec', '-it',
                                          self.name, shell)\
                                        .run(replaceForeground=True)

    def ip(self):
        return self.base_command().append('inspect', '--format',
                                          '{{.NetworkSettings.IPAddress}}',
                                          self.name).run()

    def remove(self, stop_if_running=False):
        if self.is_running() and stop_if_running:
            self.stop()
        return self.base_command().append('rm', self.name).run()

    def stop(self):
        return self.base_command().append('stop', self.name).run()

    def kill(self):
        return self.base_command().append('kill', self.name).run()

    def start(self):
        return self.base_command().append('start', self.name).run()

    processes_column_layouts = {
        0: ['Names'],
        1: ['Names'],
        2: ['Names', 'Status'],
        3: ['Names', 'Image', 'Status'],
        4: ['Names', 'Image', 'Command', 'Status'],
        5: ['Names', 'Image', 'Command', 'Status'],
        6: ['Names', 'Image', 'Command', 'Status', 'CreatedAt'],
        7: ['Names', 'Image', 'Command', 'Status', 'CreatedAt'],
        8: ['Names', 'Image', 'Command', 'Status', 'CreatedAt', 'Ports'],
    }

    def processes(self):
        def make_table(names):
            columns = []
            for name in names:
                columns += ['{{.%s}}' % name]
            return 'table %s' % '\t'.join(columns)

        terminal_size = Utils.terminal_size()
        if terminal_size:
            min_col_width = 20
            table_column_space = int(terminal_size[1] / min_col_width)
            layout = [
                'Names', 'ID', 'Image', 'Command', 'Status', 'CreatedAt',
                'Ports'
            ]
            table = make_table(
                DockerContainer.processes_column_layouts.get(
                    table_column_space, layout))
        else:
            table = make_table('Names', 'Image', 'Status')
        return self.base_command().append('ps', '--all', '--format',
                                          table).run()

    def images(self):
        return self.base_command().append('images').run()

    def logs(self, tail=100):
        if self.name:
            return self.base_command().append(
                'logs', '--follow', '--tail', str(int(tail)),
                self.name).run(replaceForeground=True)
        else:
            return CommandBuilder(
                'bash', '-c', """
       set -m
       trap 'kill $(jobs -p)' 2
       count=0
       for c in $(docker ps --format "{{.Names}}"); do
           color="$(echo "$c" | md5 | cut -c1-4)"
           color=$((31 + ((16#${color}) % 7) ))
           docker logs -f $c | sed "s/^/\033[1;${color}m$c | \033[0;00m/" &
           count+=1
       done
       wait
            """).run(replaceForeground=True)
Пример #4
0
        # if not args.machine and args.host:
        #     args.machine = re.search(r"\w+\://([^:]+)(?:\:[0-9]+)?",
        #         args.host).group(1)
        # else:
        #     print('"', args.machine, '"')
        #     print('"', args.host, '"')

        if args.action == 'create' or args.action == 'run':
            kind_and_flavor = vars(args)['kind:flavor']
        else:
            kind_and_flavor = args.name
        (kind, _, flavor) = kind_and_flavor.partition(':')
        if args.action == 'create' or args.action == 'run':
            config = config_manager.getContainerConfig(kind, flavor)
            if not args.machine and args.url:
                args.machine = DockerMachine(url=args.url)
            container_config = dict(config)
            for key in required_fields + required_container_fields:
                if key in container_config:
                    del container_config[key]
            container_config['run'] = args.action == 'run'
            DockerContainer(args.name, args.machine).create(
                config['image'],
                *config['command'],
                **container_config,
            )
        else:
            print(config_manager.describeContainer(kind, flavor))
    elif args.action == 'kinds':
        printe("Here's a list of available kinds to create containers from:",
               flush=True)
Пример #5
0
 def __init__(self, name, machine=None):
     self.name = name
     if machine is None:
         self.machine = None
     else:
         self.machine = DockerMachine(machine)
Пример #6
0
class DockerContainer(object):

    def __init__(self, name, machine=None):
        self.name = name
        if machine is None:
            self.machine = None
        else:
            self.machine = DockerMachine(machine)

    def base_command(self):
        return CommandBuilder('docker')

    def create(self, image, *command_args, **config):
        command = self.base_command()
        if config is None:
            config = dict()
        if config.get('run') is True:
            command.append('run')
            if config.get('detach') is True:
                command.append('--detach')
        else:
            command.append('create')
        command.append('--name', self.name)

        if config.get('tty') is not None:
            command.append('--tty')
        if config.get('interactive') is not None:
            command.append('--interactive')
        if config.get('privileged') is True:
            command.append('--privileged')
        if config.get('user') is not None:
            command.append('--user', config.get('user'))
        for cap in config.get('capabilities', list()):
            command.append('--cap-add', cap)
        if config.get('device') is not None:
            command.append('--device', config.get('device'))
        for env_var in config.get('environment', dict()):
            value = config.get('environment')[env_var]
            if value is True:
                value = 'true'
            elif value is False:
                value = 'false'
            elif isinstance(value, dict) or isinstance(value, list):
                value = json.dumps(value)
            command.append('--env', '%s=%s' % (env_var, str(value)))
        for exp_port in config.get('expose', list()):
            command.append('--expose', exp_port)
        for link in config.get('links', list()):
            if not re.match(r'.+:.+', link):
                printe('Error: In {name}, the link "{link}" does not contain'
                       ' both a container name and an alias. '
                       'Example = name:alias'.format(
                           name=self.name,
                           link=link,
                       ), terminate=True)
            command.append('--link', link)
        if config.get('net') is not None:
            command.append('--net', config.get('net'))
        if config.get('ports') is not None:
            ip = self.machine.ip() if self.machine is not None else None
            for port in config.get('ports'):
                if not re.match(r'.+:.+', port):
                    printe('Error: In {name}, the port "{port}" does not '
                           'contain both internal and external port.'
                           .format(self.name, port), terminate=True)
                if ip and port.startswith(':'):
                    port = ip + port
                command.append('-p', port)
        if config.get('restart') is True:
            command.append('--restart', 'always')
        for volume in config.get('volumes', list()):
            command.append('--volume', volume)
        if config.get('volumes-from') is not None:
            command.append('--volumes-from', config.get('volumes-from'))
        command.append(image)

        pattern = re.compile(r"{{([\w\-_]+)}}")
        for arg in command_args:
            for match in pattern.finditer(arg):
                name = match.group(1)
                if name == 'machine':
                    if self.machine is not None:
                        ip = self.machine.ip()
                    else:
                        ip = None
                else:
                    try:
                        printe('Looking for machine with name %s' % name)
                        ip = DockerMachine(name).ip()
                    except:
                        printe('Looking for neighboring container with '
                               'name {name}'.format(name))
                        ip = DockerContainer(name, self.machine.name).ip()
                if ip is None:
                    ip = '127.0.0.1'
                arg = arg.replace(match.group(0), ip)
            command.append(arg)
        return command.run()

    def is_running(self):
        running = self.base_command().append('inspect', '-f',
                                             '{{.State.Running}}',
                                             self.name).run()
        return running == 'true'

    def shell(self, shell='sh'):
        return self.base_command().append('exec', '-it',
                                          self.name, shell)\
                                        .run(replaceForeground=True)

    def ip(self):
        return self.base_command().append('inspect', '--format',
                                          '{{.NetworkSettings.IPAddress}}',
                                          self.name).run()

    def remove(self, stop_if_running=False):
        if self.is_running() and stop_if_running:
            self.stop()
        return self.base_command().append('rm', self.name).run()

    def stop(self):
        return self.base_command().append('stop', self.name).run()

    def kill(self):
        return self.base_command().append('kill', self.name).run()

    def start(self):
        return self.base_command().append('start', self.name).run()

    processes_column_layouts = {
        0: ['Names'],
        1: ['Names'],
        2: ['Names', 'Status'],
        3: ['Names', 'Image', 'Status'],
        4: ['Names', 'Image', 'Command', 'Status'],
        5: ['Names', 'Image', 'Command', 'Status'],
        6: ['Names', 'Image', 'Command', 'Status', 'CreatedAt'],
        7: ['Names', 'Image', 'Command', 'Status', 'CreatedAt'],
        8: ['Names', 'Image', 'Command', 'Status', 'CreatedAt', 'Ports'],
    }

    def processes(self):
        def make_table(names):
            columns = []
            for name in names:
                columns += ['{{.%s}}' % name]
            return 'table %s' % '\t'.join(columns)

        terminal_size = Utils.terminal_size()
        if terminal_size:
            min_col_width = 20
            table_column_space = int(terminal_size[1] / min_col_width)
            layout = ['Names', 'ID', 'Image', 'Command', 'Status', 'CreatedAt',
                      'Ports']
            table = make_table(DockerContainer.processes_column_layouts.get(
                table_column_space, layout))
        else:
            table = make_table('Names', 'Image', 'Status')
        return self.base_command().append('ps', '--all',
                                          '--format', table).run()

    def images(self):
        return self.base_command().append('images').run()

    def logs(self, tail=100):
        if self.name:
            return self.base_command().append('logs', '--follow', '--tail',
                                              str(int(tail)), self.name
                                              ).run(replaceForeground=True)
        else:
            return CommandBuilder('bash', '-c', """
       set -m
       trap 'kill $(jobs -p)' 2
       count=0
       for c in $(docker ps --format "{{.Names}}"); do
           color="$(echo "$c" | md5 | cut -c1-4)"
           color=$((31 + ((16#${color}) % 7) ))
           docker logs -f $c | sed "s/^/\033[1;${color}m$c | \033[0;00m/" &
           count+=1
       done
       wait
            """).run(replaceForeground=True)