Ejemplo n.º 1
0
    def test_project_platform_value(self):
        service_config = {
            'name': 'web',
            'image': 'busybox:latest',
        }
        config_data = Config(
            version=V2_4, services=[service_config], networks={}, volumes={}, secrets=None, configs=None
        )

        project = Project.from_config(name='test', client=self.mock_client, config_data=config_data)
        assert project.get_service('web').platform is None

        project = Project.from_config(
            name='test', client=self.mock_client, config_data=config_data, default_platform='windows'
        )
        assert project.get_service('web').platform == 'windows'

        service_config['platform'] = 'linux/s390x'
        project = Project.from_config(name='test', client=self.mock_client, config_data=config_data)
        assert project.get_service('web').platform == 'linux/s390x'

        project = Project.from_config(
            name='test', client=self.mock_client, config_data=config_data, default_platform='windows'
        )
        assert project.get_service('web').platform == 'linux/s390x'
Ejemplo n.º 2
0
    def test_project_up_updated_driver(self):
        vol_name = '{0:x}'.format(random.getrandbits(32))
        full_vol_name = 'composetest_{0}'.format(vol_name)

        config_data = config.Config(
            version=2, services=[{
                'name': 'web',
                'image': 'busybox:latest',
                'command': 'top'
            }], volumes={vol_name: {'driver': 'local'}}
        )
        project = Project.from_config(
            name='composetest',
            config_data=config_data, client=self.client
        )
        project.initialize_volumes()

        volume_data = self.client.inspect_volume(full_vol_name)
        self.assertEqual(volume_data['Name'], full_vol_name)
        self.assertEqual(volume_data['Driver'], 'local')

        config_data = config_data._replace(
            volumes={vol_name: {'driver': 'smb'}}
        )
        project = Project.from_config(
            name='composetest',
            config_data=config_data, client=self.client
        )
        with self.assertRaises(config.ConfigurationError) as e:
            project.initialize_volumes()
        assert 'Configuration for volume {0} specifies driver smb'.format(
            vol_name
        ) in str(e.exception)
Ejemplo n.º 3
0
    def test_use_net_from_service(self):
        container_name = 'test_aaa_1'
        self.mock_client.containers.return_value = [{
            "Name": container_name,
            "Names": [container_name],
            "Id": container_name,
            "Image": 'busybox:latest'
        }]
        project = Project.from_config(
            name='test',
            client=self.mock_client,
            config_data=Config(
                version=None,
                services=[
                    {
                        'name': 'aaa',
                        'image': 'busybox:latest'
                    },
                    {
                        'name': 'test',
                        'image': 'busybox:latest',
                        'network_mode': 'service:aaa'
                    },
                ],
                networks=None,
                volumes=None,
            ),
        )

        service = project.get_service('test')
        self.assertEqual(service.network_mode.mode,
                         'container:' + container_name)
Ejemplo n.º 4
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'}
            }),
        )
        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
Ejemplo n.º 5
0
    def test_project_up_with_network_internal(self):
        self.require_api_version('1.23')
        config_data = config.Config(
            version=V2_0,
            services=[{
                'name': 'web',
                'image': 'busybox:latest',
                'networks': {'internal': None},
            }],
            volumes={},
            networks={
                'internal': {'driver': 'bridge', 'internal': True},
            },
        )

        project = Project.from_config(
            client=self.client,
            name='composetest',
            config_data=config_data,
        )
        project.up()

        network = self.client.networks(names=['composetest_internal'])[0]

        assert network['Internal'] is True
Ejemplo n.º 6
0
    def test_up_with_network_static_addresses_missing_subnet(self):
        config_data = config.Config(
            version=V2_0,
            services=[{
                'name': 'web',
                'image': 'busybox:latest',
                'networks': {
                    'static_test': {
                        'ipv4_address': '172.16.100.100',
                        'ipv6_address': 'fe80::1001:101'
                    }
                },
            }],
            volumes={},
            networks={
                'static_test': {
                    'driver': 'bridge',
                    'driver_opts': {
                        "com.docker.network.enable_ipv6": "true",
                    },
                    'ipam': {
                        'driver': 'default',
                    },
                },
            },
        )

        project = Project.from_config(
            client=self.client,
            name='composetest',
            config_data=config_data,
        )

        with self.assertRaises(ProjectError):
            project.up()
Ejemplo n.º 7
0
    def test_project_up_named_volumes_in_binds(self):
        vol_name = '{0:x}'.format(random.getrandbits(32))
        full_vol_name = 'composetest_{0}'.format(vol_name)

        base_file = config.ConfigFile(
            'base.yml',
            {
                'version': V2_0,
                'services': {
                    'simple': {
                        'image': 'busybox:latest',
                        'command': 'top',
                        'volumes': ['{0}:/data'.format(vol_name)]
                    },
                },
                'volumes': {
                    vol_name: {'driver': 'local'}
                }

            })
        config_details = config.ConfigDetails('.', [base_file])
        config_data = config.load(config_details)
        project = Project.from_config(
            name='composetest', config_data=config_data, client=self.client
        )
        service = project.services[0]
        self.assertEqual(service.name, 'simple')
        volumes = service.options.get('volumes')
        self.assertEqual(len(volumes), 1)
        self.assertEqual(volumes[0].external, full_vol_name)
        project.up()
        engine_volumes = self.client.volumes()['Volumes']
        container = service.get_container()
        assert [mount['Name'] for mount in container.get('Mounts')] == [full_vol_name]
        assert next((v for v in engine_volumes if v['Name'] == vol_name), None) is None
