Example #1
0
def up(project_path):
    up_options = {
        "-d": True,
        "--no-color": False,
        "--no-deps": False,
        "--build": False,
        "--abort-on-container-exit": False,
        "--remove-orphans": False,
        "--no-recreate": True,
        "--force-recreate": False,
        "--no-build": False,
        "SERVICE": "",
        "--scale": []
    }

    project = project_from_options(project_path, up_options)
    cmd = TopLevelCommand(project)
    cmd.up(up_options)

    ps_options = {"SERVICE": "", "-q": True}
    containers = sorted(
        project.containers(service_names=ps_options['SERVICE'], stopped=True) +
        project.containers(service_names=ps_options['SERVICE'],
                           one_off=OneOffFilter.only),
        key=attrgetter('name'))

    container_ids = []
    for container in containers:
        container_ids.append(container.id)

    return container_ids
Example #2
0
    def test_run_with_environment_merged_with_options_list(
            self, mock_pseudo_terminal):
        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service(
            'service',
            client=mock_client,
            environment=['FOO=ONE', 'BAR=TWO'],
            image='someimage')

        command.run(
            mock_project, {
                'SERVICE': 'service',
                'COMMAND': None,
                '-e': ['BAR=NEW', 'OTHER=bär'.encode('utf-8')],
                '--user': None,
                '--no-deps': None,
                '-d': True,
                '-T': None,
                '--entrypoint': None,
                '--service-ports': None,
                '--publish': [],
                '--rm': None,
                '--name': None,
            })

        _, _, call_kwargs = mock_client.create_container.mock_calls[0]
        assert (sorted(call_kwargs['environment']) == sorted(
            ['FOO=ONE', 'BAR=NEW', 'OTHER=bär']))
Example #3
0
    def test_command_manual_and_service_ports_together(self):
        project = Project.from_config(
            name='composetest',
            client=None,
            config_data=build_config({
                'service': {
                    'image': 'busybox'
                },
            }),
        )
        command = TopLevelCommand(project)

        with pytest.raises(UserError):
            command.run({
                'SERVICE': 'service',
                'COMMAND': None,
                '-e': [],
                '--label': [],
                '--user': None,
                '--no-deps': None,
                '--detach': True,
                '-T': None,
                '--entrypoint': None,
                '--service-ports': True,
                '--use-aliases': None,
                '--publish': ['80:80'],
                '--rm': None,
                '--name': None,
            })
Example #4
0
 def test_project_name_from_environment_new_var(self):
     command = TopLevelCommand()
     name = 'namefromenv'
     with mock.patch.dict(os.environ):
         os.environ['COMPOSE_PROJECT_NAME'] = name
         project_name = command.get_project_name(None)
     self.assertEquals(project_name, name)
Example #5
0
 def test_get_project(self):
     command = TopLevelCommand()
     command.base_dir = 'tests/fixtures/longer-filename-composefile'
     project = command.get_project()
     self.assertEqual(project.name, 'longerfilenamecomposefile')
     self.assertTrue(project.client)
     self.assertTrue(project.services)
Example #6
0
    def test_command_manula_and_service_ports_together(self):
        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service(
            'service',
            client=mock_client,
            restart='always',
            image='someimage',
        )

        with self.assertRaises(UserError):
            command.run(mock_project, {
                'SERVICE': 'service',
                'COMMAND': None,
                '-e': [],
                '--user': None,
                '--no-deps': None,
                '--allow-insecure-ssl': None,
                '-d': True,
                '-T': None,
                '--entrypoint': None,
                '--service-ports': True,
                '--publish': ['80:80'],
                '--rm': None,
            })
Example #7
0
    def test_run_with_environment_merged_with_options_list(self, mock_dockerpty):
        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service(
            'service',
            client=mock_client,
            environment=['FOO=ONE', 'BAR=TWO'],
            image='someimage')

        command.run(mock_project, {
            'SERVICE': 'service',
            'COMMAND': None,
            '-e': ['BAR=NEW', 'OTHER=THREE'],
            '--user': None,
            '--no-deps': None,
            '--allow-insecure-ssl': None,
            '-d': True,
            '-T': None,
            '--entrypoint': None,
            '--service-ports': None,
            '--publish': [],
            '--rm': None,
        })

        _, _, call_kwargs = mock_client.create_container.mock_calls[0]
        self.assertEqual(
            call_kwargs['environment'],
            {'FOO': 'ONE', 'BAR': 'NEW', 'OTHER': 'THREE'})
Example #8
0
    def test_run_interactive_passes_logs_false(self, mock_pseudo_terminal, mock_run_operation):
        mock_client = mock.create_autospec(docker.APIClient)
        project = Project.from_config(
            name='composetest',
            client=mock_client,
            config_data=build_config({
                'service': {'image': 'busybox'}
            }),
        )
        plugin_manager = PluginManager('')
        command = TopLevelCommand(project, plugin_manager)

        with pytest.raises(SystemExit):
            command.run({
                'SERVICE': 'service',
                'COMMAND': None,
                '-e': [],
                '--user': None,
                '--no-deps': None,
                '-d': False,
                '-T': None,
                '--entrypoint': None,
                '--service-ports': None,
                '--publish': [],
                '--rm': None,
                '--name': None,
                '--workdir': None,
            })

        _, _, call_kwargs = mock_run_operation.mock_calls[0]
        assert call_kwargs['logs'] is False
Example #9
0
    def test_command_manula_and_service_ports_together(self):
        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service(
            "service", client=mock_client, restart="always", image="someimage"
        )

        with self.assertRaises(UserError):
            command.run(
                mock_project,
                {
                    "SERVICE": "service",
                    "COMMAND": None,
                    "-e": [],
                    "--user": None,
                    "--no-deps": None,
                    "--allow-insecure-ssl": None,
                    "-d": True,
                    "-T": None,
                    "--entrypoint": None,
                    "--service-ports": True,
                    "--publish": ["80:80"],
                    "--rm": None,
                    "--name": None,
                },
            )
Example #10
0
    def test_command_manual_and_service_ports_together(self):
        project = Project.from_config(
            name='composetest',
            client=None,
            config_data=build_config({
                'service': {'image': 'busybox'},
            }),
        )
        command = TopLevelCommand(project)

        with pytest.raises(UserError):
            command.run({
                'SERVICE': 'service',
                'COMMAND': None,
                '-e': [],
                '--label': [],
                '--user': None,
                '--no-deps': None,
                '--detach': True,
                '-T': None,
                '--entrypoint': None,
                '--service-ports': True,
                '--use-aliases': None,
                '--publish': ['80:80'],
                '--rm': None,
                '--name': None,
            })
