Improve version handling (#1744)

* version handling helper

* Improve version handling

* Fix bug
This commit is contained in:
Pascal Vizeli 2020-05-22 14:21:47 +02:00 committed by GitHub
parent 630d85ec78
commit 9dba78fbcd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 55 additions and 26 deletions

View File

@ -33,11 +33,12 @@ from ..const import (
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
from ..exceptions import APIError from ..exceptions import APIError
from ..host.sound import StreamType from ..host.sound import StreamType
from ..validate import simple_version
from .utils import api_process, api_process_raw, api_validate from .utils import api_process, api_process_raw, api_validate
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): vol.Coerce(str)}) SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): simple_version})
SCHEMA_VOLUME = vol.Schema( SCHEMA_VOLUME = vol.Schema(
{ {

View File

@ -19,11 +19,12 @@ from ..const import (
ATTR_VERSION_LATEST, ATTR_VERSION_LATEST,
) )
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
from ..validate import simple_version
from .utils import api_process, api_validate from .utils import api_process, api_validate
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): vol.Coerce(str)}) SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): simple_version})
class APICli(CoreSysAttributes): class APICli(CoreSysAttributes):

View File

@ -24,7 +24,7 @@ from ..const import (
) )
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
from ..exceptions import APIError from ..exceptions import APIError
from ..validate import dns_server_list from ..validate import dns_server_list, simple_version
from .utils import api_process, api_process_raw, api_validate from .utils import api_process, api_process_raw, api_validate
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
@ -32,7 +32,7 @@ _LOGGER: logging.Logger = logging.getLogger(__name__)
# pylint: disable=no-value-for-parameter # pylint: disable=no-value-for-parameter
SCHEMA_OPTIONS = vol.Schema({vol.Optional(ATTR_SERVERS): dns_server_list}) SCHEMA_OPTIONS = vol.Schema({vol.Optional(ATTR_SERVERS): dns_server_list})
SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): vol.Coerce(str)}) SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): simple_version})
class APICoreDNS(CoreSysAttributes): class APICoreDNS(CoreSysAttributes):

View File

@ -33,7 +33,7 @@ from ..const import (
) )
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
from ..exceptions import APIError from ..exceptions import APIError
from ..validate import docker_image, network_port from ..validate import docker_image, network_port, complex_version
from .utils import api_process, api_process_raw, api_validate from .utils import api_process, api_process_raw, api_validate
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
@ -53,7 +53,7 @@ SCHEMA_OPTIONS = vol.Schema(
} }
) )
SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): vol.Coerce(str)}) SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): complex_version})
class APIHomeAssistant(CoreSysAttributes): class APIHomeAssistant(CoreSysAttributes):

View File

@ -21,11 +21,12 @@ from ..const import (
) )
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
from ..exceptions import APIError from ..exceptions import APIError
from ..validate import simple_version
from .utils import api_process, api_process_raw, api_validate from .utils import api_process, api_process_raw, api_validate
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): vol.Coerce(str)}) SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): simple_version})
class APIMulticast(CoreSysAttributes): class APIMulticast(CoreSysAttributes):

View File

@ -8,11 +8,12 @@ import voluptuous as vol
from ..const import ATTR_BOARD, ATTR_BOOT, ATTR_VERSION, ATTR_VERSION_LATEST from ..const import ATTR_BOARD, ATTR_BOOT, ATTR_VERSION, ATTR_VERSION_LATEST
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
from ..validate import complex_version
from .utils import api_process, api_validate from .utils import api_process, api_validate
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): vol.Coerce(str)}) SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): complex_version})
class APIOS(CoreSysAttributes): class APIOS(CoreSysAttributes):

View File

@ -43,7 +43,7 @@ from ..const import (
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
from ..exceptions import APIError from ..exceptions import APIError
from ..utils.validate import validate_timezone from ..utils.validate import validate_timezone
from ..validate import repositories, wait_boot from ..validate import repositories, wait_boot, simple_version
from .utils import api_process, api_process_raw, api_validate from .utils import api_process, api_process_raw, api_validate
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
@ -61,7 +61,7 @@ SCHEMA_OPTIONS = vol.Schema(
} }
) )
SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): vol.Coerce(str)}) SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): simple_version})
class APISupervisor(CoreSysAttributes): class APISupervisor(CoreSysAttributes):

