Ejemplo n.º 1
0
 def get(self, config_type, kind, flavor):
     if kind not in self.configs[config_type]:
         printe('Unknown %s kind: "%s"' % (config_type, kind), terminate=2)
     if flavor not in self.configs[config_type][kind]:
         printe('Unknown {type} flavor for {kind}: "{flavor}"'.format(
             type=config_type, kind=kind, flavor=flavor), terminate=2)
     return self.configs[config_type][kind][flavor]
Ejemplo n.º 2
0
 def append(self, *args):
     for arg in args:
         if isinstance(arg, str):
             self.command_args += [arg]
         elif isinstance(arg, list) or isinstance(arg, tuple):
             for sub_arg in arg:
                 self.append(sub_arg)
         else:
             printe('Error appending argument of unknown type: {}'.format(
                 str(type(arg))),
                    terminate=True)
     return self
Ejemplo n.º 3
0
    def create(self, driver, **config):
        command = CommandBuilder('docker-machine', 'create')
        command.append('--driver', driver)
        if config.get('swarm_token') is not None:
            command.append('--swarm')
            command.append('--swarm-discovery',
                           'token://{token}'.format(config.get('swarm_token')))
        if config.get('swarm_master') is not None:
            command.append('--swarm-master')
        if config.get('registry_mirror') is not None:
            ip = DockerMachine(config.get('registry_mirror')).ip()
            if not ip:
                printe('IP for the registry machine could not be determined. '
                       'Does that machine have an IP?', terminate=True)
            command.append('--engine-registry-mirror', 'http://%s:5000' % ip)
        if config.get('experimental') is not None:
            command.append('--engine-install-url',
                           'https://experimental.docker.com')
        if config.get('neighbor_machine') is not None \
                and not config.get('multihost_networking') is not None:
            printe('Neighbor machine was provided but multihost networking '
                   'was not enabled explicitly. Multihost networking must be '
                   'enabled if neighboring machine is to be used.',
                   terminate=2)
        if config.get('multihost_networking') is not None:
            command.append('--engine-opt', 'default-network=overlay:multihost')
            command.append('--engine-label',
                           'com.docker.network.driver.overlay.'
                           'bind_interface=eth0')
            if config.get('neighbor_machine') is not None:
                command.append('--engine-label',
                               'com.docker.network.driver.overlay.'
                               'neighbor_ip={ip}'.format(
                                   DockerMachine(
                                       config.get('neighbor_machine')).ip()))
        if config.get('consul') is not None:
            if isinstance(config.get('consul'), str):
                consul_name = config.get('consul')
            else:
                consul_name = 'consul'
            command.append('--engine-opt', 'kv-store=consul:{ip}:8500'.format(
                DockerMachine(consul_name).ip()))

        command.append(self.name)
        return command.run()
Ejemplo n.º 4
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()
Ejemplo n.º 5
0
    parser.add_argument('kind:flavor',
                        nargs='?',
                        help='Of form "kind:flavor". Kinds available are '
                        'determined by the kinds in the config '
                        'directory. Use the actions "kinds" to look up '
                        'all available options.')
    args = parser.parse_args()

    if args.debug is True:
        os.environ['UTILS_DEBUG'] = 'true'
    elif args.debug is False:
        os.environ['UTILS_DEBUG'] = 'false'

    if args.action == 'create' or args.action == 'run' \
            and not vars(args)['kind:flavor']:
        printe('No kind provided for action "create".')
        printe(parser.format_usage(), terminate=2)

    if args.action not in actions_without_name and not args.name:
        if args.action in ('desc', 'describe'):
            printe('Container kind:flavor required for action "{action}". Use '
                   'action "kinds" to list available options.'.format(
                       args.action),
                   terminate=2)
        printe('Container name required for action "{action}".'.format(
            args.action),
               terminate=2)

    config_manager = ConfigManager(args.config_directory, filter='container')
    if args.action in ('run', 'create', 'describe', 'desc'):
        # if not args.machine and args.host:
Ejemplo n.º 6
0
 def stop(self):
     if self.local:
         printe("Machine name not provided: Won't try to stop local.")
     return CommandBuilder('docker-machine', 'stop', self.name).run()
Ejemplo n.º 7
0
 def ssh(self):
     if self.local:
         printe("Machine name not provided: Won't try to ssh to local.")
     return CommandBuilder('docker-machine', 'ssh',
                           self.name).run(replaceForeground=True)
Ejemplo n.º 8
0
 def remove(self):
     if self.local:
         printe("Machine name not provided: Cannot remove a local Docker "
                "instance.")
     return CommandBuilder('docker-machine', 'rm', self.name).run()