Ejemplo n.º 8
0
    def test_project_up_port_mappings_with_multiple_files(self):
        base_file = config.ConfigFile(
            'base.yml',
            {
                'version': V2_0,
                'services': {
                    'simple': {
                        'image': 'busybox:latest',
                        'command': 'top',
                        'ports': ['1234:1234']
                    },
                },

            })
        override_file = config.ConfigFile(
            'override.yml',
            {
                'version': V2_0,
                'services': {
                    'simple': {
                        'ports': ['1234:1234']
                    }
                }

            })
        details = config.ConfigDetails('.', [base_file, override_file])

        config_data = config.load(details)
        project = Project.from_config(
            name='composetest', config_data=config_data, client=self.client
        )
        project.up()
        containers = project.containers()
        self.assertEqual(len(containers), 1)
Ejemplo n.º 9
0
    def test_down_with_no_resources(self):
        project = Project.from_config(
            name='test',
            client=self.mock_client,
            config_data=Config(
                project_name='',
                version=V2_0,
                services=[{
                    'name': 'web',
                    'image': BUSYBOX_IMAGE_WITH_TAG,
                }],
                networks={'default': {}},
                volumes={'data': {}},
                secrets=None,
                configs=None,
            ),
        )
        self.mock_client.remove_network.side_effect = NotFound(
            None, None, 'oops')
        self.mock_client.remove_volume.side_effect = NotFound(
            None, None, 'oops')

        project.down(ImageType.all, True)
        self.mock_client.remove_image.assert_called_once_with(
            BUSYBOX_IMAGE_WITH_TAG)
Ejemplo n.º 10
0
    def test_net_from_container(self):
        net_container = Container.create(
            self.client,
            image='busybox:latest',
            name='composetest_net_container',
            command='top',
            labels={LABEL_PROJECT: 'composetest'},
        )
        net_container.start()

        project = Project.from_config(
            name='composetest',
            config_data=build_service_dicts({
                'web': {
                    'image': 'busybox:latest',
                    'net': 'container:composetest_net_container'
                },
            }),
            client=self.client,
        )

        project.up()

        web = project.get_service('web')
        self.assertEqual(web.net.mode, 'container:' + net_container.id)
Ejemplo n.º 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
Ejemplo n.º 12
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,
            })
Ejemplo n.º 13
0
 def test_net_unset(self):
     project = Project.from_config(
         "test", Config(None, [{"name": "test", "image": "busybox:latest"}], None), self.mock_client
     )
     service = project.get_service("test")
     self.assertEqual(service.net.id, None)
     self.assertNotIn("NetworkMode", service._get_container_host_config({}))
Ejemplo n.º 14
0
 def test_container_without_name(self):
     self.mock_client.containers.return_value = [
         {
             'Image': 'busybox:latest',
             'Id': '1',
             'Name': '1'
         },
         {
             'Image': 'busybox:latest',
             'Id': '2',
             'Name': None
         },
         {
             'Image': 'busybox:latest',
             'Id': '3'
         },
     ]
     self.mock_client.inspect_container.return_value = {
         'Id': '1',
         'Config': {
             'Labels': {
                 LABEL_SERVICE: 'web',
             },
         },
     }
     project = Project.from_config(
         'test',
         Config(None, [{
             'name': 'web',
             'image': 'busybox:latest',
         }], None),
         self.mock_client,
     )
     self.assertEqual([c.id for c in project.containers()], ['1'])
Ejemplo n.º 15
0
    def test_project_up_volumes(self):
        vol_name = '{0:x}'.format(random.getrandbits(32))
        full_vol_name = 'composetest_{0}'.format(vol_name)
        config_data = config.Config(
            version=V2_0,
            services=[{
                'name': 'web',
                'image': 'busybox:latest',
                'command': 'top'
            }],
            volumes={vol_name: {
                'driver': 'local'
            }},
            networks={},
        )

        project = Project.from_config(name='composetest',
                                      config_data=config_data,
                                      client=self.client)
        project.up()
        self.assertEqual(len(project.containers()), 1)

        volume_data = self.client.inspect_volume(full_vol_name)
        self.assertEqual(volume_data['Name'], full_vol_name)
        self.assertEqual(volume_data['Driver'], 'local')
Ejemplo n.º 16
0
 def test_use_volumes_from_container(self):
     container_id = 'aabbccddee'
     container_dict = dict(Name='aaa', Id=container_id)
     self.mock_client.inspect_container.return_value = container_dict
     project = Project.from_config(
         name='test',
         client=self.mock_client,
         config_data=Config(
             project_name='',
             version=V2_0,
             services=[{
                 'name':
                 'test',
                 'image':
                 BUSYBOX_IMAGE_WITH_TAG,
                 'volumes_from': [VolumeFromSpec('aaa', 'rw', 'container')]
             }],
             networks=None,
             volumes=None,
             secrets=None,
             configs=None,
         ),
     )
     assert project.get_service('test')._get_volumes_from() == [
         container_id + ":rw"
     ]