Example #11
0
    def test_run_interactive_passes_logs_false(self, mock_pseudo_terminal,
                                               mock_run_operation):
        os.environ['COMPOSE_INTERACTIVE_NO_CLI'] = 'true'
        mock_client = mock.create_autospec(docker.APIClient)
        mock_client.api_version = DEFAULT_DOCKER_API_VERSION
        project = Project.from_config(
            name='composetest',
            client=mock_client,
            config_data=build_config({'service': {
                'image': 'busybox'
            }}),
        )
        command = TopLevelCommand(project)

        with pytest.raises(SystemExit):
            command.run({
                'SERVICE': 'service',
                'COMMAND': None,
                '-e': [],
                '--label': [],
                '--user': None,
                '--no-deps': None,
                '--detach': False,
                '-T': None,
                '--entrypoint': None,
                '--service-ports': None,
                '--publish': [],
                '--volume': [],
                '--rm': None,
                '--name': None,
                '--workdir': None,
            })

        _, _, call_kwargs = mock_run_operation.mock_calls[0]
        assert call_kwargs['logs'] is False
    def __init__(self, path='./'):
        path = './'  # Path to docker-compose directory
        self.options = {
            "--file": ['docker-compose.dev.yaml', ],
            "--no-deps": False,
            "--abort-on-container-exit": False,
            "SERVICE": "",
            "--remove-orphans": False,
            "--no-recreate": True,
            "--force-recreate": False,
            "--build": False,
            '--no-build': False,
            '--no-color': False,
            "--rmi": "none",
            "--volumes": "",
            "--follow": False,
            "--timestamps": False,
            "--tail": "all",
            "-d": True,
            '--always-recreate-deps': False,
            '--scale': []
        }

        self.project = project_from_options(path, self.options)
        self.cli = TopLevelCommand(self.project)
Example #13
0
 def test_get_project(self):
     command = TopLevelCommand()
     command.base_dir = 'tests/fixtures/longer-filename-composefile'
     project = command.get_project(command.get_config_path())
     self.assertEqual(project.name, 'longerfilenamecomposefile')
     self.assertTrue(project.client)
     self.assertTrue(project.services)
Example #14
0
    def test_run_with_environment_merged_with_options_list(self, mock_dockerpty):
        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service(
            "service", client=mock_client, environment=["FOO=ONE", "BAR=TWO"], image="someimage"
        )

        command.run(
            mock_project,
            {
                "SERVICE": "service",
                "COMMAND": None,
                "-e": ["BAR=NEW", "OTHER=THREE"],
                "--user": None,
                "--no-deps": None,
                "--allow-insecure-ssl": None,
                "-d": True,
                "-T": None,
                "--entrypoint": None,
                "--service-ports": None,
                "--publish": [],
                "--rm": None,
                "--name": None,
            },
        )

        _, _, call_kwargs = mock_client.create_container.mock_calls[0]
        self.assertEqual(call_kwargs["environment"], {"FOO": "ONE", "BAR": "NEW", "OTHER": "THREE"})
Example #15
0
    def test_command_manual_and_service_ports_together(self):
        project = Project.from_config(
            name='composetest',
            client=None,
            config_data=build_config({
                'service': {'image': 'busybox'},
            }),
        )
        plugin_manager = PluginManager('')
        command = TopLevelCommand(project, plugin_manager)

        with self.assertRaises(UserError):
            command.run({
                'SERVICE': 'service',
                'COMMAND': None,
                '-e': [],
                '--user': None,
                '--no-deps': None,
                '-d': True,
                '-T': None,
                '--entrypoint': None,
                '--service-ports': True,
                '--publish': ['80:80'],
                '--rm': None,
                '--name': None,
            })
Example #16
0
    def test_run_with_environment_merged_with_options_list(self, mock_dockerpty):
        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock()
        mock_project.get_service.return_value = Service(
            'service',
            client=mock_client,
            environment=['FOO=ONE', 'BAR=TWO'],
            image='someimage')

        command.run(mock_project, {
            'SERVICE': 'service',
            'COMMAND': None,
            '-e': ['BAR=NEW', 'OTHER=THREE'],
            '--user': None,
            '--no-deps': None,
            '--allow-insecure-ssl': None,
            '-d': True,
            '-T': None,
            '--entrypoint': None,
            '--service-ports': None,
            '--rm': None,
        })

        _, _, call_kwargs = mock_client.create_container.mock_calls[0]
        self.assertEqual(
            call_kwargs['environment'],
            {'FOO': 'ONE', 'BAR': 'NEW', 'OTHER': 'THREE'})
Example #17
0
 def test_project_name_from_environment_new_var(self):
     command = TopLevelCommand()
     name = 'namefromenv'
     with mock.patch.dict(os.environ):
         os.environ['COMPOSE_PROJECT_NAME'] = name
         project_name = command.get_project_name(None)
     self.assertEquals(project_name, name)
Example #18
0
    def test_run_with_environment_merged_with_options_list(
            self, mock_pseudo_terminal):
        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service(
            'service',
            client=mock_client,
            environment=['FOO=ONE', 'BAR=TWO'],
            image='someimage')

        command.run(
            mock_project, {
                'SERVICE': 'service',
                'COMMAND': None,
                '-e': ['BAR=NEW', 'OTHER=bär'.encode('utf-8')],
                '--user': None,
                '--no-deps': None,
                '-d': True,
                '-T': None,
                '--entrypoint': None,
                '--service-ports': None,
                '--publish': [],
                '--rm': None,
                '--name': None,
            })

        _, _, call_kwargs = mock_client.create_container.mock_calls[0]
        assert (sorted(call_kwargs['environment']) == sorted(
            ['FOO=ONE', 'BAR=NEW', 'OTHER=bär']))
Example #19
0
    def test_run_interactive_passes_logs_false(self, mock_pseudo_terminal):
        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service(
            'service',
            client=mock_client,
            environment=['FOO=ONE', 'BAR=TWO'],
            image='someimage')

        with pytest.raises(SystemExit):
            command.run(mock_project, {
                'SERVICE': 'service',
                'COMMAND': None,
                '-e': ['BAR=NEW', 'OTHER=bär'.encode('utf-8')],
                '--user': None,
                '--no-deps': None,
                '-d': False,
                '-T': None,
                '--entrypoint': None,
                '--service-ports': None,
                '--publish': [],
                '--rm': None,
                '--name': None,
            })

        _, _, call_kwargs = mock_pseudo_terminal.mock_calls[0]
        assert call_kwargs['logs'] is False
class DockerCompose(object):

    def __init__(self, path='./'):
        path = './'  # Path to docker-compose directory
        self.options = {
            "--file": ['docker-compose.dev.yaml', ],
            "--no-deps": False,
            "--abort-on-container-exit": False,
            "SERVICE": "",
            "--remove-orphans": False,
            "--no-recreate": True,
            "--force-recreate": False,
            "--build": False,
            '--no-build': False,
            '--no-color': False,
            "--rmi": "none",
            "--volumes": "",
            "--follow": False,
            "--timestamps": False,
            "--tail": "all",
            "-d": True,
            '--always-recreate-deps': False,
            '--scale': []
        }

        self.project = project_from_options(path, self.options)
        self.cli = TopLevelCommand(self.project)

    def up(self, **kwargs):
        self.cli.up(self.options)
        time.sleep(0.5)  # wait for the server to be ready

    def down(self):
        self.cli.down(self.options)
Example #21
0
def docker_compose(request):
    """
    :type request: _pytest.python.FixtureRequest
    """

    options = {"--no-deps": False,
               "--abort-on-container-exit": False,
               "SERVICE": "",
               "--remove-orphans": False,
               "--no-recreate": True,
               "--force-recreate": False,
               "--build": False,
               '--no-build': False,
               '--no-color': False,
               "--rmi": "none",
               "--volumes": "",
               "--follow": False,
               "--timestamps": False,
               "--tail": "all",
               "-d": True,
               }

    project = project_from_options(os.path.dirname(__file__), options)
    cmd = TopLevelCommand(project)
    cmd.up(options)

    def fin():
        cmd.logs(options)
        cmd.down(options)

    request.addfinalizer(fin)
