Store image on local config (#1627)

* Store image on local config

* Fix api validate

* Fix install handling
This commit is contained in:
Pascal Vizeli 2020-04-03 17:12:18 +02:00 committed by GitHub
parent 387e0ad03e
commit 9350e4f961
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 71 additions and 51 deletions

1
API.md
View File

@ -368,7 +368,6 @@ Trigger an udev reload
"machine": "Image machine type", "machine": "Image machine type",
"ip_address": "ip address", "ip_address": "ip address",
"image": "str", "image": "str",
"custom": "bool -> if custom image",
"boot": "bool", "boot": "bool",
"port": 8123, "port": 8123,
"ssl": "bool", "ssl": "bool",

View File

@ -14,10 +14,8 @@ from ..const import (
ATTR_BLK_WRITE, ATTR_BLK_WRITE,
ATTR_BOOT, ATTR_BOOT,
ATTR_CPU_PERCENT, ATTR_CPU_PERCENT,
ATTR_CUSTOM,
ATTR_IMAGE, ATTR_IMAGE,
ATTR_IP_ADDRESS, ATTR_IP_ADDRESS,
ATTR_VERSION_LATEST,
ATTR_MACHINE, ATTR_MACHINE,
ATTR_MEMORY_LIMIT, ATTR_MEMORY_LIMIT,
ATTR_MEMORY_PERCENT, ATTR_MEMORY_PERCENT,
@ -28,6 +26,7 @@ from ..const import (
ATTR_REFRESH_TOKEN, ATTR_REFRESH_TOKEN,
ATTR_SSL, ATTR_SSL,
ATTR_VERSION, ATTR_VERSION,
ATTR_VERSION_LATEST,
ATTR_WAIT_BOOT, ATTR_WAIT_BOOT,
ATTR_WATCHDOG, ATTR_WATCHDOG,
CONTENT_TYPE_BINARY, CONTENT_TYPE_BINARY,
@ -43,8 +42,7 @@ _LOGGER: logging.Logger = logging.getLogger(__name__)
SCHEMA_OPTIONS = vol.Schema( SCHEMA_OPTIONS = vol.Schema(
{ {
vol.Optional(ATTR_BOOT): vol.Boolean(), vol.Optional(ATTR_BOOT): vol.Boolean(),
vol.Inclusive(ATTR_IMAGE, "custom_hass"): vol.Maybe(docker_image), vol.Optional(ATTR_IMAGE): docker_image,
vol.Inclusive(ATTR_VERSION_LATEST, "custom_hass"): vol.Maybe(vol.Coerce(str)),
vol.Optional(ATTR_PORT): network_port, vol.Optional(ATTR_PORT): network_port,
vol.Optional(ATTR_SSL): vol.Boolean(), vol.Optional(ATTR_SSL): vol.Boolean(),
vol.Optional(ATTR_WATCHDOG): vol.Boolean(), vol.Optional(ATTR_WATCHDOG): vol.Boolean(),
@ -71,7 +69,6 @@ class APIHomeAssistant(CoreSysAttributes):
ATTR_IP_ADDRESS: str(self.sys_homeassistant.ip_address), ATTR_IP_ADDRESS: str(self.sys_homeassistant.ip_address),
ATTR_ARCH: self.sys_homeassistant.arch, ATTR_ARCH: self.sys_homeassistant.arch,
ATTR_IMAGE: self.sys_homeassistant.image, ATTR_IMAGE: self.sys_homeassistant.image,
ATTR_CUSTOM: self.sys_homeassistant.is_custom_image,
ATTR_BOOT: self.sys_homeassistant.boot, ATTR_BOOT: self.sys_homeassistant.boot,
ATTR_PORT: self.sys_homeassistant.api_port, ATTR_PORT: self.sys_homeassistant.api_port,
ATTR_SSL: self.sys_homeassistant.api_ssl, ATTR_SSL: self.sys_homeassistant.api_ssl,
@ -88,9 +85,8 @@ class APIHomeAssistant(CoreSysAttributes):
"""Set Home Assistant options.""" """Set Home Assistant options."""
body = await api_validate(SCHEMA_OPTIONS, request) body = await api_validate(SCHEMA_OPTIONS, request)
if ATTR_IMAGE in body and ATTR_VERSION_LATEST in body: if ATTR_IMAGE in body:
self.sys_homeassistant.image = body[ATTR_IMAGE] self.sys_homeassistant.image = body[ATTR_IMAGE]
self.sys_homeassistant.latest_version = body[ATTR_VERSION_LATEST]
if ATTR_BOOT in body: if ATTR_BOOT in body:
self.sys_homeassistant.boot = body[ATTR_BOOT] self.sys_homeassistant.boot = body[ATTR_BOOT]

View File

@ -8,7 +8,7 @@ from typing import Awaitable, Optional
import jinja2 import jinja2
from .const import ATTR_VERSION, FILE_HASSIO_AUDIO from .const import ATTR_IMAGE, ATTR_VERSION, FILE_HASSIO_AUDIO
from .coresys import CoreSys, CoreSysAttributes from .coresys import CoreSys, CoreSysAttributes
from .docker.audio import DockerAudio from .docker.audio import DockerAudio
from .docker.stats import DockerStats from .docker.stats import DockerStats
@ -52,6 +52,18 @@ class Audio(JsonConfig, CoreSysAttributes):
"""Set current version of Audio.""" """Set current version of Audio."""
self._data[ATTR_VERSION] = value self._data[ATTR_VERSION] = value
@property
def image(self) -> str:
"""Return current image of Audio."""
if self._data.get(ATTR_IMAGE):
return self._data[ATTR_IMAGE]
return f"homeassistant/{self.sys_arch.supervisor}-hassio-audio"
@image.setter
def image(self, value: str) -> None:
"""Return current image of Audio."""
self._data[ATTR_IMAGE] = value
@property @property
def latest_version(self) -> Optional[str]: def latest_version(self) -> Optional[str]:
"""Return latest version of Audio.""" """Return latest version of Audio."""
@ -84,6 +96,7 @@ class Audio(JsonConfig, CoreSysAttributes):
await self.install() await self.install()
else: else:
self.version = self.instance.version self.version = self.instance.version
self.image = self.instance.image
self.save_data() self.save_data()
# Run PulseAudio # Run PulseAudio
@ -122,6 +135,7 @@ class Audio(JsonConfig, CoreSysAttributes):
_LOGGER.info("Audio plugin now installed") _LOGGER.info("Audio plugin now installed")
self.version = self.instance.version self.version = self.instance.version
self.image = self.instance.image
self.save_data() self.save_data()
async def update(self, version: Optional[str] = None) -> None: async def update(self, version: Optional[str] = None) -> None:

View File

@ -5,7 +5,7 @@ import logging
import secrets import secrets
from typing import Awaitable, Optional from typing import Awaitable, Optional
from .const import ATTR_ACCESS_TOKEN, ATTR_VERSION, FILE_HASSIO_CLI from .const import ATTR_ACCESS_TOKEN, ATTR_IMAGE, ATTR_VERSION, FILE_HASSIO_CLI
from .coresys import CoreSys, CoreSysAttributes from .coresys import CoreSys, CoreSysAttributes
from .docker.cli import DockerCli from .docker.cli import DockerCli
from .docker.stats import DockerStats from .docker.stats import DockerStats
@ -35,6 +35,18 @@ class HaCli(CoreSysAttributes, JsonConfig):
"""Set current version of cli.""" """Set current version of cli."""
self._data[ATTR_VERSION] = value self._data[ATTR_VERSION] = value
@property
def image(self) -> str:
"""Return current image of cli."""
if self._data.get(ATTR_IMAGE):
return self._data[ATTR_IMAGE]
return f"homeassistant/{self.sys_arch.supervisor}-hassio-cli"
@image.setter
def image(self, value: str) -> None:
"""Return current image of cli."""
self._data[ATTR_IMAGE] = value
@property @property
def latest_version(self) -> str: def latest_version(self) -> str:
"""Return version of latest cli.""" """Return version of latest cli."""
@ -72,6 +84,7 @@ class HaCli(CoreSysAttributes, JsonConfig):
await self.install() await self.install()
else: else:
self.version = self.instance.version self.version = self.instance.version
self.image = self.instance.image
self.save_data() self.save_data()
# Run PulseAudio # Run PulseAudio
@ -96,6 +109,7 @@ class HaCli(CoreSysAttributes, JsonConfig):
_LOGGER.info("cli plugin now installed") _LOGGER.info("cli plugin now installed")
self.version = self.instance.version self.version = self.instance.version
self.image = self.instance.image
self.save_data() self.save_data()
async def update(self, version: Optional[str] = None) -> None: async def update(self, version: Optional[str] = None) -> None:

View File

@ -17,7 +17,7 @@ from .const import (
) )
from .utils.dt import parse_datetime from .utils.dt import parse_datetime
from .utils.json import JsonConfig from .utils.json import JsonConfig
from .validate import SCHEMA_HASSIO_CONFIG from .validate import SCHEMA_SUPERVISOR_CONFIG
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
@ -45,7 +45,7 @@ class CoreConfig(JsonConfig):
def __init__(self): def __init__(self):
"""Initialize config object.""" """Initialize config object."""
super().__init__(FILE_HASSIO_CONFIG, SCHEMA_HASSIO_CONFIG) super().__init__(FILE_HASSIO_CONFIG, SCHEMA_SUPERVISOR_CONFIG)
@property @property
def timezone(self): def timezone(self):

View File

@ -147,7 +147,6 @@ ATTR_SIZE = "size"
ATTR_TYPE = "type" ATTR_TYPE = "type"
ATTR_TIMEOUT = "timeout" ATTR_TIMEOUT = "timeout"
ATTR_AUTO_UPDATE = "auto_update" ATTR_AUTO_UPDATE = "auto_update"
ATTR_CUSTOM = "custom"
ATTR_VIDEO = "video" ATTR_VIDEO = "video"
ATTR_AUDIO = "audio" ATTR_AUDIO = "audio"
ATTR_AUDIO_INPUT = "audio_input" ATTR_AUDIO_INPUT = "audio_input"

View File

@ -10,14 +10,14 @@ import attr
import jinja2 import jinja2
import voluptuous as vol import voluptuous as vol
from .const import ATTR_SERVERS, ATTR_VERSION, DNS_SUFFIX, FILE_HASSIO_DNS from .const import ATTR_IMAGE, ATTR_SERVERS, ATTR_VERSION, DNS_SUFFIX, FILE_HASSIO_DNS
from .coresys import CoreSys, CoreSysAttributes from .coresys import CoreSys, CoreSysAttributes
from .docker.dns import DockerDNS from .docker.dns import DockerDNS
from .docker.stats import DockerStats from .docker.stats import DockerStats
from .exceptions import CoreDNSError, CoreDNSUpdateError, DockerAPIError from .exceptions import CoreDNSError, CoreDNSUpdateError, DockerAPIError
from .misc.forwarder import DNSForward from .misc.forwarder import DNSForward
from .utils.json import JsonConfig from .utils.json import JsonConfig
from .validate import dns_url, SCHEMA_DNS_CONFIG from .validate import SCHEMA_DNS_CONFIG, dns_url
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
@ -79,6 +79,18 @@ class CoreDNS(JsonConfig, CoreSysAttributes):
"""Return current version of DNS.""" """Return current version of DNS."""
self._data[ATTR_VERSION] = value self._data[ATTR_VERSION] = value
@property
def image(self) -> str:
"""Return current image of DNS."""
if self._data.get(ATTR_IMAGE):
return self._data[ATTR_IMAGE]
return f"homeassistant/{self.sys_arch.supervisor}-hassio-dns"
@image.setter
def image(self, value: str) -> None:
"""Return current image of DNS."""
self._data[ATTR_IMAGE] = value
@property @property
def latest_version(self) -> Optional[str]: def latest_version(self) -> Optional[str]:
"""Return latest version of CoreDNS.""" """Return latest version of CoreDNS."""
@ -115,6 +127,7 @@ class CoreDNS(JsonConfig, CoreSysAttributes):
await self.install() await self.install()
else: else:
self.version = self.instance.version self.version = self.instance.version
self.image = self.instance.image
self.save_data() self.save_data()
# Start DNS forwarder # Start DNS forwarder
@ -161,6 +174,7 @@ class CoreDNS(JsonConfig, CoreSysAttributes):
_LOGGER.info("CoreDNS plugin now installed") _LOGGER.info("CoreDNS plugin now installed")
self.version = self.instance.version self.version = self.instance.version
self.image = self.instance.image
self.save_data() self.save_data()
# Init Hosts # Init Hosts

View File

@ -20,7 +20,7 @@ class DockerAudio(DockerInterface, CoreSysAttributes):
@property @property
def image(self) -> str: def image(self) -> str:
"""Return name of Supervisor Audio image.""" """Return name of Supervisor Audio image."""
return f"homeassistant/{self.sys_arch.supervisor}-hassio-audio" return self.sys_audio.image
@property @property
def name(self) -> str: def name(self) -> str:

View File

@ -18,7 +18,7 @@ class DockerCli(DockerInterface, CoreSysAttributes):
@property @property
def image(self): def image(self):
"""Return name of HA cli image.""" """Return name of HA cli image."""
return f"homeassistant/{self.sys_arch.supervisor}-hassio-cli" return self.sys_cli.image
@property @property
def name(self) -> str: def name(self) -> str:

View File

@ -18,7 +18,7 @@ class DockerDNS(DockerInterface, CoreSysAttributes):
@property @property
def image(self) -> str: def image(self) -> str:
"""Return name of Supervisor DNS image.""" """Return name of Supervisor DNS image."""
return f"homeassistant/{self.sys_arch.supervisor}-hassio-dns" return self.sys_dns.image
@property @property
def name(self) -> str: def name(self) -> str:

View File

@ -91,6 +91,7 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
await self.install_landingpage() await self.install_landingpage()
else: else:
self.version = self.instance.version self.version = self.instance.version
self.image = self.instance.image
self.save_data() self.save_data()
@property @property
@ -163,8 +164,6 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
@property @property
def latest_version(self) -> str: def latest_version(self) -> str:
"""Return last available version of Home Assistant.""" """Return last available version of Home Assistant."""
if self.is_custom_image:
return self._data.get(ATTR_VERSION_LATEST)
return self.sys_updater.version_homeassistant return self.sys_updater.version_homeassistant
@latest_version.setter @latest_version.setter
@ -183,17 +182,9 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
return os.environ["HOMEASSISTANT_REPOSITORY"] return os.environ["HOMEASSISTANT_REPOSITORY"]
@image.setter @image.setter
def image(self, value: str): def image(self, value: str) -> None:
"""Set image name of Home Assistant container.""" """Set image name of Home Assistant container."""
if value: self._data[ATTR_IMAGE] = value
self._data[ATTR_IMAGE] = value
else:
self._data.pop(ATTR_IMAGE, None)
@property
def is_custom_image(self) -> bool:
"""Return True if a custom image is used."""
return all(attr in self._data for attr in (ATTR_IMAGE, ATTR_VERSION_LATEST))
@property @property
def version(self) -> Optional[str]: def version(self) -> Optional[str]:
@ -304,6 +295,7 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
_LOGGER.info("Home Assistant docker now installed") _LOGGER.info("Home Assistant docker now installed")
self.version = self.instance.version self.version = self.instance.version
self.image = self.instance.image
self.save_data() self.save_data()
# finishing # finishing

View File

@ -24,7 +24,6 @@ from ..const import (
ATTR_FOLDERS, ATTR_FOLDERS,
ATTR_HOMEASSISTANT, ATTR_HOMEASSISTANT,
ATTR_IMAGE, ATTR_IMAGE,
ATTR_VERSION_LATEST,
ATTR_NAME, ATTR_NAME,
ATTR_PORT, ATTR_PORT,
ATTR_PROTECTED, ATTR_PROTECTED,
@ -430,13 +429,7 @@ class Snapshot(CoreSysAttributes):
self.homeassistant[ATTR_WATCHDOG] = self.sys_homeassistant.watchdog self.homeassistant[ATTR_WATCHDOG] = self.sys_homeassistant.watchdog
self.homeassistant[ATTR_BOOT] = self.sys_homeassistant.boot self.homeassistant[ATTR_BOOT] = self.sys_homeassistant.boot
self.homeassistant[ATTR_WAIT_BOOT] = self.sys_homeassistant.wait_boot self.homeassistant[ATTR_WAIT_BOOT] = self.sys_homeassistant.wait_boot
self.homeassistant[ATTR_IMAGE] = self.sys_homeassistant.image
# Custom image
if self.sys_homeassistant.is_custom_image:
self.homeassistant[ATTR_IMAGE] = self.sys_homeassistant.image
self.homeassistant[
ATTR_VERSION_LATEST
] = self.sys_homeassistant.latest_version
# API/Proxy # API/Proxy
self.homeassistant[ATTR_PORT] = self.sys_homeassistant.api_port self.homeassistant[ATTR_PORT] = self.sys_homeassistant.api_port
@ -455,12 +448,9 @@ class Snapshot(CoreSysAttributes):
self.sys_homeassistant.boot = self.homeassistant[ATTR_BOOT] self.sys_homeassistant.boot = self.homeassistant[ATTR_BOOT]
self.sys_homeassistant.wait_boot = self.homeassistant[ATTR_WAIT_BOOT] self.sys_homeassistant.wait_boot = self.homeassistant[ATTR_WAIT_BOOT]
# Custom image # Was not needed before
if self.homeassistant.get(ATTR_IMAGE): if self.homeassistant[ATTR_IMAGE]:
self.sys_homeassistant.image = self.homeassistant[ATTR_IMAGE] self.sys_homeassistant.image = self.homeassistant[ATTR_IMAGE]
self.sys_homeassistant.latest_version = self.homeassistant[
ATTR_VERSION_LATEST
]
# API/Proxy # API/Proxy
self.sys_homeassistant.api_port = self.homeassistant[ATTR_PORT] self.sys_homeassistant.api_port = self.homeassistant[ATTR_PORT]

View File

@ -11,7 +11,6 @@ from ..const import (
ATTR_FOLDERS, ATTR_FOLDERS,
ATTR_HOMEASSISTANT, ATTR_HOMEASSISTANT,
ATTR_IMAGE, ATTR_IMAGE,
ATTR_VERSION_LATEST,
ATTR_NAME, ATTR_NAME,
ATTR_PORT, ATTR_PORT,
ATTR_PROTECTED, ATTR_PROTECTED,
@ -60,8 +59,7 @@ SCHEMA_SNAPSHOT = vol.Schema(
vol.Optional(ATTR_HOMEASSISTANT, default=dict): vol.Schema( vol.Optional(ATTR_HOMEASSISTANT, default=dict): vol.Schema(
{ {
vol.Optional(ATTR_VERSION): vol.Coerce(str), vol.Optional(ATTR_VERSION): vol.Coerce(str),
vol.Inclusive(ATTR_IMAGE, "custom_hass"): docker_image, vol.Optional(ATTR_IMAGE): docker_image,
vol.Inclusive(ATTR_VERSION_LATEST, "custom_hass"): vol.Coerce(str),
vol.Optional(ATTR_BOOT, default=True): vol.Boolean(), vol.Optional(ATTR_BOOT, default=True): vol.Boolean(),
vol.Optional(ATTR_SSL, default=False): vol.Boolean(), vol.Optional(ATTR_SSL, default=False): vol.Boolean(),
vol.Optional(ATTR_PORT, default=8123): network_port, vol.Optional(ATTR_PORT, default=8123): network_port,

View File

@ -22,7 +22,6 @@ from .const import (
ATTR_HOMEASSISTANT, ATTR_HOMEASSISTANT,
ATTR_IMAGE, ATTR_IMAGE,
ATTR_LAST_BOOT, ATTR_LAST_BOOT,
ATTR_VERSION_LATEST,
ATTR_LOGGING, ATTR_LOGGING,
ATTR_PORT, ATTR_PORT,
ATTR_PORTS, ATTR_PORTS,
@ -102,10 +101,9 @@ SCHEMA_HASS_CONFIG = vol.Schema(
{ {
vol.Optional(ATTR_UUID, default=lambda: uuid.uuid4().hex): uuid_match, vol.Optional(ATTR_UUID, default=lambda: uuid.uuid4().hex): uuid_match,
vol.Optional(ATTR_VERSION): vol.Maybe(vol.Coerce(str)), vol.Optional(ATTR_VERSION): vol.Maybe(vol.Coerce(str)),
vol.Optional(ATTR_IMAGE): docker_image,
vol.Optional(ATTR_ACCESS_TOKEN): token, vol.Optional(ATTR_ACCESS_TOKEN): token,
vol.Optional(ATTR_BOOT, default=True): vol.Boolean(), vol.Optional(ATTR_BOOT, default=True): vol.Boolean(),
vol.Inclusive(ATTR_IMAGE, "custom_hass"): docker_image,
vol.Inclusive(ATTR_VERSION_LATEST, "custom_hass"): vol.Coerce(str),
vol.Optional(ATTR_PORT, default=8123): network_port, vol.Optional(ATTR_PORT, default=8123): network_port,
vol.Optional(ATTR_REFRESH_TOKEN): vol.Maybe(vol.Coerce(str)), vol.Optional(ATTR_REFRESH_TOKEN): vol.Maybe(vol.Coerce(str)),
vol.Optional(ATTR_SSL, default=False): vol.Boolean(), vol.Optional(ATTR_SSL, default=False): vol.Boolean(),
@ -137,7 +135,7 @@ SCHEMA_UPDATER_CONFIG = vol.Schema(
# pylint: disable=no-value-for-parameter # pylint: disable=no-value-for-parameter
SCHEMA_HASSIO_CONFIG = vol.Schema( SCHEMA_SUPERVISOR_CONFIG = vol.Schema(
{ {
vol.Optional(ATTR_TIMEZONE, default="UTC"): validate_timezone, vol.Optional(ATTR_TIMEZONE, default="UTC"): validate_timezone,
vol.Optional(ATTR_LAST_BOOT): vol.Coerce(str), vol.Optional(ATTR_LAST_BOOT): vol.Coerce(str),
@ -173,6 +171,7 @@ SCHEMA_INGRESS_CONFIG = vol.Schema(
SCHEMA_DNS_CONFIG = vol.Schema( SCHEMA_DNS_CONFIG = vol.Schema(
{ {
vol.Optional(ATTR_VERSION): vol.Maybe(vol.Coerce(str)), vol.Optional(ATTR_VERSION): vol.Maybe(vol.Coerce(str)),
vol.Optional(ATTR_IMAGE): docker_image,
vol.Optional(ATTR_SERVERS, default=list): dns_server_list, vol.Optional(ATTR_SERVERS, default=list): dns_server_list,
}, },
extra=vol.REMOVE_EXTRA, extra=vol.REMOVE_EXTRA,
@ -180,13 +179,18 @@ SCHEMA_DNS_CONFIG = vol.Schema(
SCHEMA_AUDIO_CONFIG = vol.Schema( SCHEMA_AUDIO_CONFIG = vol.Schema(
{vol.Optional(ATTR_VERSION): vol.Maybe(vol.Coerce(str))}, extra=vol.REMOVE_EXTRA, {
vol.Optional(ATTR_VERSION): vol.Maybe(vol.Coerce(str)),
vol.Optional(ATTR_IMAGE): docker_image,
},
extra=vol.REMOVE_EXTRA,
) )
SCHEMA_CLI_CONFIG = vol.Schema( SCHEMA_CLI_CONFIG = vol.Schema(
{ {
vol.Optional(ATTR_VERSION): vol.Maybe(vol.Coerce(str)), vol.Optional(ATTR_VERSION): vol.Maybe(vol.Coerce(str)),
vol.Optional(ATTR_IMAGE): docker_image,
vol.Optional(ATTR_ACCESS_TOKEN): token, vol.Optional(ATTR_ACCESS_TOKEN): token,
}, },
extra=vol.REMOVE_EXTRA, extra=vol.REMOVE_EXTRA,