Ejemplo n.º 17
0
 def test_use_net_from_container(self):
     container_id = 'aabbccddee'
     container_dict = dict(Name='aaa', Id=container_id)
     self.mock_client.inspect_container.return_value = container_dict
     project = Project.from_config(
         name='test',
         client=self.mock_client,
         config_data=Config(
             project_name='',
             version=V2_0,
             services=[
                 {
                     'name': 'test',
                     'image': BUSYBOX_IMAGE_WITH_TAG,
                     'network_mode': 'container:aaa'
                 },
             ],
             networks=None,
             volumes=None,
             secrets=None,
             configs=None,
         ),
     )
     service = project.get_service('test')
     assert service.network_mode.mode == 'container:' + container_id
Ejemplo n.º 18
0
    def test_project_up_starts_depends(self):
        project = Project.from_config(
            name='composetest',
            config_data=build_service_dicts({
                'console': {
                    'image': 'busybox:latest',
                    'command': ["top"],
                },
                'data': {
                    'image': 'busybox:latest',
                    'command': ["top"]
                },
                'db': {
                    'image': 'busybox:latest',
                    'command': ["top"],
                    'volumes_from': ['data'],
                },
                'web': {
                    'image': 'busybox:latest',
                    'command': ["top"],
                    'links': ['db'],
                },
            }),
            client=self.client,
        )
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['web'])
        self.assertEqual(len(project.containers()), 3)
        self.assertEqual(len(project.get_service('web').containers()), 1)
        self.assertEqual(len(project.get_service('db').containers()), 1)
        self.assertEqual(len(project.get_service('data').containers()), 1)
        self.assertEqual(len(project.get_service('console').containers()), 0)
Ejemplo n.º 19
0
    def test_error_parallel_pull(self, mock_write):
        project = Project.from_config(
            name='test',
            client=self.mock_client,
            config_data=Config(
                project_name='',
                version=V2_0,
                services=[{
                    'name': 'web',
                    'image': BUSYBOX_IMAGE_WITH_TAG,
                }],
                networks=None,
                volumes=None,
                secrets=None,
                configs=None,
            ),
        )

        self.mock_client.pull.side_effect = OperationFailedError('pull error')
        with pytest.raises(ProjectError):
            project.pull(parallel_pull=True)

        self.mock_client.pull.side_effect = OperationFailedError(b'pull error')
        with pytest.raises(ProjectError):
            project.pull(parallel_pull=True)
Ejemplo n.º 20
0
    def test_project_up_networks(self):
        config_data = config.Config(
            version=V2_0,
            services=[{
                'name': 'web',
                'image': 'busybox:latest',
                'command': 'top',
                'networks': ['foo', 'bar', 'baz'],
            }],
            volumes={},
            networks={
                'foo': {'driver': 'bridge'},
                'bar': {'driver': None},
                'baz': {},
            },
        )

        project = Project.from_config(
            client=self.client,
            name='composetest',
            config_data=config_data,
        )
        project.up()
        self.assertEqual(len(project.containers()), 1)

        for net_name in ['foo', 'bar', 'baz']:
            full_net_name = 'composetest_{}'.format(net_name)
            network_data = self.client.inspect_network(full_net_name)
            self.assertEqual(network_data['Name'], full_net_name)

        foo_data = self.client.inspect_network('composetest_foo')
        self.assertEqual(foo_data['Driver'], 'bridge')
Ejemplo n.º 21
0
    def test_initialize_volumes_external_volumes(self):
        # Use composetest_ prefix so it gets garbage-collected in tearDown()
        vol_name = 'composetest_{0:x}'.format(random.getrandbits(32))
        full_vol_name = 'composetest_{0}'.format(vol_name)
        self.client.create_volume(vol_name)
        config_data = config.Config(
            version=V2_0,
            services=[{
                'name': 'web',
                'image': 'busybox:latest',
                'command': 'top'
            }],
            volumes={
                vol_name: {'external': True, 'external_name': vol_name}
            },
            networks=None,
        )
        project = Project.from_config(
            name='composetest',
            config_data=config_data, client=self.client
        )
        project.volumes.initialize()

        with self.assertRaises(NotFound):
            self.client.inspect_volume(full_vol_name)
Ejemplo n.º 22
0
 def test_use_net_from_container(self):
     container_id = 'aabbccddee'
     container_dict = dict(Name='aaa', Id=container_id)
     self.mock_client.inspect_container.return_value = container_dict
     project = Project.from_config(
         name='test',
         client=self.mock_client,
         config_data=Config(
             version=None,
             services=[
                 {
                     'name': 'test',
                     'image': 'busybox:latest',
                     'network_mode': 'container:aaa'
                 },
             ],
             networks=None,
             volumes=None,
             secrets=None,
             configs=None,
         ),
     )
     service = project.get_service('test')
     self.assertEqual(service.network_mode.mode,
                      'container:' + container_id)
