diff --git a/compose/service.py b/compose/service.py index 0aaf3cf37..e989d4877 100644 --- a/compose/service.py +++ b/compose/service.py @@ -685,6 +685,7 @@ class Service(object): 'links': self.get_link_names(), 'net': self.network_mode.id, 'networks': self.networks, + 'secrets': self.secrets, 'volumes_from': [ (v.source.name, v.mode) for v in self.volumes_from if isinstance(v.source, Service) diff --git a/tests/integration/project_test.py b/tests/integration/project_test.py index 57f3b7074..fe6ace90e 100644 --- a/tests/integration/project_test.py +++ b/tests/integration/project_test.py @@ -1,6 +1,7 @@ from __future__ import absolute_import from __future__ import unicode_literals +import copy import json import os import random @@ -1496,6 +1497,60 @@ class ProjectTest(DockerClientTestCase): output = container.logs() assert output == b"This is the secret\n" + @v3_only() + def test_project_up_with_added_secrets(self): + node = create_host_file(self.client, os.path.abspath('tests/fixtures/secrets/default')) + + config_input1 = { + 'version': V3_1, + 'services': [ + { + 'name': 'web', + 'image': 'busybox:latest', + 'command': 'cat /run/secrets/special', + 'environment': ['constraint:node=={}'.format(node if node is not None else '')] + } + + ], + 'secrets': { + 'super': { + 'file': os.path.abspath('tests/fixtures/secrets/default') + } + } + } + config_input2 = copy.deepcopy(config_input1) + # Add the secret + config_input2['services'][0]['secrets'] = [ + types.ServiceSecret.parse({'source': 'super', 'target': 'special'}) + ] + + config_data1 = build_config(**config_input1) + config_data2 = build_config(**config_input2) + + # First up with non-secret + project = Project.from_config( + client=self.client, + name='composetest', + config_data=config_data1, + ) + project.up() + + # Then up with secret + project = Project.from_config( + client=self.client, + name='composetest', + config_data=config_data2, + ) + project.up() + project.stop() + + containers = project.containers(stopped=True) + assert len(containers) == 1 + container, = containers + + output = container.logs() + assert output == b"This is the secret\n" + @v2_only() def test_initialize_volumes_invalid_volume_driver(self): vol_name = '{0:x}'.format(random.getrandbits(32)) diff --git a/tests/unit/service_test.py b/tests/unit/service_test.py index 8b3352fcb..3d7c4987a 100644 --- a/tests/unit/service_test.py +++ b/tests/unit/service_test.py @@ -333,7 +333,7 @@ class ServiceTest(unittest.TestCase): assert service.options['environment'] == environment assert opts['labels'][LABEL_CONFIG_HASH] == \ - '2524a06fcb3d781aa2c981fc40bcfa08013bb318e4273bfa388df22023e6f2aa' + '689149e6041a85f6fb4945a2146a497ed43c8a5cbd8991753d875b165f1b4de4' assert opts['environment'] == ['also=real'] def test_get_container_create_options_sets_affinity_with_binds(self): @@ -676,6 +676,7 @@ class ServiceTest(unittest.TestCase): 'options': {'image': 'example.com/foo'}, 'links': [('one', 'one')], 'net': 'other', + 'secrets': [], 'networks': {'default': None}, 'volumes_from': [('two', 'rw')], } @@ -698,6 +699,7 @@ class ServiceTest(unittest.TestCase): 'options': {'image': 'example.com/foo'}, 'links': [], 'networks': {}, + 'secrets': [], 'net': 'aaabbb', 'volumes_from': [], }