Example #22
0
    def test_run_interactive_passes_logs_false(self, mock_pseudo_terminal, mock_run_operation):
        mock_client = mock.create_autospec(docker.Client)
        project = Project.from_config(
            name='composetest',
            client=mock_client,
            config_data=build_config({
                'service': {'image': 'busybox'}
            }),
        )
        command = TopLevelCommand(project)

        with pytest.raises(SystemExit):
            command.run({
                'SERVICE': 'service',
                'COMMAND': None,
                '-e': [],
                '--user': None,
                '--no-deps': None,
                '-d': False,
                '-T': None,
                '--entrypoint': None,
                '--service-ports': None,
                '--publish': [],
                '--rm': None,
                '--name': None,
                '--workdir': None,
            })

        _, _, call_kwargs = mock_run_operation.mock_calls[0]
        assert call_kwargs['logs'] is False
Example #23
0
    def test_command_manula_and_service_ports_together(self):
        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service(
            'service',
            client=mock_client,
            restart='always',
            image='someimage',
        )

        with self.assertRaises(UserError):
            command.run(mock_project, {
                'SERVICE': 'service',
                'COMMAND': None,
                '-e': [],
                '--user': None,
                '--no-deps': None,
                '-d': True,
                '-T': None,
                '--entrypoint': None,
                '--service-ports': True,
                '--publish': ['80:80'],
                '--rm': None,
                '--name': None,
            })
Example #24
0
def get_config_filename_for_files(filenames):
    project_dir = tempfile.mkdtemp()
    try:
        make_files(project_dir, filenames)
        command = TopLevelCommand()
        command.base_dir = project_dir
        return os.path.basename(command.get_config_path())
    finally:
        shutil.rmtree(project_dir)
Example #25
0
def test_compose_command():
    @compose_command()
    def test_command(self):
        """
        Test command

        Usage: config [options]

        Options:
            -o, --option     Option
        """
        return True

    @compose_command(standalone=True)
    def stest_command(self):
        """
        Second test command

        Usage: config [options]

        Options:
            -o, --option     Option
        """
        return False

    if hasattr(TopLevelCommand, '__modified_doc__'):
        assert re.search(
            r'test_command\s+Test command',
            TopLevelCommand.__modified_doc__
        ) is not None
        assert re.search(
            r'stest_command\s+Second test command',
            TopLevelCommand.__modified_doc__
        ) is not None
    else:
        assert re.search(
            r'test_command\s+Test command',
            TopLevelCommand.__doc__
        ) is not None
        assert re.search(
            r'stest_command\s+Second test command',
            TopLevelCommand.__doc__
        ) is not None

    top_level_command = TopLevelCommand(None, None, None)

    assert TopLevelCommand.test_command.__standalone__ is False
    assert TopLevelCommand.stest_command.__standalone__ is True

    assert top_level_command.test_command() is True
    assert top_level_command.stest_command() is False

    with pytest.raises(PluginCommandError):
        test_command(None)

    with pytest.raises(PluginCommandError):
        stest_command(None)
Example #26
0
def get_project(path):
    """
    get docker project given file path
    """
    logging.debug('get project ' + path)
    command = TopLevelCommand()
    command.base_dir = path
    project = command.get_project(command.get_config_path())
    return project
Example #27
0
def get_project(path):
    """
    get docker project given file path
    """
    logging.debug('get project ' + path)
    command = TopLevelCommand()
    command.base_dir = path
    project = command.get_project(command.get_config_path())
    return project
Example #28
0
def get_config_filename_for_files(filenames):
    project_dir = tempfile.mkdtemp()
    try:
        make_files(project_dir, filenames)
        command = TopLevelCommand()
        command.base_dir = project_dir
        return os.path.basename(command.get_config_path())
    finally:
        shutil.rmtree(project_dir)
Example #29
0
class DockerCompose(Module):
    """
    :Docker-compose module:

    Will automatically run `docker-compose up -d` before your test and `down` after it if this
    module was enabled and you have `docker-compose.yml` file in your directory.

    :Enable this module:

    - run `pip install catcher[compose]`. It will installs all requirements, if they were not installed.

    """
    def __init__(self, resources_dir) -> None:
        super().__init__(resources_dir)
        self._cmd = None
        self._options = {
            '--detach': True,
            'SERVICE': "",
            '--no-deps': False,
            '--abort-on-container-exit': False,
            '--no-recreate': True,
            '--remove-orphans': False,
            '--always-recreate-deps': False,
            '--force-recreate': False,
            '--build': False,
            '--no-build': False,
            '--no-color': False,
            '--rmi': 'none',
            '--volumes': "",
            '--follow': False,
            '--timestamps': False,
            '--scale': {}
        }

    def before(self, *args, **kwargs):
        """
        Will run `docker-compose up -d` only in case docker-compose is installed locally
        and there is a docker-compose.yml file in resources directory
        """
        compose = self.find_resource_file()
        if compose and is_package_installed('compose'):
            from compose.cli.main import TopLevelCommand, project_from_options
            info('Starting docker-compose. Please wait.')
            self._options['-f'] = join(self._resources, compose),
            self._cmd = TopLevelCommand(
                project_from_options(self._resources, self._options))
            self._cmd.up(self._options)

    def after(self, *args, **kwargs):
        if self._cmd:
            self._cmd.down(self._options)

    def filter_resource(self, file: str) -> bool:
        # use only default docker-compose.yml for now, will change it in future if needed.
        return isfile(join(self._resources,
                           file)) and file == 'docker-compose.yml'
Example #30
0
    def test_default_project_name(self):
        cwd = os.getcwd()

        try:
            os.chdir('tests/fixtures/simple-composefile')
            command = TopLevelCommand()
            project_name = command.get_project_name(command.get_config_path())
            self.assertEquals('simplecomposefile', project_name)
        finally:
            os.chdir(cwd)
Example #31
0
    def test_default_project_name(self):
        cwd = os.getcwd()

        try:
            os.chdir('tests/fixtures/simple-composefile')
            command = TopLevelCommand()
            project_name = command.get_project_name('.')
            self.assertEquals('simplecomposefile', project_name)
        finally:
            os.chdir(cwd)
Example #32
0
    def __init__(self, docker_compose_file, options=None):
        self.docker_compose_file = docker_compose_file

        # build docker options with default ones + input overrides
        dockerenv_options = self.options
        if options:
            dockerenv_options.update(options)

        project = project_from_options(str(TESTS_DIR), dockerenv_options)
        self.cmd = TopLevelCommand(project)
        self.cmd.up(dockerenv_options)
def run_compose_with_file(project_name, yml_file, manager_services, timeout):

    class ContainerKiller(object):

        def __init__(self, project_description):
            self.project_description = project_description
            self.has_been_killed = False
            self.kill_lock = threading.Lock()
            self.exception_on_kill = None

        def kill(self, exception_on_kill=None):
            self.kill_lock.acquire()
            if self.has_been_killed:
                return None
            self.has_been_killed = True
            self.exception_on_kill = exception_on_kill
            # Kill all running containers
            command.dispatch(self.project_description + ["kill"], None)
            # Remove containers(Cleaning up)
            command.dispatch(self.project_description + ["rm", "--force"], None)
            self.kill_lock.release()

    """
        :param project_name: A name used to identify containers of this project
        :param yml_file; Path of YAML file which docker-compose is going to be run with.
        :param manager_services: list of services which are supposed to act as managers.
        Runs docker-compose and waits until manager containers stop. Kills all the container afterwards.
        Streams managers' logs to the output.
    """
    if not manager_services:
        manager_services = []

    command = TopLevelCommand()
    project_description = ["-f", [yml_file], "-p", project_name]
    # Start docker-compose as a daemon
    command.dispatch(project_description + ["up", "-d"], None)
    # Attach to manager container(s)' logs. Waits for manager container to stop.
    # if no service is mentioned as manager(i.e. manager_services is an empty list)
    # automatically attaches to all containers logs
    container_killer = ContainerKiller(project_description)

    timer = None
    if timeout:
        timer = threading.Timer(timeout, container_killer.kill, kwargs={"exception_on_kill": TimeoutError()})
    try:
        if timeout:
            timer.start()
        command.dispatch(project_description + ["logs"] + manager_services, None)
    finally:
        container_killer.kill()
        if timeout:
            timer.cancel()
    if container_killer.exception_on_kill is not None:
        raise container_killer.exception_on_kill