Ejemplo n.º 23
0
    def test_project_up_with_no_deps(self):
        project = Project.from_config(
            name='composetest',
            config_data=build_config({
                'console': {
                    'image': 'busybox:latest',
                    'command': ["top"],
                },
                'data': {
                    'image': 'busybox:latest',
                    'command': ["top"]
                },
                'db': {
                    'image': 'busybox:latest',
                    'command': ["top"],
                    'volumes_from': ['data'],
                },
                'web': {
                    'image': 'busybox:latest',
                    'command': ["top"],
                    'links': ['db'],
                },
            }),
            client=self.client,
        )
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['db'], start_deps=False)
        self.assertEqual(len(project.containers(stopped=True)), 2)
        self.assertEqual(len(project.get_service('web').containers()), 0)
        self.assertEqual(len(project.get_service('db').containers()), 1)
        self.assertEqual(len(project.get_service('data').containers()), 0)
        self.assertEqual(len(project.get_service('data').containers(stopped=True)), 1)
        self.assertEqual(len(project.get_service('console').containers()), 0)
Ejemplo n.º 24
0
    def test_build_container_operation_with_timeout_func_does_not_mutate_options_with_timeout(self):
        config_data = Config(
            version=V3_7,
            services=[
                {'name': 'web', 'image': 'busybox:latest'},
                {'name': 'db', 'image': 'busybox:latest', 'stop_grace_period': '1s'},
            ],
            networks={}, volumes={}, secrets=None, configs=None,
        )

        project = Project.from_config(name='test', client=self.mock_client, config_data=config_data)

        stop_op = project.build_container_operation_with_timeout_func('stop', options={})

        web_container = mock.create_autospec(Container, service='web')
        db_container = mock.create_autospec(Container, service='db')

        # `stop_grace_period` is not set to 'web' service,
        # then it is stopped with the default timeout.
        stop_op(web_container)
        web_container.stop.assert_called_once_with(timeout=DEFAULT_TIMEOUT)

        # `stop_grace_period` is set to 'db' service,
        # then it is stopped with the specified timeout and
        # the value is not overridden by the previous function call.
        stop_op(db_container)
        db_container.stop.assert_called_once_with(timeout=1)
Ejemplo n.º 25
0
    def test_up_with_network_link_local_ips(self):
        config_data = config.Config(
            version=V2_1,
            services=[{
                'name': 'web',
                'image': 'busybox:latest',
                'networks': {
                    'linklocaltest': {
                        'link_local_ips': ['169.254.8.8']
                    }
                }
            }],
            volumes={},
            networks={
                'linklocaltest': {'driver': 'bridge'}
            }
        )
        project = Project.from_config(
            client=self.client,
            name='composetest',
            config_data=config_data
        )
        project.up(detached=True)

        service_container = project.get_service('web').containers(stopped=True)[0]
        ipam_config = service_container.inspect().get(
            'NetworkSettings', {}
        ).get(
            'Networks', {}
        ).get(
            'composetest_linklocaltest', {}
        ).get('IPAMConfig', {})
        assert 'LinkLocalIPs' in ipam_config
        assert ipam_config['LinkLocalIPs'] == ['169.254.8.8']
Ejemplo n.º 26
0
 def test_from_config(self):
     config = Config(
         version=None,
         services=[
             {
                 'name': 'web',
                 'image': 'busybox:latest',
             },
             {
                 'name': 'db',
                 'image': 'busybox:latest',
             },
         ],
         networks=None,
         volumes=None,
     )
     project = Project.from_config(
         name='composetest',
         config_data=config,
         client=None,
     )
     self.assertEqual(len(project.services), 2)
     self.assertEqual(project.get_service('web').name, 'web')
     self.assertEqual(
         project.get_service('web').options['image'], 'busybox:latest')
     self.assertEqual(project.get_service('db').name, 'db')
     self.assertEqual(
         project.get_service('db').options['image'], 'busybox:latest')
     self.assertFalse(project.networks.use_networking)
Ejemplo n.º 27
0
    def test_project_up_with_network_label(self):
        self.require_api_version('1.23')

        network_name = 'network_with_label'

        config_data = config.Config(
            version=V2_0,
            services=[{
                'name': 'web',
                'image': 'busybox:latest',
                'networks': {network_name: None}
            }],
            volumes={},
            networks={
                network_name: {'labels': {'label_key': 'label_val'}}
            }
        )

        project = Project.from_config(
            client=self.client,
            name='composetest',
            config_data=config_data
        )

        project.up()

        networks = [
            n for n in self.client.networks()
            if n['Name'].startswith('composetest_')
        ]

        assert [n['Name'] for n in networks] == ['composetest_{}'.format(network_name)]

        assert networks[0]['Labels'] == {'label_key': 'label_val'}
Ejemplo n.º 28
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,
            })
Ejemplo n.º 29
0
    def test_initialize_volumes_external_volumes(self):
        # Use composetest_ prefix so it gets garbage-collected in tearDown()
        vol_name = 'composetest_{0:x}'.format(random.getrandbits(32))
        full_vol_name = 'composetest_{0}'.format(vol_name)
        self.client.create_volume(vol_name)
        config_data = config.Config(
            version=V2_0,
            services=[{
                'name': 'web',
                'image': 'busybox:latest',
                'command': 'top'
            }],
            volumes={
                vol_name: {'external': True, 'external_name': vol_name}
            },
            networks=None,
        )
        project = Project.from_config(
            name='composetest',
            config_data=config_data, client=self.client
        )
        project.volumes.initialize()

        with self.assertRaises(NotFound):
            self.client.inspect_volume(full_vol_name)