Ejemplo n.º 9
0
                        help='Whether or not this machine will be a swarm '
                             'master.')
    parser.add_argument('action', choices=action_mappings,
                        help='The action to perform: {actions}'.format(
                            ', '.join(action_mappings)))
    parser.add_argument('name', nargs='?',
                        help='The name of the machine to use.')
    args = parser.parse_args()
    if args.debug is True:
        os.environ['UTILS_DEBUG'] = 'true'
    elif args.debug is False:
        os.environ['UTILS_DEBUG'] = 'false'

    config_manager = ConfigManager(args.config_directory, filter='machine')
    if args.action not in actions_without_name and not args.name:
        printe('Action "%s" requires a name.' % args.action)
        printe(parser.format_usage(), terminate=2)

    if args.action == 'kinds':
        printe("Here's a list of available kinds to create machines from:",
               flush=True)
        print('\n'.join(config_manager.listMachines()), flush=True)
        printe('To create one, use the "create" action, supply a name, and '
               'put kind:flavor on the end.')
    elif args.action in actions_without_name:
        action_mappings[args.action]()
    elif args.action == 'create':
        machine_config = dict(vars(args))
        if 'consul_machine' in machine_config:
            machine_config['consul'] = machine_config['consul_machine']
            del machine_config['consul_machine']
Ejemplo n.º 10
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()
Ejemplo n.º 11
0
                        help='The name of the container to be used.')
    parser.add_argument('kind:flavor', nargs='?',
                        help='Of form "kind:flavor". Kinds available are '
                             'determined by the kinds in the config '
                             'directory. Use the actions "kinds" to look up '
                             'all available options.')
    args = parser.parse_args()

    if args.debug is True:
        os.environ['UTILS_DEBUG'] = 'true'
    elif args.debug is False:
        os.environ['UTILS_DEBUG'] = 'false'

    if args.action == 'create' or args.action == 'run' \
            and not vars(args)['kind:flavor']:
        printe('No kind provided for action "create".')
        printe(parser.format_usage(), terminate=2)

    if args.action not in actions_without_name and not args.name:
        if args.action in ('desc', 'describe'):
            printe('Container kind:flavor required for action "{action}". Use '
                   'action "kinds" to list available options.'.format(
                       args.action), terminate=2)
        printe('Container name required for action "{action}".'.format(
            args.action), terminate=2)

    config_manager = ConfigManager(args.config_directory, filter='container')
    if args.action in ('run', 'create', 'describe', 'desc'):
        # if not args.machine and args.host:
        #     args.machine = re.search(r"\w+\://([^:]+)(?:\:[0-9]+)?",
        #         args.host).group(1)
Ejemplo n.º 12
0
 def __init__(self, config_directory, filter=None):
     if config_directory.startswith('~'):
         config_directory = os.path.expanduser('~') + config_directory[1:]
     if not os.path.exists(config_directory):
         os.makedirs(config_directory)
     try:
         configs = os.listdir(config_directory)
     except:
         printe('Could not list files in the directory:', config_directory,
                terminate=True)
     self.configs = {}
     for config in configs:
         if not config.endswith('.json'):
             continue
         with open('%s/%s' % (config_directory, config)) as file:
             configJson = json.load(file)
         if filter and configJson['type'] != filter:
             continue
         for field in required_fields:
             if field not in configJson:
                 printe('Config %s is missing its %s.' % (config, field),
                        terminate=3)
         if configJson['type'] == 'container':
             all_fields = list(required_fields)
             all_fields += required_container_fields
             all_fields += optional_container_fields
             for field in configJson:
                 if field not in all_fields:
                     printe('Container config {config} has unknown field '
                            '"{field}".'.format(config=config, field=field),
                            terminate=3)
             for field in required_container_fields:
                 if field not in configJson:
                     printe('Container config {config} is missing its '
                            'field.'.format(config=config, field=field),
                            terminate=3)
             for field in optional_container_fields:
                 if field not in configJson:
                     configJson[field] = optional_container_fields[field]
         elif configJson['type'] == 'machine':
             all_fields = list(required_fields)
             all_fields += required_machine_fields
             all_fields += optional_machine_fields
             for field in configJson:
                 if field not in all_fields:
                     printe('Machine config {config} has unknown field '
                            '"{field}".'.format(config=config, field=field),
                            terminate=3)
             for field in required_machine_fields:
                 if field not in configJson:
                     printe('Machine config {config} is missing its '
                            '{field}.'.format(config=config, field=field),
                            terminate=3)
             for field in optional_machine_fields:
                 if field not in configJson:
                     configJson[field] = optional_machine_fields[field]
         else:
             printe('Unknown type "{}". Available types are: container, '
                    'machine'.format(configJson['type']), terminate=3)
         config_type = configJson['type']
         kind = configJson['kind']
         flavor = configJson['flavor']
         if config_type not in self.configs:
             self.configs[config_type] = {}
         if kind not in self.configs[config_type]:
             self.configs[config_type][kind] = {}
         elif flavor in self.configs[config_type][kind]:
             printe(
                 "Duplicate kind:flavor configs found: {file} {config}. "
                 "Please change or remove one of these configs to have a "
                 "different kind:flavor combination.".format(
                     file=self.configs[config_type][kind][flavor]
                              .get('file_name'),
                     config=config,
                 ),
                 terminate=True
             )
         del configJson['type']
         del configJson['kind']
         del configJson['flavor']
         configJson['file_name'] = config
         self.configs[config_type][kind][flavor] = configJson