From 4bdd256000bd286eaa3dbf59f2e18349a2aad054 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Mon, 15 May 2017 23:19:35 +0200 Subject: [PATCH] Use label instead env, cleanup build (#50) * Use label instead env, cleanup build * Update const.py * fix lint * add space * fix lint * use dynamic type * fix lint * fix path * fix label read * fix bug --- hassio/const.py | 8 ++++++++ hassio/dock/__init__.py | 24 ++++++++++++++++++------ hassio/dock/addon.py | 14 ++++++-------- hassio/dock/homeassistant.py | 4 +--- hassio/dock/util.py | 14 +++++++++++--- 5 files changed, 44 insertions(+), 20 deletions(-) diff --git a/hassio/const.py b/hassio/const.py index 0b004b6bf..d81e5360e 100644 --- a/hassio/const.py +++ b/hassio/const.py @@ -26,6 +26,14 @@ FILE_HASSIO_CONFIG = Path(HASSIO_SHARE, "config.json") SOCKET_DOCKER = Path("/var/run/docker.sock") SOCKET_HC = Path("/var/run/hassio-hc.sock") +LABEL_VERSION = 'io.hass.version' +LABEL_ARCH = 'io.hass.arch' +LABEL_TYPE = 'io.hass.type' + +META_ADDON = 'addon' +META_SUPERVISOR = 'supervisor' +META_HOMEASSISTANT = 'homeassistant' + JSON_RESULT = 'result' JSON_DATA = 'data' JSON_MESSAGE = 'message' diff --git a/hassio/dock/__init__.py b/hassio/dock/__init__.py index ac585ea75..e0b14d22b 100644 --- a/hassio/dock/__init__.py +++ b/hassio/dock/__init__.py @@ -5,6 +5,7 @@ import logging import docker +from ..const import LABEL_VERSION from ..tools import get_version_from_env _LOGGER = logging.getLogger(__name__) @@ -33,6 +34,19 @@ class DockerBase(object): """Return True if a task is in progress.""" return self._lock.locked() + def process_metadata(self, metadata=None, force=False): + """Read metadata and set it to object.""" + if not force and self.version: + return + + # read metadata + metadata = metadata or self.container.attrs + if LABEL_VERSION in metadata['Config']['Labels']: + self.version = metadata['Config']['Labels'][LABEL_VERSION] + else: + # dedicated + self.version = get_version_from_env(metadata['Config']['Env']) + async def install(self, tag): """Pull docker image.""" if self._lock.locked(): @@ -51,8 +65,8 @@ class DockerBase(object): _LOGGER.info("Pull image %s tag %s.", self.image, tag) image = self.dock.images.pull("{}:{}".format(self.image, tag)) - self.version = tag image.tag(self.image, tag='latest') + self.process_metadata(metadata=image.attrs, force=True) except docker.errors.APIError as err: _LOGGER.error("Can't install %s:%s -> %s.", self.image, tag, err) return False @@ -74,7 +88,7 @@ class DockerBase(object): """ try: image = self.dock.images.get(self.image) - self.version = get_version_from_env(image.attrs['Config']['Env']) + self.process_metadata(metadata=image.attrs) except docker.errors.DockerException: return False @@ -95,8 +109,7 @@ class DockerBase(object): if not self.container: try: self.container = self.dock.containers.get(self.docker_name) - self.version = get_version_from_env( - self.container.attrs['Config']['Env']) + self.process_metadata() except docker.errors.DockerException: return False else: @@ -121,8 +134,7 @@ class DockerBase(object): try: self.container = self.dock.containers.get(self.docker_name) self.image = self.container.attrs['Config']['Image'] - self.version = get_version_from_env( - self.container.attrs['Config']['Env']) + self.process_metadata() _LOGGER.info("Attach to image %s with version %s", self.image, self.version) except (docker.errors.DockerException, KeyError): diff --git a/hassio/dock/addon.py b/hassio/dock/addon.py index 8a32569ab..d98fdbab9 100644 --- a/hassio/dock/addon.py +++ b/hassio/dock/addon.py @@ -7,7 +7,7 @@ import docker from . import DockerBase from .util import dockerfile_template -from ..tools import get_version_from_env +from ..const import META_ADDON _LOGGER = logging.getLogger(__name__) @@ -82,9 +82,7 @@ class DockerAddon(DockerBase): volumes=self.volumes, ) - self.version = get_version_from_env( - self.container.attrs['Config']['Env']) - + self.process_metadata() _LOGGER.info("Start docker addon %s with version %s", self.image, self.version) @@ -101,8 +99,7 @@ class DockerAddon(DockerBase): """ try: self.container = self.dock.containers.get(self.docker_name) - self.version = get_version_from_env( - self.container.attrs['Config']['Env']) + self.process_metadata() _LOGGER.info( "Attach to image %s with version %s", self.image, self.version) @@ -147,7 +144,8 @@ class DockerAddon(DockerBase): # prepare Dockerfile try: dockerfile_template( - Path(build_dir, 'Dockerfile'), self.addons_data.arch, tag) + Path(build_dir, 'Dockerfile'), self.addons_data.arch, + tag, META_ADDON) except OSError as err: _LOGGER.error("Can't prepare dockerfile -> %s", err) @@ -159,8 +157,8 @@ class DockerAddon(DockerBase): image = self.dock.images.build( path=str(build_dir), tag=build_tag, pull=True) - self.version = tag image.tag(self.image, tag='latest') + self.process_metadata(metadata=image.attrs, force=True) except (docker.errors.DockerException, TypeError) as err: _LOGGER.error("Can't build %s -> %s", build_tag, err) diff --git a/hassio/dock/homeassistant.py b/hassio/dock/homeassistant.py index f33ea5124..b981af0fb 100644 --- a/hassio/dock/homeassistant.py +++ b/hassio/dock/homeassistant.py @@ -4,7 +4,6 @@ import logging import docker from . import DockerBase -from ..tools import get_version_from_env _LOGGER = logging.getLogger(__name__) @@ -51,8 +50,7 @@ class DockerHomeAssistant(DockerBase): {'bind': '/ssl', 'mode': 'rw'}, }) - self.version = get_version_from_env( - self.container.attrs['Config']['Env']) + self.process_metadata() _LOGGER.info("Start docker addon %s with version %s", self.image, self.version) diff --git a/hassio/dock/util.py b/hassio/dock/util.py index b851e9b6f..9aafab437 100644 --- a/hassio/dock/util.py +++ b/hassio/dock/util.py @@ -11,11 +11,10 @@ RESIN_BASE_IMAGE = { ARCH_AMD64: "resin/amd64-alpine:3.5", } -TMPL_VERSION = re.compile(r"%%VERSION%%") TMPL_IMAGE = re.compile(r"%%BASE_IMAGE%%") -def dockerfile_template(dockerfile, arch, version): +def dockerfile_template(dockerfile, arch, version, meta_type): """Prepare a Hass.IO dockerfile.""" buff = [] resin_image = RESIN_BASE_IMAGE[arch] @@ -23,10 +22,19 @@ def dockerfile_template(dockerfile, arch, version): # read docker with dockerfile.open('r') as dock_input: for line in dock_input: - line = TMPL_VERSION.sub(version, line) line = TMPL_IMAGE.sub(resin_image, line) buff.append(line) + # add metadata + buff.append(create_metadata(version, arch, meta_type)) + # write docker with dockerfile.open('w') as dock_output: dock_output.writelines(buff) + + +def create_metadata(version, arch, meta_type): + """Generate docker label layer for hassio.""" + return ('LABEL io.hass.version="{}" ' + 'io.hass.arch="{}" ' + 'io.hass.type="{}"').format(version, arch, meta_type)