Ejemplo n.º 30
0
 def test_from_config(self):
     config = Config(
         version=None,
         services=[
             {
                 'name': 'web',
                 'image': 'busybox:latest',
             },
             {
                 'name': 'db',
                 'image': 'busybox:latest',
             },
         ],
         networks=None,
         volumes=None,
         plugins=None,
     )
     project = Project.from_config(
         name='composetest',
         config_data=config,
         client=None,
     )
     self.assertEqual(len(project.services), 2)
     self.assertEqual(project.get_service('web').name, 'web')
     self.assertEqual(project.get_service('web').options['image'], 'busybox:latest')
     self.assertEqual(project.get_service('db').name, 'db')
     self.assertEqual(project.get_service('db').options['image'], 'busybox:latest')
     self.assertFalse(project.networks.use_networking)
Ejemplo n.º 31
0
 def test_use_volumes_from_service_no_container(self):
     container_name = 'test_vol_1'
     self.mock_client.containers.return_value = [
         {
             "Name": container_name,
             "Names": [container_name],
             "Id": container_name,
             "Image": 'busybox:latest'
         }
     ]
     project = Project.from_config(
         name='test',
         client=self.mock_client,
         config_data=Config(
             version=None,
             services=[
                 {
                     'name': 'vol',
                     'image': 'busybox:latest'
                 },
                 {
                     'name': 'test',
                     'image': 'busybox:latest',
                     'volumes_from': [VolumeFromSpec('vol', 'rw', 'service')]
                 }
             ],
             networks=None,
             volumes=None,
             plugins=None,
         ),
     )
     assert project.get_service('test')._get_volumes_from() == [container_name + ":rw"]
Ejemplo n.º 32
0
 def test_from_config_v1(self):
     config = Config(
         version=V1,
         services=[
             {
                 'name': 'web',
                 'image': 'busybox:latest',
             },
             {
                 'name': 'db',
                 'image': 'busybox:latest',
             },
         ],
         networks=None,
         volumes=None,
         secrets=None,
         configs=None,
     )
     project = Project.from_config(
         name='composetest',
         config_data=config,
         client=None,
     )
     assert len(project.services) == 2
     assert project.get_service('web').name == 'web'
     assert project.get_service('web').options['image'] == 'busybox:latest'
     assert project.get_service('db').name == 'db'
     assert project.get_service('db').options['image'] == 'busybox:latest'
     assert not project.networks.use_networking
Ejemplo n.º 33
0
    def test_project_up_named_volumes_in_binds(self):
        vol_name = '{0:x}'.format(random.getrandbits(32))
        full_vol_name = 'composetest_{0}'.format(vol_name)

        base_file = config.ConfigFile(
            'base.yml',
            {
                'version': V2_0,
                'services': {
                    'simple': {
                        'image': 'busybox:latest',
                        'command': 'top',
                        'volumes': ['{0}:/data'.format(vol_name)]
                    },
                },
                'volumes': {
                    vol_name: {'driver': 'local'}
                }

            })
        config_details = config.ConfigDetails('.', [base_file])
        config_data = config.load(config_details)
        project = Project.from_config(
            name='composetest', config_data=config_data, client=self.client
        )
        service = project.services[0]
        self.assertEqual(service.name, 'simple')
        volumes = service.options.get('volumes')
        self.assertEqual(len(volumes), 1)
        self.assertEqual(volumes[0].external, full_vol_name)
        project.up()
        engine_volumes = self.client.volumes()['Volumes']
        container = service.get_container()
        assert [mount['Name'] for mount in container.get('Mounts')] == [full_vol_name]
        assert next((v for v in engine_volumes if v['Name'] == vol_name), None) is None
Ejemplo n.º 34
0
    def test_project_up_with_no_deps(self):
        project = Project.from_config(
            name='composetest',
            config_data=build_config({
                'console': {
                    'image': 'busybox:latest',
                    'command': ["top"],
                },
                'data': {
                    'image': 'busybox:latest',
                    'command': ["top"]
                },
                'db': {
                    'image': 'busybox:latest',
                    'command': ["top"],
                    'volumes_from': ['data'],
                },
                'web': {
                    'image': 'busybox:latest',
                    'command': ["top"],
                    'links': ['db'],
                },
            }),
            client=self.client,
        )
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['db'], start_deps=False)
        self.assertEqual(len(project.containers(stopped=True)), 2)
        self.assertEqual(len(project.get_service('web').containers()), 0)
        self.assertEqual(len(project.get_service('db').containers()), 1)
        self.assertEqual(len(project.get_service('data').containers()), 0)
        self.assertEqual(len(project.get_service('data').containers(stopped=True)), 1)
        self.assertEqual(len(project.get_service('console').containers()), 0)
Ejemplo n.º 35
0
    def test_project_up_networks(self):
        config_data = config.Config(
            version=V2_0,
            services=[{
                'name': 'web',
                'image': 'busybox:latest',
                'command': 'top',
                'networks': {'foo': None, 'bar': None, 'baz': None},
            }],
            volumes={},
            networks={
                'foo': {'driver': 'bridge'},
                'bar': {'driver': None},
                'baz': {},
            },
        )

        project = Project.from_config(
            client=self.client,
            name='composetest',
            config_data=config_data,
        )
        project.up()
        self.assertEqual(len(project.containers()), 1)

        for net_name in ['foo', 'bar', 'baz']:
            full_net_name = 'composetest_{}'.format(net_name)
            network_data = self.client.inspect_network(full_net_name)
            self.assertEqual(network_data['Name'], full_net_name)

        foo_data = self.client.inspect_network('composetest_foo')
        self.assertEqual(foo_data['Driver'], 'bridge')