Example #34
0
 def __init__(self,
              project_name,
              project_dir='.',
              file_compose='docker-compose.yml'):
     self._name = project_name
     self.file = file_compose
     self.project_dir = project_dir
     print("Reading file: {}".format(self.get_compose_file()))
     # TODO: get project must be called every time in order to load  the compose file updated
     self._project = self._get_project(project_dir, project_name=self._name)
     self.compose = TopLevelCommand(self._project, project_dir=project_dir)
    def create(self, instance_id: str, content: str, c_type: str,
               **kwargs) -> None:
        """
        This creates a set of containers using docker compose.
        Note: the use of the docker compose python module is unsupported by docker inc.
        :param content: the docker compose file as a string
        :return:
        """
        if c_type != 'docker-compose':
            raise NotImplementedError(
                'The type ({type}) of cluster manager is unknown'.format(
                    type=c_type))

        # when we get the manifest, we have to dump it to a temporary file
        # to allow for multiple stack instances we need to have multiple projects!
        # this means multiple directories
        mani_dir = self.manifest_cache + '/' + instance_id

        if not os.path.exists(mani_dir):
            os.makedirs(mani_dir)
        else:
            LOG.info(
                'The instance is already running with the following project: {mani_dir}'
                .format(mani_dir=mani_dir))
            LOG.warning('Content in this directory will be overwritten.')
            # XXX shouldn't this raise an exception?

        # can supply external parameters here...
        # parameters is the name set in the OSBA spec for additional parameters supplied on provisioning
        # if none supplied, we use an empty dict
        # add optionally supplied parameters as environment variables
        parameters = kwargs.get('parameters', dict())
        env_list = list()
        for k, v in parameters.items():
            LOG.info('Including as environment variable: {k}={v}'.format(k=k,
                                                                         v=v))
            env_list.append(k + '=' + v)

        if len(env_list) > 0:
            m = yaml.load(content)
            for k, v in m['services'].items():
                v['environment'] = env_list
            content = yaml.dump(m)

        LOG.debug('writing to: {compo}'.format(compo=mani_dir +
                                               '/docker-compose.yml'))
        m = open(mani_dir + '/docker-compose.yml', 'wt')
        m.write(content)
        m.close()

        project = project_from_options(mani_dir, self.options)
        cmd = TopLevelCommand(project)
        cmd.up(self.options)
Example #36
0
 def before(self, *args, **kwargs):
     """
     Will run `docker-compose up -d` only in case docker-compose is installed locally
     and there is a docker-compose.yml file in resources directory
     """
     compose = self.find_resource_file()
     if compose and is_package_installed('compose'):
         from compose.cli.main import TopLevelCommand, project_from_options
         info('Starting docker-compose. Please wait.')
         self._options['-f'] = join(self._resources, compose),
         self._cmd = TopLevelCommand(
             project_from_options(self._resources, self._options))
         self._cmd.up(self._options)
Example #37
0
    def test_run_interactive_passes_logs_false(
        self,
        mock_container_create,
        mock_pseudo_terminal,
        mock_run_operation,
    ):
        os.environ['COMPOSE_INTERACTIVE_NO_CLI'] = 'true'
        mock_client = mock.create_autospec(docker.APIClient)
        mock_client.api_version = DEFAULT_DOCKER_API_VERSION
        mock_client._general_configs = {}
        mock_container_create.return_value = Container(mock_client, {
            'Id':
            '37b35e0ba80d91009d37e16f249b32b84f72bda269985578ed6c75a0a13fcaa8',
            'Config': {
                'Labels': {
                    LABEL_SERVICE: 'service',
                }
            },
        },
                                                       has_been_inspected=True)
        project = Project.from_config(
            name='composetest',
            client=mock_client,
            config_data=build_config({'service': {
                'image': 'busybox'
            }}),
        )
        command = TopLevelCommand(project)

        with pytest.raises(SystemExit):
            command.run({
                'SERVICE': 'service',
                'COMMAND': None,
                '-e': [],
                '--label': [],
                '--user': None,
                '--no-deps': None,
                '--detach': False,
                '-T': None,
                '--entrypoint': None,
                '--service-ports': None,
                '--use-aliases': None,
                '--publish': [],
                '--volume': [],
                '--rm': None,
                '--name': None,
                '--workdir': None,
            })

        _, _, call_kwargs = mock_run_operation.mock_calls[0]
        assert call_kwargs['logs'] is False
Example #38
0
    def test_run_service_with_restart_always(self):
        mock_client = mock.create_autospec(docker.APIClient)
        mock_client.api_version = DEFAULT_DOCKER_API_VERSION
        mock_client._general_configs = {}

        project = Project.from_config(
            name='composetest',
            client=mock_client,
            config_data=build_config(
                {'service': {
                    'image': 'busybox',
                    'restart': 'always',
                }}),
        )

        command = TopLevelCommand(project)
        command.run({
            'SERVICE': 'service',
            'COMMAND': None,
            '-e': [],
            '--label': [],
            '--user': None,
            '--no-deps': None,
            '--detach': True,
            '-T': None,
            '--entrypoint': None,
            '--service-ports': None,
            '--use-aliases': None,
            '--publish': [],
            '--volume': [],
            '--rm': None,
            '--name': None,
            '--workdir': None,
        })

        assert mock_client.create_host_config.call_args[1]['restart_policy'][
            'Name'] == 'always'

        command = TopLevelCommand(project)
        command.run({
            'SERVICE': 'service',
            'COMMAND': None,
            '-e': [],
            '--label': [],
            '--user': None,
            '--no-deps': None,
            '--detach': True,
            '-T': None,
            '--entrypoint': None,
            '--service-ports': None,
            '--use-aliases': None,
            '--publish': [],
            '--volume': [],
            '--rm': True,
            '--name': None,
            '--workdir': None,
        })

        assert not mock_client.create_host_config.call_args[1].get(
            'restart_policy')
Example #39
0
    def test_run_service_with_restart_always(self):
        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service(
            'service',
            client=mock_client,
            restart={
                'Name': 'always',
                'MaximumRetryCount': 0
            },
            image='someimage')
        command.run(
            mock_project, {
                'SERVICE': 'service',
                'COMMAND': None,
                '-e': [],
                '--user': None,
                '--no-deps': None,
                '--allow-insecure-ssl': None,
                '-d': True,
                '-T': None,
                '--entrypoint': None,
                '--service-ports': None,
                '--publish': [],
                '--rm': None,
                '--name': None,
            })

        self.assertEquals(
            mock_client.create_host_config.call_args[1]['restart_policy']
            ['Name'], 'always')

        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service('service',
                                                        client=mock_client,
                                                        restart='always',
                                                        image='someimage')
        command.run(
            mock_project, {
                'SERVICE': 'service',
                'COMMAND': None,
                '-e': [],
                '--user': None,
                '--no-deps': None,
                '--allow-insecure-ssl': None,
                '-d': True,
                '-T': None,
                '--entrypoint': None,
                '--service-ports': None,
                '--publish': [],
                '--rm': True,
                '--name': None,
            })

        self.assertFalse(
            mock_client.create_host_config.call_args[1].get('restart_policy'))
