Explorar o código

Validate extended service against our schema

Signed-off-by: Mazz Mosley <[email protected]>
Mazz Mosley %!s(int64=10) %!d(string=hai) anos
pai
achega
36757cde1c

+ 4 - 3
compose/config/config.py

@@ -182,6 +182,8 @@ class ServiceLoader(object):
             self.extended_config_path = self.get_extended_config_path(
                 self.service_dict['extends']
             )
+            extended_config = load_yaml(self.extended_config_path)
+            validate_against_schema(extended_config)
 
     def detect_cycle(self, name):
         if self.signature(name) in self.already_seen:
@@ -217,10 +219,9 @@ class ServiceLoader(object):
 
         extends_options = self.service_dict['extends']
         service_name = self.service_dict['name']
+        other_config_path = self.extended_config_path
 
-        other_config_path = self.get_extended_config_path(extends_options)
-
-        other_working_dir = os.path.dirname(other_config_path)
+        other_working_dir = os.path.dirname(self.extended_config_path)
         other_already_seen = self.already_seen + [self.signature(service_name)]
 
         base_service = extends_options['service']

+ 9 - 0
tests/fixtures/extends/invalid-links.yml

@@ -0,0 +1,9 @@
+myweb:
+  build: '.'
+  extends:
+    service: web
+  command: top
+web:
+  build: '.'
+  links:
+    - "mydb:db"

+ 8 - 0
tests/fixtures/extends/invalid-net.yml

@@ -0,0 +1,8 @@
+myweb:
+  build: '.'
+  extends:
+    service: web
+  command: top
+web:
+  build: '.'
+  net: "container:db"

+ 9 - 0
tests/fixtures/extends/invalid-volumes.yml

@@ -0,0 +1,9 @@
+myweb:
+  build: '.'
+  extends:
+    service: web
+  command: top
+web:
+  build: '.'
+  volumes_from:
+    - "db"

+ 5 - 0
tests/fixtures/extends/service-with-invalid-schema.yml

@@ -0,0 +1,5 @@
+myweb:
+  extends:
+    service: web
+web:
+  command: top

+ 18 - 27
tests/unit/config_test.py

@@ -867,6 +867,12 @@ class ExtendsTest(unittest.TestCase):
         self.assertEquals(len(service), 1)
         self.assertIsInstance(service[0], dict)
 
+    def test_extended_service_with_invalid_config(self):
+        expected_error_msg = "Service 'myweb' has neither an image nor a build path specified"
+
+        with self.assertRaisesRegexp(ConfigurationError, expected_error_msg):
+            load_from_filename('tests/fixtures/extends/service-with-invalid-schema.yml')
+
     def test_extends_file_defaults_to_self(self):
         """
         Test not specifying a file in our extends options that the
@@ -891,37 +897,22 @@ class ExtendsTest(unittest.TestCase):
             }
         ]))
 
-    def test_blacklisted_options(self):
-        def load_config():
-            return make_service_dict('myweb', {
-                'extends': {
-                    'file': 'whatever',
-                    'service': 'web',
-                }
-            }, '.')
-
-        with self.assertRaisesRegexp(ConfigurationError, 'links'):
-            other_config = {'web': {'links': ['db']}}
-
-            with mock.patch.object(config, 'load_yaml', return_value=other_config):
-                print(load_config())
-
-        with self.assertRaisesRegexp(ConfigurationError, 'volumes_from'):
-            other_config = {'web': {'volumes_from': ['db']}}
-
-            with mock.patch.object(config, 'load_yaml', return_value=other_config):
-                print(load_config())
+    def test_invalid_links_in_extended_service(self):
+        expected_error_msg = "services with 'links' cannot be extended"
+        with self.assertRaisesRegexp(ConfigurationError, expected_error_msg):
+            load_from_filename('tests/fixtures/extends/invalid-links.yml')
 
-        with self.assertRaisesRegexp(ConfigurationError, 'net'):
-            other_config = {'web': {'net': 'container:db'}}
+    def test_invalid_volumes_from_in_extended_service(self):
+        expected_error_msg = "services with 'volumes_from' cannot be extended"
 
-            with mock.patch.object(config, 'load_yaml', return_value=other_config):
-                print(load_config())
+        with self.assertRaisesRegexp(ConfigurationError, expected_error_msg):
+            load_from_filename('tests/fixtures/extends/invalid-volumes.yml')
 
-        other_config = {'web': {'net': 'host'}}
+    def test_invalid_net_in_extended_service(self):
+        expected_error_msg = "services with 'net: container' cannot be extended"
 
-        with mock.patch.object(config, 'load_yaml', return_value=other_config):
-            print(load_config())
+        with self.assertRaisesRegexp(ConfigurationError, expected_error_msg):
+            load_from_filename('tests/fixtures/extends/invalid-net.yml')
 
     def test_volume_path(self):
         dicts = load_from_filename('tests/fixtures/volume-path/docker-compose.yml')