Ejemplo n.º 36
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
Ejemplo n.º 37
0
 def test_container_without_name(self):
     self.mock_client.containers.return_value = [
         {'Image': BUSYBOX_IMAGE_WITH_TAG, 'Id': '1', 'Name': '1'},
         {'Image': BUSYBOX_IMAGE_WITH_TAG, 'Id': '2', 'Name': None},
         {'Image': BUSYBOX_IMAGE_WITH_TAG, 'Id': '3'},
     ]
     self.mock_client.inspect_container.return_value = {
         'Id': '1',
         'Config': {
             'Labels': {
                 LABEL_SERVICE: 'web',
             },
         },
     }
     project = Project.from_config(
         name='test',
         client=self.mock_client,
         config_data=Config(
             version=V2_0,
             services=[{
                 'name': 'web',
                 'image': BUSYBOX_IMAGE_WITH_TAG,
             }],
             networks=None,
             volumes=None,
             secrets=None,
             configs=None,
         ),
     )
     assert [c.id for c in project.containers()] == ['1']
Ejemplo n.º 38
0
    def test_build_container_operation_with_timeout_func_does_not_mutate_options_with_timeout(self):
        config_data = Config(
            version=V3_7,
            services=[
                {'name': 'web', 'image': BUSYBOX_IMAGE_WITH_TAG},
                {'name': 'db', 'image': BUSYBOX_IMAGE_WITH_TAG, 'stop_grace_period': '1s'},
            ],
            networks={}, volumes={}, secrets=None, configs=None,
        )

        project = Project.from_config(name='test', client=self.mock_client, config_data=config_data)

        stop_op = project.build_container_operation_with_timeout_func('stop', options={})

        web_container = mock.create_autospec(Container, service='web')
        db_container = mock.create_autospec(Container, service='db')

        # `stop_grace_period` is not set to 'web' service,
        # then it is stopped with the default timeout.
        stop_op(web_container)
        web_container.stop.assert_called_once_with(timeout=DEFAULT_TIMEOUT)

        # `stop_grace_period` is set to 'db' service,
        # then it is stopped with the specified timeout and
        # the value is not overridden by the previous function call.
        stop_op(db_container)
        db_container.stop.assert_called_once_with(timeout=1)
Ejemplo n.º 39
0
 def test_from_config_v1(self):
     config = Config(
         version=V1,
         services=[
             {
                 'name': 'web',
                 'image': BUSYBOX_IMAGE_WITH_TAG,
             },
             {
                 'name': 'db',
                 'image': BUSYBOX_IMAGE_WITH_TAG,
             },
         ],
         networks=None,
         volumes=None,
         secrets=None,
         configs=None,
     )
     project = Project.from_config(
         name='composetest',
         config_data=config,
         client=None,
     )
     assert len(project.services) == 2
     assert project.get_service('web').name == 'web'
     assert project.get_service('web').options['image'] == BUSYBOX_IMAGE_WITH_TAG
     assert project.get_service('db').name == 'db'
     assert project.get_service('db').options['image'] == BUSYBOX_IMAGE_WITH_TAG
     assert not project.networks.use_networking
Ejemplo n.º 40
0
    def test_use_net_from_service(self):
        container_name = 'test_aaa_1'
        self.mock_client.containers.return_value = [
            {
                "Name": container_name,
                "Names": [container_name],
                "Id": container_name,
                "Image": BUSYBOX_IMAGE_WITH_TAG
            }
        ]
        project = Project.from_config(
            name='test',
            client=self.mock_client,
            config_data=Config(
                version=V2_0,
                services=[
                    {
                        'name': 'aaa',
                        'image': BUSYBOX_IMAGE_WITH_TAG
                    },
                    {
                        'name': 'test',
                        'image': BUSYBOX_IMAGE_WITH_TAG,
                        'network_mode': 'service:aaa'
                    },
                ],
                networks=None,
                volumes=None,
                secrets=None,
                configs=None,
            ),
        )

        service = project.get_service('test')
        assert service.network_mode.mode == 'container:' + container_name
Ejemplo n.º 41
0
    def test_use_volumes_from_service_container(self):
        container_ids = ['aabbccddee', '12345']

        project = Project.from_config(
            name='test',
            client=None,
            config_data=Config(
                version=V2_0,
                services=[
                    {
                        'name': 'vol',
                        'image': BUSYBOX_IMAGE_WITH_TAG
                    },
                    {
                        'name': 'test',
                        'image': BUSYBOX_IMAGE_WITH_TAG,
                        'volumes_from': [VolumeFromSpec('vol', 'rw', 'service')]
                    }
                ],
                networks=None,
                volumes=None,
                secrets=None,
                configs=None,
            ),
        )
        with mock.patch.object(Service, 'containers') as mock_return:
            mock_return.return_value = [
                mock.Mock(id=container_id, spec=Container)
                for container_id in container_ids]
            assert (
                project.get_service('test')._get_volumes_from() ==
                [container_ids[0] + ':rw']
            )