Example #40
0
def rm(project_path):

    rm_options = {
        "--force": True,
        "--stop": True,
        "-v": False,
        "--rmi": "none",
        "--volumes": "/private",
        "--remove-orphans": False,
        "SERVICE": ""
    }

    project = project_from_options(project_path, rm_options)
    cmd = TopLevelCommand(project)
    cmd.down(rm_options)
Example #41
0
    def test_run_up_with_docker_cli_build(self, mock_project_up):
        os.environ['COMPOSE_DOCKER_CLI_BUILD'] = '1'
        mock_client = mock.create_autospec(docker.APIClient)
        mock_client.api_version = DEFAULT_DOCKER_API_VERSION
        mock_client._general_configs = {}
        container = Container(mock_client, {
            'Id':
            '37b35e0ba80d91009d37e16f249b32b84f72bda269985578ed6c75a0a13fcaa8',
            'Name': 'composetest_service_37b35',
            'Config': {
                'Labels': {
                    LABEL_SERVICE: 'service',
                }
            },
        },
                              has_been_inspected=True)
        mock_project_up.return_value = [container]

        project = Project.from_config(
            name='composetest',
            config_data=build_config({'service': {
                'image': 'busybox'
            }}),
            client=mock_client,
        )

        command = TopLevelCommand(project)
        command.run({
            'SERVICE': 'service',
            'COMMAND': None,
            '-e': [],
            '--label': [],
            '--user': None,
            '--no-deps': None,
            '--detach': True,
            '-T': None,
            '--entrypoint': None,
            '--service-ports': None,
            '--use-aliases': None,
            '--publish': [],
            '--volume': [],
            '--rm': None,
            '--name': None,
            '--workdir': None,
        })

        _, _, call_kwargs = mock_project_up.mock_calls[0]
        assert call_kwargs.get('cli')
Example #42
0
def build_and_run(options, request):
    project = project_from_options(os.path.dirname(__file__), options)
    cmd = TopLevelCommand(project)
    start_time = str(int(unix_time_milliseconds(datetime.utcnow())))
    run_containers(cmd, options)

    def fin():
        # Stop the containers then remove them and their volumes (--volumes option)
        print("containers stopping", flush=True)
        try:
            # Used for when there are multiple filewriter instances
            # as the service is not called "filewriter"
            multiple_log_options = dict(options)
            multiple_log_options["SERVICE"] = ["filewriter1", "filewriter2"]
            cmd.logs(multiple_log_options)
        except:
            log_options = dict(options)
            log_options["SERVICE"] = ["filewriter"]
            cmd.logs(log_options)
        options["--timeout"] = 30
        cmd.down(options)
        print("containers stopped", flush=True)

    # Using a finalizer rather than yield in the fixture means
    # that the containers will be brought down even if tests fail
    request.addfinalizer(fin)
    # Return the start time so the filewriter knows when to start consuming data
    # from to get all data which was published
    return start_time
Example #43
0
    def top_level_cmd(self):
        try:
            compose_files = self.get_compose_files()
            config_path = get_config_path_from_options(
                ".",
                {},
                {"COMPOSE_FILE": compose_files},
            )

            os.environ["COMPOSE_FILE"] = compose_files

            for k, v in self.settings.items():
                if k == "CONFIGURATION_OPTIONAL_SCOPES":
                    continue
                if isinstance(v, bool):
                    v = f"{v}".lower()
                if isinstance(v, int):
                    v = str(v)
                os.environ[k] = v

            env = Environment()
            env.update(os.environ)

            project = get_project(os.getcwd(), config_path, environment=env)
            tlc = TopLevelCommand(project)
            yield tlc
        except Exception:  # noqa: B902
            raise
Example #44
0
def start_ioc(request):
    options = common_options
    options["--project-name"] = "ioc"
    options["--file"] = [os.path.join("compose", "docker-compose-ioc.yml")]
    project = project_from_options(os.path.dirname(__file__), options)
    cmd = TopLevelCommand(project)

    cmd.up(options)

    def fin():
        print("Stopping zookeeper and kafka", flush=True)
        options["--timeout"] = 30
        options["--project-name"] = "ioc"
        options["--file"] = [os.path.join("compose", "docker-compose-ioc.yml")]
        cmd.down(options)

    request.addfinalizer(fin)
Example #45
0
    def test_run_service_with_restart_always(self):
        mock_client = mock.create_autospec(docker.Client)

        project = Project.from_config(
            name='composetest',
            client=mock_client,
            config_data=build_config({
                'service': {
                    'image': 'busybox',
                    'restart': 'always',
                }
            }),
        )

        command = TopLevelCommand(project)
        command.run({
            'SERVICE': 'service',
            'COMMAND': None,
            '-e': [],
            '--user': None,
            '--no-deps': None,
            '-d': True,
            '-T': None,
            '--entrypoint': None,
            '--service-ports': None,
            '--publish': [],
            '--rm': None,
            '--name': None,
            '--workdir': None,
        })

        self.assertEquals(
            mock_client.create_host_config.call_args[1]['restart_policy']['Name'],
            'always'
        )

        command = TopLevelCommand(project)
        command.run({
            'SERVICE': 'service',
            'COMMAND': None,
            '-e': [],
            '--user': None,
            '--no-deps': None,
            '-d': True,
            '-T': None,
            '--entrypoint': None,
            '--service-ports': None,
            '--publish': [],
            '--rm': True,
            '--name': None,
            '--workdir': None,
        })

        self.assertFalse(
            mock_client.create_host_config.call_args[1].get('restart_policy')
        )
Example #46
0
    def test_run_service_with_restart_always(self):
        mock_client = mock.create_autospec(docker.APIClient)
        mock_client.api_version = DEFAULT_DOCKER_API_VERSION
        mock_client._general_configs = {}

        project = Project.from_config(
            name='composetest',
            client=mock_client,
            config_data=build_config({
                'service': {
                    'image': 'busybox',
                    'restart': 'always',
                }
            }),
        )

        command = TopLevelCommand(project)
        command.run({
            'SERVICE': 'service',
            'COMMAND': None,
            '-e': [],
            '--label': [],
            '--user': None,
            '--no-deps': None,
            '--detach': True,
            '-T': None,
            '--entrypoint': None,
            '--service-ports': None,
            '--use-aliases': None,
            '--publish': [],
            '--volume': [],
            '--rm': None,
            '--name': None,
            '--workdir': None,
        })

        assert mock_client.create_host_config.call_args[1]['restart_policy']['Name'] == 'always'

        command = TopLevelCommand(project)
        command.run({
            'SERVICE': 'service',
            'COMMAND': None,
            '-e': [],
            '--label': [],
            '--user': None,
            '--no-deps': None,
            '--detach': True,
            '-T': None,
            '--entrypoint': None,
            '--service-ports': None,
            '--use-aliases': None,
            '--publish': [],
            '--volume': [],
            '--rm': True,
            '--name': None,
            '--workdir': None,
        })

        assert not mock_client.create_host_config.call_args[1].get('restart_policy')