View File

@ -3,11 +3,11 @@
import voluptuous as vol import voluptuous as vol
from ..const import ATTR_ACCESS_TOKEN, ATTR_IMAGE, ATTR_SERVERS, ATTR_VERSION from ..const import ATTR_ACCESS_TOKEN, ATTR_IMAGE, ATTR_SERVERS, ATTR_VERSION
from ..validate import dns_server_list, docker_image, token from ..validate import dns_server_list, docker_image, token, simple_version
SCHEMA_DNS_CONFIG = vol.Schema( SCHEMA_DNS_CONFIG = vol.Schema(
{ {
vol.Optional(ATTR_VERSION): vol.Maybe(vol.Coerce(str)), vol.Optional(ATTR_VERSION): simple_version,
vol.Optional(ATTR_IMAGE): docker_image, vol.Optional(ATTR_IMAGE): docker_image,
vol.Optional(ATTR_SERVERS, default=list): dns_server_list, vol.Optional(ATTR_SERVERS, default=list): dns_server_list,
}, },
@ -17,7 +17,7 @@ SCHEMA_DNS_CONFIG = vol.Schema(
SCHEMA_AUDIO_CONFIG = vol.Schema( SCHEMA_AUDIO_CONFIG = vol.Schema(
{ {
vol.Optional(ATTR_VERSION): vol.Maybe(vol.Coerce(str)), vol.Optional(ATTR_VERSION): simple_version,
vol.Optional(ATTR_IMAGE): docker_image, vol.Optional(ATTR_IMAGE): docker_image,
}, },
extra=vol.REMOVE_EXTRA, extra=vol.REMOVE_EXTRA,
@ -26,7 +26,7 @@ SCHEMA_AUDIO_CONFIG = vol.Schema(
SCHEMA_CLI_CONFIG = vol.Schema( SCHEMA_CLI_CONFIG = vol.Schema(
{ {
vol.Optional(ATTR_VERSION): vol.Maybe(vol.Coerce(str)), vol.Optional(ATTR_VERSION): simple_version,
vol.Optional(ATTR_IMAGE): docker_image, vol.Optional(ATTR_IMAGE): docker_image,
vol.Optional(ATTR_ACCESS_TOKEN): token, vol.Optional(ATTR_ACCESS_TOKEN): token,
}, },
@ -36,7 +36,7 @@ SCHEMA_CLI_CONFIG = vol.Schema(
SCHEMA_MULTICAST_CONFIG = vol.Schema( SCHEMA_MULTICAST_CONFIG = vol.Schema(
{ {
vol.Optional(ATTR_VERSION): vol.Maybe(vol.Coerce(str)), vol.Optional(ATTR_VERSION): simple_version,
vol.Optional(ATTR_IMAGE): docker_image, vol.Optional(ATTR_IMAGE): docker_image,
}, },
extra=vol.REMOVE_EXTRA, extra=vol.REMOVE_EXTRA,

View File

@ -31,7 +31,7 @@ from ..const import (
SNAPSHOT_FULL, SNAPSHOT_FULL,
SNAPSHOT_PARTIAL, SNAPSHOT_PARTIAL,
) )
from ..validate import docker_image, network_port, repositories from ..validate import docker_image, network_port, repositories, complex_version
ALL_FOLDERS = [FOLDER_HOMEASSISTANT, FOLDER_SHARE, FOLDER_ADDONS, FOLDER_SSL] ALL_FOLDERS = [FOLDER_HOMEASSISTANT, FOLDER_SHARE, FOLDER_ADDONS, FOLDER_SSL]
@ -58,7 +58,7 @@ SCHEMA_SNAPSHOT = vol.Schema(
vol.Inclusive(ATTR_CRYPTO, "encrypted"): CRYPTO_AES128, vol.Inclusive(ATTR_CRYPTO, "encrypted"): CRYPTO_AES128,
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): complex_version,
vol.Optional(ATTR_IMAGE): docker_image, vol.Optional(ATTR_IMAGE): docker_image,
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(),

View File

@ -2,8 +2,10 @@
import ipaddress import ipaddress
import re import re
import uuid import uuid
from typing import Optional, Union
import voluptuous as vol import voluptuous as vol
from packaging import version as pkg_version
from .const import ( from .const import (
ATTR_ACCESS_TOKEN, ATTR_ACCESS_TOKEN,
@ -51,6 +53,29 @@ sha256 = vol.Match(r"^[0-9a-f]{64}$")
token = vol.Match(r"^[0-9a-f]{32,256}$") token = vol.Match(r"^[0-9a-f]{32,256}$")
def simple_version(value: Union[str, int, None]) -> Optional[str]:
"""Validate main version handling."""
if not isinstance(value, (str, int)):
return None
elif isinstance(value, int):
return str(value)
elif value.isnumeric() or value == "dev":
return value
return None
def complex_version(value: Union[str, None]) -> Optional[str]:
"""Validate main version handling."""
if not isinstance(value, str):
return None
try:
pkg_version.parse(value)
except pkg_version.InvalidVersion:
raise vol.Invalid(f"Invalid version format {value}")
return value
def dns_url(url: str) -> str: def dns_url(url: str) -> str:
"""Take a DNS url (str) and validates that it matches the scheme dns://<ip address>.""" """Take a DNS url (str) and validates that it matches the scheme dns://<ip address>."""
if not url.lower().startswith("dns://"): if not url.lower().startswith("dns://"):
@ -100,7 +125,7 @@ DOCKER_PORTS_DESCRIPTION = vol.Schema(
SCHEMA_HASS_CONFIG = vol.Schema( 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.Coerce(str), vol.Optional(ATTR_VERSION): complex_version,
vol.Optional(ATTR_IMAGE): docker_image, 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(),
@ -123,13 +148,13 @@ SCHEMA_UPDATER_CONFIG = vol.Schema(
vol.Optional(ATTR_CHANNEL, default=UpdateChannels.STABLE): vol.Coerce( vol.Optional(ATTR_CHANNEL, default=UpdateChannels.STABLE): vol.Coerce(
UpdateChannels UpdateChannels
), ),
vol.Optional(ATTR_HOMEASSISTANT): vol.Coerce(str), vol.Optional(ATTR_HOMEASSISTANT): complex_version,
vol.Optional(ATTR_SUPERVISOR): vol.Coerce(str), vol.Optional(ATTR_SUPERVISOR): simple_version,
vol.Optional(ATTR_HASSOS): vol.Coerce(str), vol.Optional(ATTR_HASSOS): complex_version,
vol.Optional(ATTR_CLI): vol.Coerce(str), vol.Optional(ATTR_CLI): simple_version,
vol.Optional(ATTR_DNS): vol.Coerce(str), vol.Optional(ATTR_DNS): simple_version,
vol.Optional(ATTR_AUDIO): vol.Coerce(str), vol.Optional(ATTR_AUDIO): simple_version,
vol.Optional(ATTR_MULTICAST): vol.Coerce(str), vol.Optional(ATTR_MULTICAST): simple_version,
vol.Optional(ATTR_IMAGE, default=dict): vol.Schema( vol.Optional(ATTR_IMAGE, default=dict): vol.Schema(
{ {
vol.Optional(ATTR_HOMEASSISTANT): docker_image, vol.Optional(ATTR_HOMEASSISTANT): docker_image,
@ -151,7 +176,7 @@ 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),
vol.Optional(ATTR_VERSION): vol.Coerce(str), vol.Optional(ATTR_VERSION): simple_version,
vol.Optional( vol.Optional(
ATTR_ADDONS_CUSTOM_LIST, ATTR_ADDONS_CUSTOM_LIST,
default=["https://github.com/hassio-addons/repository"], default=["https://github.com/hassio-addons/repository"],