Ejemplo n.º 42
0
 def test_use_volumes_from_service_no_container(self):
     container_name = 'test_vol_1'
     self.mock_client.containers.return_value = [
         {
             "Name": container_name,
             "Names": [container_name],
             "Id": container_name,
             "Image": BUSYBOX_IMAGE_WITH_TAG
         }
     ]
     project = Project.from_config(
         name='test',
         client=self.mock_client,
         config_data=Config(
             version=V2_0,
             services=[
                 {
                     'name': 'vol',
                     'image': BUSYBOX_IMAGE_WITH_TAG
                 },
                 {
                     'name': 'test',
                     'image': BUSYBOX_IMAGE_WITH_TAG,
                     'volumes_from': [VolumeFromSpec('vol', 'rw', 'service')]
                 }
             ],
             networks=None,
             volumes=None,
             secrets=None,
             configs=None,
         ),
     )
     assert project.get_service('test')._get_volumes_from() == [container_name + ":rw"]
Ejemplo n.º 43
0
    def test_up_with_network_static_addresses_missing_subnet(self):
        config_data = config.Config(
            version=V2_0,
            services=[{
                'name': 'web',
                'image': 'busybox:latest',
                'networks': {
                    'static_test': {
                        'ipv4_address': '172.16.100.100',
                        'ipv6_address': 'fe80::1001:101'
                    }
                },
            }],
            volumes={},
            networks={
                'static_test': {
                    'driver': 'bridge',
                    'driver_opts': {
                        "com.docker.network.enable_ipv6": "true",
                    },
                    'ipam': {
                        'driver': 'default',
                    },
                },
            },
        )

        project = Project.from_config(
            client=self.client,
            name='composetest',
            config_data=config_data,
        )

        assert len(project.up()) == 0
Ejemplo n.º 44
0
    def test_use_net_from_service(self):
        container_name = 'test_aaa_1'
        self.mock_client.containers.return_value = [
            {
                "Name": container_name,
                "Names": [container_name],
                "Id": container_name,
                "Image": 'busybox:latest'
            }
        ]
        project = Project.from_config(
            name='test',
            client=self.mock_client,
            config_data=Config(
                version=None,
                services=[
                    {
                        'name': 'aaa',
                        'image': 'busybox:latest'
                    },
                    {
                        'name': 'test',
                        'image': 'busybox:latest',
                        'network_mode': 'service:aaa'
                    },
                ],
                networks=None,
                volumes=None,
                plugins=None,
            ),
        )

        service = project.get_service('test')
        self.assertEqual(service.network_mode.mode, 'container:' + container_name)
Ejemplo n.º 45
0
    def test_network_mode_from_service(self):
        project = Project.from_config(
            name='composetest',
            client=self.client,
            config_data=build_config({
                'version': V2_0,
                'services': {
                    'net': {
                        'image': 'busybox:latest',
                        'command': ["top"]
                    },
                    'web': {
                        'image': 'busybox:latest',
                        'network_mode': 'service:net',
                        'command': ["top"]
                    },
                },
            }),
        )

        project.up()

        web = project.get_service('web')
        net = project.get_service('net')
        self.assertEqual(web.network_mode.mode,
                         'container:' + net.containers()[0].id)
Ejemplo n.º 46
0
 def test_container_without_name(self):
     self.mock_client.containers.return_value = [
         {'Image': 'busybox:latest', 'Id': '1', 'Name': '1'},
         {'Image': 'busybox:latest', 'Id': '2', 'Name': None},
         {'Image': 'busybox:latest', 'Id': '3'},
     ]
     self.mock_client.inspect_container.return_value = {
         'Id': '1',
         'Config': {
             'Labels': {
                 LABEL_SERVICE: 'web',
             },
         },
     }
     project = Project.from_config(
         name='test',
         client=self.mock_client,
         config_data=Config(
             version=None,
             services=[{
                 'name': 'web',
                 'image': 'busybox:latest',
             }],
             networks=None,
             volumes=None,
             plugins=None,
         ),
     )
     self.assertEqual([c.id for c in project.containers()], ['1'])
Ejemplo n.º 47
0
    def test_project_up_with_network_internal(self):
        self.require_api_version('1.23')
        config_data = config.Config(
            version=V2_0,
            services=[{
                'name': 'web',
                'image': 'busybox:latest',
                'networks': {'internal': None},
            }],
            volumes={},
            networks={
                'internal': {'driver': 'bridge', 'internal': True},
            },
        )

        project = Project.from_config(
            client=self.client,
            name='composetest',
            config_data=config_data,
        )
        project.up()

        network = self.client.networks(names=['composetest_internal'])[0]

        assert network['Internal'] is True
Ejemplo n.º 48
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,
            })
Ejemplo n.º 49
0
    def test_net_from_container(self):
        net_container = Container.create(
            self.client,
            image='busybox:latest',
            name='composetest_net_container',
            command='top',
            labels={LABEL_PROJECT: 'composetest'},
        )
        net_container.start()

        project = Project.from_config(
            name='composetest',
            config_data=build_service_dicts({
                'web': {
                    'image': 'busybox:latest',
                    'net': 'container:composetest_net_container'
                },
            }),
            client=self.client,
        )

        project.up()

        web = project.get_service('web')
        self.assertEqual(web.net.mode, 'container:' + net_container.id)