Example #47
0
    def test_run_service_with_restart_always(self):
        mock_client = mock.create_autospec(docker.APIClient)

        project = Project.from_config(
            name='composetest',
            client=mock_client,
            config_data=build_config({
                'service': {
                    'image': 'busybox',
                    'restart': 'always',
                }
            }),
        )

        command = TopLevelCommand(project)
        command.run({
            'SERVICE': 'service',
            'COMMAND': None,
            '-e': [],
            '--user': None,
            '--no-deps': None,
            '-d': True,
            '-T': None,
            '--entrypoint': None,
            '--service-ports': None,
            '--publish': [],
            '--volume': [],
            '--rm': None,
            '--name': None,
            '--workdir': None,
        })

        self.assertEqual(
            mock_client.create_host_config.call_args[1]['restart_policy']['Name'],
            'always'
        )

        command = TopLevelCommand(project)
        command.run({
            'SERVICE': 'service',
            'COMMAND': None,
            '-e': [],
            '--user': None,
            '--no-deps': None,
            '-d': True,
            '-T': None,
            '--entrypoint': None,
            '--service-ports': None,
            '--publish': [],
            '--volume': [],
            '--rm': True,
            '--name': None,
            '--workdir': None,
        })

        self.assertFalse(
            mock_client.create_host_config.call_args[1].get('restart_policy')
        )
Example #48
0
    def test_run_service_with_restart_always(self):
        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service(
            'service',
            client=mock_client,
            restart={'Name': 'always', 'MaximumRetryCount': 0},
            image='someimage')
        command.run(mock_project, {
            'SERVICE': 'service',
            'COMMAND': None,
            '-e': [],
            '--user': None,
            '--no-deps': None,
            '--allow-insecure-ssl': None,
            '-d': True,
            '-T': None,
            '--entrypoint': None,
            '--service-ports': None,
            '--publish': [],
            '--rm': None,
            '--name': None,
        })

        self.assertEquals(
            mock_client.create_host_config.call_args[1]['restart_policy']['Name'],
            'always'
        )

        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service(
            'service',
            client=mock_client,
            restart='always',
            image='someimage')
        command.run(mock_project, {
            'SERVICE': 'service',
            'COMMAND': None,
            '-e': [],
            '--user': None,
            '--no-deps': None,
            '--allow-insecure-ssl': None,
            '-d': True,
            '-T': None,
            '--entrypoint': None,
            '--service-ports': None,
            '--publish': [],
            '--rm': True,
            '--name': None,
        })

        self.assertFalse(
            mock_client.create_host_config.call_args[1].get('restart_policy')
        )
Example #49
0
    def test_run_interactive_passes_logs_false(self, mock_pseudo_terminal, mock_run_operation):
        os.environ['COMPOSE_INTERACTIVE_NO_CLI'] = 'true'
        mock_client = mock.create_autospec(docker.APIClient)
        mock_client.api_version = DEFAULT_DOCKER_API_VERSION
        mock_client._general_configs = {}
        project = Project.from_config(
            name='composetest',
            client=mock_client,
            config_data=build_config({
                'service': {'image': 'busybox'}
            }),
        )
        command = TopLevelCommand(project)

        with pytest.raises(SystemExit):
            command.run({
                'SERVICE': 'service',
                'COMMAND': None,
                '-e': [],
                '--label': [],
                '--user': None,
                '--no-deps': None,
                '--detach': False,
                '-T': None,
                '--entrypoint': None,
                '--service-ports': None,
                '--use-aliases': None,
                '--publish': [],
                '--volume': [],
                '--rm': None,
                '--name': None,
                '--workdir': None,
            })

        _, _, call_kwargs = mock_run_operation.mock_calls[0]
        assert call_kwargs['logs'] is False
Example #50
0
    def test_run_service_with_restart_always(self):
        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service(
            "service", client=mock_client, restart="always", image="someimage"
        )
        command.run(
            mock_project,
            {
                "SERVICE": "service",
                "COMMAND": None,
                "-e": [],
                "--user": None,
                "--no-deps": None,
                "--allow-insecure-ssl": None,
                "-d": True,
                "-T": None,
                "--entrypoint": None,
                "--service-ports": None,
                "--publish": [],
                "--rm": None,
                "--name": None,
            },
        )

        self.assertEquals(mock_client.create_host_config.call_args[1]["restart_policy"]["Name"], "always")

        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service(
            "service", client=mock_client, restart="always", image="someimage"
        )
        command.run(
            mock_project,
            {
                "SERVICE": "service",
                "COMMAND": None,
                "-e": [],
                "--user": None,
                "--no-deps": None,
                "--allow-insecure-ssl": None,
                "-d": True,
                "-T": None,
                "--entrypoint": None,
                "--service-ports": None,
                "--publish": [],
                "--rm": True,
                "--name": None,
            },
        )

        self.assertFalse(mock_client.create_host_config.call_args[1].get("restart_policy"))
Example #51
0
    def test_run_service_with_restart_always(self):
        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service(
            'service',
            client=mock_client,
            restart='always',
            image='someimage')
        command.run(mock_project, {
            'SERVICE': 'service',
            'COMMAND': None,
            '-e': [],
            '--user': None,
            '--no-deps': None,
            '--allow-insecure-ssl': None,
            '-d': True,
            '-T': None,
            '--entrypoint': None,
            '--service-ports': None,
            '--publish': [],
            '--rm': None,
            '--name': None,
        })
        _, _, call_kwargs = mock_client.create_container.mock_calls[0]
        self.assertEquals(call_kwargs['host_config']['RestartPolicy']['Name'], 'always')

        command = TopLevelCommand()
        mock_client = mock.create_autospec(docker.Client)
        mock_project = mock.Mock(client=mock_client)
        mock_project.get_service.return_value = Service(
            'service',
            client=mock_client,
            restart='always',
            image='someimage')
        command.run(mock_project, {
            'SERVICE': 'service',
            'COMMAND': None,
            '-e': [],
            '--user': None,
            '--no-deps': None,
            '--allow-insecure-ssl': None,
            '-d': True,
            '-T': None,
            '--entrypoint': None,
            '--service-ports': None,
            '--publish': [],
            '--rm': True,
            '--name': None,
        })
        _, _, call_kwargs = mock_client.create_container.mock_calls[0]
        self.assertFalse('RestartPolicy' in call_kwargs['host_config'])
Example #52
0
 def test_project_name_with_explicit_project_name(self):
     command = TopLevelCommand()
     name = 'explicit-project-name'
     project_name = command.get_project_name(None, project_name=name)
     self.assertEquals('explicitprojectname', project_name)
Example #53
0
 def test_command_help_nonexistent(self):
     with pytest.raises(NoSuchCommand):
         TopLevelCommand.help({'COMMAND': 'nonexistent'})
Example #54
0
 def test_project_name_with_explicit_base_dir(self):
     command = TopLevelCommand()
     command.base_dir = 'tests/fixtures/simple-composefile'
     project_name = command.get_project_name(command.get_config_path())
     self.assertEquals('simplecomposefile', project_name)
Example #55
0
 def test_project_name_with_explicit_uppercase_base_dir(self):
     command = TopLevelCommand()
     command.base_dir = 'tests/fixtures/UpperCaseDir'
     project_name = command.get_project_name(command.get_config_path())
     self.assertEquals('uppercasedir', project_name)
Example #56
0
 def setUp(self):
     super(CLITestCase, self).setUp()
     self.old_sys_exit = sys.exit
     sys.exit = lambda code=0: None
     self.command = TopLevelCommand()
     self.command.base_dir = 'tests/fixtures/simple-composefile'
