Pārlūkot izejas kodu

Merge pull request #6964 from guillaumerose/addmorelabels

Add working dir, config files and env file in service labels
Guillaume LOURS 6 gadi atpakaļ
vecāks
revīzija
944660048d
5 mainītis faili ar 66 papildinājumiem un 35 dzēšanām
  1. 3 3
      Jenkinsfile
  2. 27 3
      compose/cli/command.py
  3. 3 0
      compose/const.py
  4. 2 1
      compose/project.py
  5. 31 28
      compose/service.py

+ 3 - 3
Jenkinsfile

@@ -2,7 +2,7 @@
 
 def buildImage = { String baseImage ->
   def image
-  wrappedNode(label: "ubuntu && !zfs", cleanWorkspace: true) {
+  wrappedNode(label: "ubuntu && amd64 && !zfs", cleanWorkspace: true) {
     stage("build image for \"${baseImage}\"") {
       checkout(scm)
       def imageName = "dockerbuildbot/compose:${baseImage}-${gitCommit()}"
@@ -29,7 +29,7 @@ def buildImage = { String baseImage ->
 
 def get_versions = { String imageId, int number ->
   def docker_versions
-  wrappedNode(label: "ubuntu && !zfs") {
+  wrappedNode(label: "ubuntu && amd64 && !zfs") {
     def result = sh(script: """docker run --rm \\
         --entrypoint=/code/.tox/py27/bin/python \\
         ${imageId} \\
@@ -55,7 +55,7 @@ def runTests = { Map settings ->
   }
 
   { ->
-    wrappedNode(label: "ubuntu && !zfs", cleanWorkspace: true) {
+    wrappedNode(label: "ubuntu && amd64 && !zfs", cleanWorkspace: true) {
       stage("test python=${pythonVersions} / docker=${dockerVersions} / baseImage=${baseImage}") {
         checkout(scm)
         def storageDriver = sh(script: 'docker info | awk -F \': \' \'$1 == "Storage Driver" { print $2; exit }\'', returnStdout: true).trim()

+ 27 - 3
compose/cli/command.py

@@ -13,6 +13,9 @@ from .. import config
 from .. import parallel
 from ..config.environment import Environment
 from ..const import API_VERSIONS
+from ..const import LABEL_CONFIG_FILES
+from ..const import LABEL_ENVIRONMENT_FILE
+from ..const import LABEL_WORKING_DIR
 from ..project import Project
 from .docker_client import docker_client
 from .docker_client import get_tls_version
@@ -57,7 +60,8 @@ def project_from_options(project_dir, options, additional_options={}):
         environment=environment,
         override_dir=override_dir,
         compatibility=options.get('--compatibility'),
-        interpolate=(not additional_options.get('--no-interpolate'))
+        interpolate=(not additional_options.get('--no-interpolate')),
+        environment_file=environment_file
     )
 
 
@@ -125,7 +129,7 @@ def get_client(environment, verbose=False, version=None, tls_config=None, host=N
 
 def get_project(project_dir, config_path=None, project_name=None, verbose=False,
                 host=None, tls_config=None, environment=None, override_dir=None,
-                compatibility=False, interpolate=True):
+                compatibility=False, interpolate=True, environment_file=None):
     if not environment:
         environment = Environment.from_env_file(project_dir)
     config_details = config.find(project_dir, config_path, environment, override_dir)
@@ -145,10 +149,30 @@ def get_project(project_dir, config_path=None, project_name=None, verbose=False,
 
     with errors.handle_connection_errors(client):
         return Project.from_config(
-            project_name, config_data, client, environment.get('DOCKER_DEFAULT_PLATFORM')
+            project_name,
+            config_data,
+            client,
+            environment.get('DOCKER_DEFAULT_PLATFORM'),
+            execution_context_labels(config_details, environment_file),
         )
 
 
+def execution_context_labels(config_details, environment_file):
+    extra_labels = [
+        '{0}={1}'.format(LABEL_WORKING_DIR, os.path.abspath(config_details.working_dir)),
+        '{0}={1}'.format(LABEL_CONFIG_FILES, config_files_label(config_details)),
+    ]
+    if environment_file is not None:
+        extra_labels.append('{0}={1}'.format(LABEL_ENVIRONMENT_FILE,
+                                             os.path.normpath(environment_file)))
+    return extra_labels
+
+
+def config_files_label(config_details):
+    return ",".join(
+        map(str, (os.path.normpath(c.filename) for c in config_details.config_files)))
+
+
 def get_project_name(working_dir, project_name=None, environment=None):
     def normalize_name(name):
         return re.sub(r'[^-_a-z0-9]', '', name.lower())

+ 3 - 0
compose/const.py

@@ -11,6 +11,9 @@ IS_WINDOWS_PLATFORM = (sys.platform == "win32")
 LABEL_CONTAINER_NUMBER = 'com.docker.compose.container-number'
 LABEL_ONE_OFF = 'com.docker.compose.oneoff'
 LABEL_PROJECT = 'com.docker.compose.project'
+LABEL_WORKING_DIR = 'com.docker.compose.project.working_dir'
+LABEL_CONFIG_FILES = 'com.docker.compose.project.config_files'
+LABEL_ENVIRONMENT_FILE = 'com.docker.compose.project.environment_file'
 LABEL_SERVICE = 'com.docker.compose.service'
 LABEL_NETWORK = 'com.docker.compose.network'
 LABEL_VERSION = 'com.docker.compose.version'

+ 2 - 1
compose/project.py

@@ -83,7 +83,7 @@ class Project(object):
         return labels
 
     @classmethod
-    def from_config(cls, name, config_data, client, default_platform=None):
+    def from_config(cls, name, config_data, client, default_platform=None, extra_labels=[]):
         """
         Construct a Project from a config.Config object.
         """
@@ -136,6 +136,7 @@ class Project(object):
                     pid_mode=pid_mode,
                     platform=service_dict.pop('platform', None),
                     default_platform=default_platform,
+                    extra_labels=extra_labels,
                     **service_dict)
             )
 

+ 31 - 28
compose/service.py

@@ -68,7 +68,6 @@ else:
 
 log = logging.getLogger(__name__)
 
-
 HOST_CONFIG_KEYS = [
     'cap_add',
     'cap_drop',
@@ -137,7 +136,6 @@ class NoSuchImageError(Exception):
 
 ServiceName = namedtuple('ServiceName', 'project service number')
 
-
 ConvergencePlan = namedtuple('ConvergencePlan', 'action containers')
 
 
@@ -173,20 +171,21 @@ class BuildAction(enum.Enum):
 
 class Service(object):
     def __init__(
-        self,
-        name,
-        client=None,
-        project='default',
-        use_networking=False,
-        links=None,
-        volumes_from=None,
-        network_mode=None,
-        networks=None,
-        secrets=None,
-        scale=1,
-        pid_mode=None,
-        default_platform=None,
-        **options
+            self,
+            name,
+            client=None,
+            project='default',
+            use_networking=False,
+            links=None,
+            volumes_from=None,
+            network_mode=None,
+            networks=None,
+            secrets=None,
+            scale=1,
+            pid_mode=None,
+            default_platform=None,
+            extra_labels=[],
+            **options
     ):
         self.name = name
         self.client = client
@@ -201,6 +200,7 @@ class Service(object):
         self.scale_num = scale
         self.default_platform = default_platform
         self.options = options
+        self.extra_labels = extra_labels
 
     def __repr__(self):
         return '<Service: {}>'.format(self.name)
@@ -215,7 +215,7 @@ class Service(object):
             for container in self.client.containers(
                 all=stopped,
                 filters=filters)])
-        )
+                      )
         if result:
             return result
 
@@ -404,8 +404,8 @@ class Service(object):
             return ConvergencePlan('start', containers)
 
         if (
-            strategy is ConvergenceStrategy.always or
-            self._containers_have_diverged(containers)
+                strategy is ConvergenceStrategy.always or
+                self._containers_have_diverged(containers)
         ):
             return ConvergencePlan('recreate', containers)
 
@@ -482,6 +482,7 @@ class Service(object):
                 container, timeout=timeout, attach_logs=not detached,
                 start_new_container=start, renew_anonymous_volumes=renew_anonymous_volumes
             )
+
         containers, errors = parallel_execute(
             containers,
             recreate,
@@ -705,11 +706,11 @@ class Service(object):
         net_name = self.network_mode.service_name
         pid_namespace = self.pid_mode.service_name
         return (
-            self.get_linked_service_names() +
-            self.get_volumes_from_names() +
-            ([net_name] if net_name else []) +
-            ([pid_namespace] if pid_namespace else []) +
-            list(self.options.get('depends_on', {}).keys())
+                self.get_linked_service_names() +
+                self.get_volumes_from_names() +
+                ([net_name] if net_name else []) +
+                ([pid_namespace] if pid_namespace else []) +
+                list(self.options.get('depends_on', {}).keys())
         )
 
     def get_dependency_configs(self):
@@ -899,7 +900,7 @@ class Service(object):
 
         container_options['labels'] = build_container_labels(
             container_options.get('labels', {}),
-            self.labels(one_off=one_off),
+            self.labels(one_off=one_off) + self.extra_labels,
             number,
             self.config_hash if add_config_hash else None,
             slug
@@ -1552,9 +1553,9 @@ def warn_on_masked_volume(volumes_option, container_volumes, service):
 
     for volume in volumes_option:
         if (
-            volume.external and
-            volume.internal in container_volumes and
-            container_volumes.get(volume.internal) != volume.external
+                volume.external and
+                volume.internal in container_volumes and
+                container_volumes.get(volume.internal) != volume.external
         ):
             log.warning((
                 "Service \"{service}\" is using volume \"{volume}\" from the "
@@ -1601,6 +1602,7 @@ def build_mount(mount_spec):
         read_only=mount_spec.read_only, consistency=mount_spec.consistency, **kwargs
     )
 
+
 # Labels
 
 
@@ -1655,6 +1657,7 @@ def format_environment(environment):
         if isinstance(value, six.binary_type):
             value = value.decode('utf-8')
         return '{key}={value}'.format(key=key, value=value)
+
     return [format_env(*item) for item in environment.items()]