Ejemplo n.º 50
0
    def test_project_up_starts_depends(self):
        project = Project.from_config(
            name='composetest',
            config_data=build_service_dicts({
                'console': {
                    'image': 'busybox:latest',
                    'command': ["top"],
                },
                'data': {
                    'image': 'busybox:latest',
                    'command': ["top"]
                },
                'db': {
                    'image': 'busybox:latest',
                    'command': ["top"],
                    'volumes_from': ['data'],
                },
                'web': {
                    'image': 'busybox:latest',
                    'command': ["top"],
                    'links': ['db'],
                },
            }),
            client=self.client,
        )
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['web'])
        self.assertEqual(len(project.containers()), 3)
        self.assertEqual(len(project.get_service('web').containers()), 1)
        self.assertEqual(len(project.get_service('db').containers()), 1)
        self.assertEqual(len(project.get_service('data').containers()), 1)
        self.assertEqual(len(project.get_service('console').containers()), 0)
Ejemplo n.º 51
0
    def test_project_up_port_mappings_with_multiple_files(self):
        base_file = config.ConfigFile(
            'base.yml',
            {
                'version': V2_0,
                'services': {
                    'simple': {
                        'image': 'busybox:latest',
                        'command': 'top',
                        'ports': ['1234:1234']
                    },
                },

            })
        override_file = config.ConfigFile(
            'override.yml',
            {
                'version': V2_0,
                'services': {
                    'simple': {
                        'ports': ['1234:1234']
                    }
                }

            })
        details = config.ConfigDetails('.', [base_file, override_file])

        config_data = config.load(details)
        project = Project.from_config(
            name='composetest', config_data=config_data, client=self.client
        )
        project.up()
        containers = project.containers()
        self.assertEqual(len(containers), 1)
Ejemplo n.º 52
0
    def test_network_mode_from_service(self):
        project = Project.from_config(
            name='composetest',
            client=self.client,
            config_data=build_config({
                'version': V2_0,
                'services': {
                    'net': {
                        'image': 'busybox:latest',
                        'command': ["top"]
                    },
                    'web': {
                        'image': 'busybox:latest',
                        'network_mode': 'service:net',
                        'command': ["top"]
                    },
                },
            }),
        )

        project.up()

        web = project.get_service('web')
        net = project.get_service('net')
        self.assertEqual(web.network_mode.mode, 'container:' + net.containers()[0].id)
Ejemplo n.º 53
0
    def test_use_volumes_from_service_container(self):
        container_ids = ['aabbccddee', '12345']

        project = Project.from_config(
            name='test',
            client=None,
            config_data=Config(
                version=None,
                services=[
                    {
                        'name': 'vol',
                        'image': 'busybox:latest'
                    },
                    {
                        'name': 'test',
                        'image': 'busybox:latest',
                        'volumes_from': [VolumeFromSpec('vol', 'rw', 'service')]
                    }
                ],
                networks=None,
                volumes=None,
                plugins=None,
            ),
        )
        with mock.patch.object(Service, 'containers') as mock_return:
            mock_return.return_value = [
                mock.Mock(id=container_id, spec=Container)
                for container_id in container_ids]
            assert (
                project.get_service('test')._get_volumes_from() ==
                [container_ids[0] + ':rw']
            )
Ejemplo n.º 54
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')
Ejemplo n.º 55
0
    def test_up_with_ipam_config(self):
        config_data = config.Config(
            version=V2_0,
            services=[{
                'name': 'web',
                'image': 'busybox:latest',
                'networks': {'front': None},
            }],
            volumes={},
            networks={
                'front': {
                    'driver': 'bridge',
                    'driver_opts': {
                        "com.docker.network.bridge.enable_icc": "false",
                    },
                    'ipam': {
                        'driver': 'default',
                        'config': [{
                            "subnet": "172.28.0.0/16",
                            "ip_range": "172.28.5.0/24",
                            "gateway": "172.28.5.254",
                            "aux_addresses": {
                                "a": "172.28.1.5",
                                "b": "172.28.1.6",
                                "c": "172.28.1.7",
                            },
                        }],
                    },
                },
            },
        )

        project = Project.from_config(
            client=self.client,
            name='composetest',
            config_data=config_data,
        )
        project.up()

        network = self.client.networks(names=['composetest_front'])[0]

        assert network['Options'] == {
            "com.docker.network.bridge.enable_icc": "false"
        }

        assert network['IPAM'] == {
            'Driver': 'default',
            'Options': None,
            'Config': [{
                'Subnet': "172.28.0.0/16",
                'IPRange': "172.28.5.0/24",
                'Gateway': "172.28.5.254",
                'AuxiliaryAddresses': {
                    'a': '172.28.1.5',
                    'b': '172.28.1.6',
                    'c': '172.28.1.7',
                },
            }],
        }
Ejemplo n.º 56
0
    def get_auxiliary_project(self):
        config_details = config.find(self.auxiliary_project, [], Environment(self.environment()))
        project_name = self.auxiliary_project_name
        config_data = dork_config_load([], config_details)

        client = get_client(self.environment(), version=API_VERSIONS[config_data.version])

        return Project.from_config(project_name, config_data, client)
Ejemplo n.º 57
0
 def make_project(self, cfg):
     details = config.ConfigDetails(
         'working_dir',
         [config.ConfigFile(None, cfg)])
     return Project.from_config(
         name='composetest',
         client=self.client,
         config_data=config.load(details))
Ejemplo n.º 58
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')
        )