Example #57
0
class CLITestCase(DockerClientTestCase):
    def setUp(self):
        super(CLITestCase, self).setUp()
        self.old_sys_exit = sys.exit
        sys.exit = lambda code=0: None
        self.command = TopLevelCommand()
        self.command.base_dir = 'tests/fixtures/simple-composefile'

    def tearDown(self):
        sys.exit = self.old_sys_exit
        self.project.kill()
        self.project.remove_stopped()

    @property
    def project(self):
        return self.command.get_project(self.command.get_config_path())

    def test_help(self):
        old_base_dir = self.command.base_dir
        self.command.base_dir = 'tests/fixtures/no-composefile'
        with self.assertRaises(SystemExit) as exc_context:
            self.command.dispatch(['help', 'up'], None)
            self.assertIn('Usage: up [options] [SERVICE...]', str(exc_context.exception))
        # self.project.kill() fails during teardown
        # unless there is a composefile.
        self.command.base_dir = old_base_dir

    # TODO: address the "Inappropriate ioctl for device" warnings in test output
    @patch('sys.stdout', new_callable=StringIO)
    def test_ps(self, mock_stdout):
        self.project.get_service('simple').create_container()
        self.command.dispatch(['ps'], None)
        self.assertIn('simplecomposefile_simple_1', mock_stdout.getvalue())

    @patch('sys.stdout', new_callable=StringIO)
    def test_ps_default_composefile(self, mock_stdout):
        self.command.base_dir = 'tests/fixtures/multiple-composefiles'
        self.command.dispatch(['up', '-d'], None)
        self.command.dispatch(['ps'], None)

        output = mock_stdout.getvalue()
        self.assertIn('multiplecomposefiles_simple_1', output)
        self.assertIn('multiplecomposefiles_another_1', output)
        self.assertNotIn('multiplecomposefiles_yetanother_1', output)

    @patch('sys.stdout', new_callable=StringIO)
    def test_ps_alternate_composefile(self, mock_stdout):
        self.command.base_dir = 'tests/fixtures/multiple-composefiles'
        self.command.dispatch(['-f', 'compose2.yml', 'up', '-d'], None)
        self.command.dispatch(['-f', 'compose2.yml', 'ps'], None)

        output = mock_stdout.getvalue()
        self.assertNotIn('multiplecomposefiles_simple_1', output)
        self.assertNotIn('multiplecomposefiles_another_1', output)
        self.assertIn('multiplecomposefiles_yetanother_1', output)

    @patch('compose.service.log')
    def test_pull(self, mock_logging):
        self.command.dispatch(['pull'], None)
        mock_logging.info.assert_any_call('Pulling simple (busybox:latest)...')
        mock_logging.info.assert_any_call('Pulling another (busybox:latest)...')

    @patch('sys.stdout', new_callable=StringIO)
    def test_build_no_cache(self, mock_stdout):
        self.command.base_dir = 'tests/fixtures/simple-dockerfile'
        self.command.dispatch(['build', 'simple'], None)

        mock_stdout.truncate(0)
        cache_indicator = 'Using cache'
        self.command.dispatch(['build', 'simple'], None)
        output = mock_stdout.getvalue()
        self.assertIn(cache_indicator, output)

        mock_stdout.truncate(0)
        self.command.dispatch(['build', '--no-cache', 'simple'], None)
        output = mock_stdout.getvalue()
        self.assertNotIn(cache_indicator, output)

    def test_up(self):
        self.command.dispatch(['up', '-d'], None)
        service = self.project.get_service('simple')
        another = self.project.get_service('another')
        self.assertEqual(len(service.containers()), 1)
        self.assertEqual(len(another.containers()), 1)

        # Ensure containers don't have stdin and stdout connected in -d mode
        config = service.containers()[0].inspect()['Config']
        self.assertFalse(config['AttachStderr'])
        self.assertFalse(config['AttachStdout'])
        self.assertFalse(config['AttachStdin'])

    def test_up_with_links(self):
        self.command.base_dir = 'tests/fixtures/links-composefile'
        self.command.dispatch(['up', '-d', 'web'], None)
        web = self.project.get_service('web')
        db = self.project.get_service('db')
        console = self.project.get_service('console')
        self.assertEqual(len(web.containers()), 1)
        self.assertEqual(len(db.containers()), 1)
        self.assertEqual(len(console.containers()), 0)

    def test_up_with_no_deps(self):
        self.command.base_dir = 'tests/fixtures/links-composefile'
        self.command.dispatch(['up', '-d', '--no-deps', 'web'], None)
        web = self.project.get_service('web')
        db = self.project.get_service('db')
        console = self.project.get_service('console')
        self.assertEqual(len(web.containers()), 1)
        self.assertEqual(len(db.containers()), 0)
        self.assertEqual(len(console.containers()), 0)

    def test_up_with_recreate(self):
        self.command.dispatch(['up', '-d'], None)
        service = self.project.get_service('simple')
        self.assertEqual(len(service.containers()), 1)

        old_ids = [c.id for c in service.containers()]

        self.command.dispatch(['up', '-d'], None)
        self.assertEqual(len(service.containers()), 1)

        new_ids = [c.id for c in service.containers()]

        self.assertNotEqual(old_ids, new_ids)

    def test_up_with_keep_old(self):
        self.command.dispatch(['up', '-d'], None)
        service = self.project.get_service('simple')
        self.assertEqual(len(service.containers()), 1)

        old_ids = [c.id for c in service.containers()]

        self.command.dispatch(['up', '-d', '--no-recreate'], None)
        self.assertEqual(len(service.containers()), 1)

        new_ids = [c.id for c in service.containers()]

        self.assertEqual(old_ids, new_ids)

    @patch('dockerpty.start')
    def test_run_service_without_links(self, mock_stdout):
        self.command.base_dir = 'tests/fixtures/links-composefile'
        self.command.dispatch(['run', 'console', '/bin/true'], None)
        self.assertEqual(len(self.project.containers()), 0)

        # Ensure stdin/out was open
        container = self.project.containers(stopped=True, one_off=True)[0]
        config = container.inspect()['Config']
        self.assertTrue(config['AttachStderr'])
        self.assertTrue(config['AttachStdout'])
        self.assertTrue(config['AttachStdin'])

    @patch('dockerpty.start')
    def test_run_service_with_links(self, __):
        self.command.base_dir = 'tests/fixtures/links-composefile'
        self.command.dispatch(['run', 'web', '/bin/true'], None)
        db = self.project.get_service('db')
        console = self.project.get_service('console')
        self.assertEqual(len(db.containers()), 1)
        self.assertEqual(len(console.containers()), 0)

    @patch('dockerpty.start')
    def test_run_with_no_deps(self, __):
        self.command.base_dir = 'tests/fixtures/links-composefile'
        self.command.dispatch(['run', '--no-deps', 'web', '/bin/true'], None)
        db = self.project.get_service('db')
        self.assertEqual(len(db.containers()), 0)

    @patch('dockerpty.start')
    def test_run_does_not_recreate_linked_containers(self, __):
        self.command.base_dir = 'tests/fixtures/links-composefile'
        self.command.dispatch(['up', '-d', 'db'], None)
        db = self.project.get_service('db')
        self.assertEqual(len(db.containers()), 1)

        old_ids = [c.id for c in db.containers()]

        self.command.dispatch(['run', 'web', '/bin/true'], None)
        self.assertEqual(len(db.containers()), 1)

        new_ids = [c.id for c in db.containers()]

        self.assertEqual(old_ids, new_ids)

    @patch('dockerpty.PseudoTerminal')
    def test_run_without_command(self, __):
        self.command.base_dir = 'tests/fixtures/commands-composefile'
        self.check_build('tests/fixtures/simple-dockerfile', tag='composetest_test')

        for c in self.project.containers(stopped=True, one_off=True):
            c.remove()

        self.command.dispatch(['run', 'implicit'], None)
        service = self.project.get_service('implicit')
        containers = service.containers(stopped=True, one_off=True)
        self.assertEqual(
            [c.human_readable_command for c in containers],
            [u'/bin/sh -c echo "success"'],
        )

        self.command.dispatch(['run', 'explicit'], None)
        service = self.project.get_service('explicit')
        containers = service.containers(stopped=True, one_off=True)
        self.assertEqual(
            [c.human_readable_command for c in containers],
            [u'/bin/true'],
        )

    @patch('dockerpty.PseudoTerminal')
    def test_run_service_with_entrypoint_overridden(self, _):
        self.command.base_dir = 'tests/fixtures/dockerfile_with_entrypoint'
        name = 'service'
        self.command.dispatch(
            ['run', '--entrypoint', '/bin/echo', name, 'helloworld'],
            None
        )
        service = self.project.get_service(name)
        container = service.containers(stopped=True, one_off=True)[0]
        self.assertEqual(
            container.human_readable_command,
            u'/bin/echo helloworld'
        )

    @patch('dockerpty.start')
    def test_run_service_with_environement_overridden(self, _):
        name = 'service'
        self.command.base_dir = 'tests/fixtures/environment-composefile'
        self.command.dispatch(
            ['run', '-e', 'foo=notbar', '-e', 'allo=moto=bobo',
             '-e', 'alpha=beta', name],
            None
        )
        service = self.project.get_service(name)
        container = service.containers(stopped=True, one_off=True)[0]
        # env overriden
        self.assertEqual('notbar', container.environment['foo'])
        # keep environement from yaml
        self.assertEqual('world', container.environment['hello'])
        # added option from command line
        self.assertEqual('beta', container.environment['alpha'])
        # make sure a value with a = don't crash out
        self.assertEqual('moto=bobo', container.environment['allo'])

    @patch('dockerpty.start')
    def test_run_service_without_map_ports(self, __):
        # create one off container
        self.command.base_dir = 'tests/fixtures/ports-composefile'
        self.command.dispatch(['run', '-d', 'simple'], None)
        container = self.project.get_service('simple').containers(one_off=True)[0]

        # get port information
        port_random = container.get_local_port(3000)
        port_assigned = container.get_local_port(3001)

        # close all one off containers we just created
        container.stop()

        # check the ports
        self.assertEqual(port_random, None)
        self.assertEqual(port_assigned, None)

    @patch('dockerpty.start')
    def test_run_service_with_map_ports(self, __):
        # create one off container
        self.command.base_dir = 'tests/fixtures/ports-composefile'
        self.command.dispatch(['run', '-d', '--service-ports', 'simple'], None)
        container = self.project.get_service('simple').containers(one_off=True)[0]

        # get port information
        port_random = container.get_local_port(3000)
        port_assigned = container.get_local_port(3001)

        # close all one off containers we just created
        container.stop()

        # check the ports
        self.assertNotEqual(port_random, None)
        self.assertIn("0.0.0.0", port_random)
        self.assertEqual(port_assigned, "0.0.0.0:9999")

    def test_rm(self):
        service = self.project.get_service('simple')
        service.create_container()
        service.kill()
        self.assertEqual(len(service.containers(stopped=True)), 1)
        self.command.dispatch(['rm', '--force'], None)
        self.assertEqual(len(service.containers(stopped=True)), 0)

    def test_kill(self):
        self.command.dispatch(['up', '-d'], None)
        service = self.project.get_service('simple')
        self.assertEqual(len(service.containers()), 1)
        self.assertTrue(service.containers()[0].is_running)

        self.command.dispatch(['kill'], None)

        self.assertEqual(len(service.containers(stopped=True)), 1)
        self.assertFalse(service.containers(stopped=True)[0].is_running)

    def test_kill_signal_sigint(self):
        self.command.dispatch(['up', '-d'], None)
        service = self.project.get_service('simple')
        self.assertEqual(len(service.containers()), 1)
        self.assertTrue(service.containers()[0].is_running)

        self.command.dispatch(['kill', '-s', 'SIGINT'], None)

        self.assertEqual(len(service.containers()), 1)
        # The container is still running. It has been only interrupted
        self.assertTrue(service.containers()[0].is_running)

    def test_kill_interrupted_service(self):
        self.command.dispatch(['up', '-d'], None)
        service = self.project.get_service('simple')
        self.command.dispatch(['kill', '-s', 'SIGINT'], None)
        self.assertTrue(service.containers()[0].is_running)

        self.command.dispatch(['kill', '-s', 'SIGKILL'], None)

        self.assertEqual(len(service.containers(stopped=True)), 1)
        self.assertFalse(service.containers(stopped=True)[0].is_running)

    def test_restart(self):
        service = self.project.get_service('simple')
        container = service.create_container()
        service.start_container(container)
        started_at = container.dictionary['State']['StartedAt']
        self.command.dispatch(['restart'], None)
        container.inspect()
        self.assertNotEqual(
            container.dictionary['State']['FinishedAt'],
            '0001-01-01T00:00:00Z',
        )
        self.assertNotEqual(
            container.dictionary['State']['StartedAt'],
            started_at,
        )

    def test_scale(self):
        project = self.project

        self.command.scale(project, {'SERVICE=NUM': ['simple=1']})
        self.assertEqual(len(project.get_service('simple').containers()), 1)

        self.command.scale(project, {'SERVICE=NUM': ['simple=3', 'another=2']})
        self.assertEqual(len(project.get_service('simple').containers()), 3)
        self.assertEqual(len(project.get_service('another').containers()), 2)

        self.command.scale(project, {'SERVICE=NUM': ['simple=1', 'another=1']})
        self.assertEqual(len(project.get_service('simple').containers()), 1)
        self.assertEqual(len(project.get_service('another').containers()), 1)

        self.command.scale(project, {'SERVICE=NUM': ['simple=1', 'another=1']})
        self.assertEqual(len(project.get_service('simple').containers()), 1)
        self.assertEqual(len(project.get_service('another').containers()), 1)

        self.command.scale(project, {'SERVICE=NUM': ['simple=0', 'another=0']})
        self.assertEqual(len(project.get_service('simple').containers()), 0)
        self.assertEqual(len(project.get_service('another').containers()), 0)

    def test_port(self):
        self.command.base_dir = 'tests/fixtures/ports-composefile'
        self.command.dispatch(['up', '-d'], None)
        container = self.project.get_service('simple').get_container()

        @patch('sys.stdout', new_callable=StringIO)
        def get_port(number, mock_stdout):
            self.command.dispatch(['port', 'simple', str(number)], None)
            return mock_stdout.getvalue().rstrip()

        self.assertEqual(get_port(3000), container.get_local_port(3000))
        self.assertEqual(get_port(3001), "0.0.0.0:9999")
        self.assertEqual(get_port(3002), "")
Example #58
0
 def test_help(self):
     command = TopLevelCommand()
     with self.assertRaises(SystemExit):
         command.dispatch(['-h'], None)