Merge pull request #1426 from home-assistant/dev

Release 195
This commit is contained in:
Pascal Vizeli 2020-01-09 16:24:00 +01:00 committed by GitHub
commit 3a4ef6ceb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 187 additions and 178 deletions

27
.github/lock.yml vendored Normal file
View File

@ -0,0 +1,27 @@
# Configuration for Lock Threads - https://github.com/dessant/lock-threads
# Number of days of inactivity before a closed issue or pull request is locked
daysUntilLock: 1
# Skip issues and pull requests created before a given timestamp. Timestamp must
# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable
skipCreatedBefore: 2020-01-01
# Issues and pull requests with these labels will be ignored. Set to `[]` to disable
exemptLabels: []
# Label to add before locking, such as `outdated`. Set to `false` to disable
lockLabel: false
# Comment to post before locking. Set to `false` to disable
lockComment: false
# Assign `resolved` as the reason for locking. Set to `false` to disable
setLockReason: false
# Limit to only `issues` or `pulls`
only: pulls
# Optionally, specify configuration settings just for `issues` or `pulls`
issues:
daysUntilLock: 30

1
API.md
View File

@ -410,7 +410,6 @@ Output is the raw Docker log.
"last_version": "Optional for custom image|null",
"port": "port for access hass",
"ssl": "bool",
"password": "",
"refresh_token": "",
"watchdog": "bool",
"wait_boot": 600

View File

@ -4,153 +4,151 @@ trigger:
batch: true
branches:
include:
- master
- dev
- master
- dev
tags:
include:
- '*'
- "*"
exclude:
- untagged*
- untagged*
pr:
- dev
variables:
- name: basePythonTag
value: '3.7-alpine3.10'
value: "3.7-alpine3.11"
- name: versionHadolint
value: 'v1.16.3'
value: "v1.16.3"
- name: versionBuilder
value: '4.4'
value: "4.4"
- name: versionWheels
value: '1.0-3.7-alpine3.10'
value: "1.6-3.7-alpine3.11"
- group: docker
- group: wheels
stages:
- stage: "Test"
jobs:
- job: "Tox"
pool:
vmImage: "ubuntu-latest"
steps:
- task: UsePythonVersion@0
displayName: "Use Python 3.7"
inputs:
versionSpec: "3.7"
- script: pip install tox
displayName: "Install Tox"
- script: tox
displayName: "Run Tox"
- job: "JQ"
pool:
vmImage: "ubuntu-latest"
steps:
- script: sudo apt-get install -y jq
displayName: "Install JQ"
- bash: |
shopt -s globstar
cat **/*.json | jq '.'
displayName: "Run JQ"
- job: "Hadolint"
pool:
vmImage: "ubuntu-latest"
steps:
- script: sudo docker pull hadolint/hadolint:$(versionHadolint)
displayName: "Install Hadolint"
- script: |
sudo docker run --rm -i \
-v $(pwd)/.hadolint.yaml:/.hadolint.yaml:ro \
hadolint/hadolint:$(versionHadolint) < Dockerfile
displayName: "Run Hadolint"
- stage: 'Test'
jobs:
- job: 'Tox'
pool:
vmImage: 'ubuntu-latest'
steps:
- task: UsePythonVersion@0
displayName: 'Use Python 3.7'
inputs:
versionSpec: '3.7'
- script: pip install tox
displayName: 'Install Tox'
- script: tox
displayName: 'Run Tox'
- job: 'JQ'
pool:
vmImage: 'ubuntu-latest'
steps:
- script: sudo apt-get install -y jq
displayName: 'Install JQ'
- bash: |
shopt -s globstar
cat **/*.json | jq '.'
displayName: 'Run JQ'
- job: 'Hadolint'
pool:
vmImage: 'ubuntu-latest'
steps:
- script: sudo docker pull hadolint/hadolint:$(versionHadolint)
displayName: 'Install Hadolint'
- script: |
sudo docker run --rm -i \
-v $(pwd)/.hadolint.yaml:/.hadolint.yaml:ro \
hadolint/hadolint:$(versionHadolint) < Dockerfile
displayName: 'Run Hadolint'
- stage: "Wheels"
jobs:
- job: "Wheels"
condition: eq(variables['Build.SourceBranchName'], 'dev')
timeoutInMinutes: 360
pool:
vmImage: "ubuntu-latest"
strategy:
maxParallel: 5
matrix:
amd64:
buildArch: "amd64"
i386:
buildArch: "i386"
armhf:
buildArch: "armhf"
armv7:
buildArch: "armv7"
aarch64:
buildArch: "aarch64"
steps:
- script: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
qemu-user-static \
binfmt-support \
curl
- stage: 'Wheels'
jobs:
- job: 'Wheels'
condition: eq(variables['Build.SourceBranchName'], 'dev')
timeoutInMinutes: 360
pool:
vmImage: 'ubuntu-latest'
strategy:
maxParallel: 5
matrix:
amd64:
buildArch: 'amd64'
i386:
buildArch: 'i386'
armhf:
buildArch: 'armhf'
armv7:
buildArch: 'armv7'
aarch64:
buildArch: 'aarch64'
steps:
- script: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
qemu-user-static \
binfmt-support \
curl
sudo mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
sudo update-binfmts --enable qemu-arm
sudo update-binfmts --enable qemu-aarch64
displayName: "Initial cross build"
- script: |
mkdir -p .ssh
echo -e "-----BEGIN RSA PRIVATE KEY-----\n$(wheelsSSH)\n-----END RSA PRIVATE KEY-----" >> .ssh/id_rsa
ssh-keyscan -H $(wheelsHost) >> .ssh/known_hosts
chmod 600 .ssh/*
displayName: "Install ssh key"
- script: sudo docker pull homeassistant/$(buildArch)-wheels:$(versionWheels)
displayName: "Install wheels builder"
- script: |
sudo docker run --rm -v $(pwd):/data:ro -v $(pwd)/.ssh:/root/.ssh:rw \
homeassistant/$(buildArch)-wheels:$(versionWheels) \
--apk "build-base;libffi-dev;openssl-dev" \
--index $(wheelsIndex) \
--requirement requirements.txt \
--upload rsync \
--remote wheels@$(wheelsHost):/opt/wheels
displayName: "Run wheels build"
sudo mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
sudo update-binfmts --enable qemu-arm
sudo update-binfmts --enable qemu-aarch64
displayName: 'Initial cross build'
- script: |
mkdir -p .ssh
echo -e "-----BEGIN RSA PRIVATE KEY-----\n$(wheelsSSH)\n-----END RSA PRIVATE KEY-----" >> .ssh/id_rsa
ssh-keyscan -H $(wheelsHost) >> .ssh/known_hosts
chmod 600 .ssh/*
displayName: 'Install ssh key'
- script: sudo docker pull homeassistant/$(buildArch)-wheels:$(versionWheels)
displayName: 'Install wheels builder'
- script: |
sudo docker run --rm -v $(pwd):/data:ro -v $(pwd)/.ssh:/root/.ssh:rw \
homeassistant/$(buildArch)-wheels:$(versionWheels) \
--apk "build-base;libffi-dev;openssl-dev" \
--index $(wheelsIndex) \
--requirement requirements.txt \
--upload rsync \
--remote wheels@$(wheelsHost):/opt/wheels
displayName: 'Run wheels build'
- stage: "Deploy"
jobs:
- job: "VersionValidate"
condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), eq(variables['Build.SourceBranchName'], 'dev'))
pool:
vmImage: "ubuntu-latest"
steps:
- task: UsePythonVersion@0
displayName: "Use Python 3.7"
inputs:
versionSpec: "3.7"
- script: |
setup_version="$(python setup.py -V)"
branch_version="$(Build.SourceBranchName)"
- stage: 'Deploy'
jobs:
- job: 'VersionValidate'
condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), eq(variables['Build.SourceBranchName'], 'dev'))
pool:
vmImage: 'ubuntu-latest'
steps:
- task: UsePythonVersion@0
displayName: 'Use Python 3.7'
inputs:
versionSpec: '3.7'
- script: |
setup_version="$(python setup.py -V)"
branch_version="$(Build.SourceBranchName)"
if [ "${branch_version}" == "dev" ]; then
exit 0
elif [ "${setup_version}" != "${branch_version}" ]; then
echo "Version of tag ${branch_version} don't match with ${setup_version}!"
exit 1
fi
displayName: 'Check version of branch/tag'
- job: 'Release'
dependsOn:
- 'VersionValidate'
pool:
vmImage: 'ubuntu-latest'
steps:
- script: sudo docker login -u $(dockerUser) -p $(dockerPassword)
displayName: 'Docker hub login'
- script: sudo docker pull homeassistant/amd64-builder:$(versionBuilder)
displayName: 'Install Builder'
- script: |
sudo docker run --rm --privileged \
-v ~/.docker:/root/.docker \
-v /run/docker.sock:/run/docker.sock:rw -v $(pwd):/data:ro \
homeassistant/amd64-builder:$(versionBuilder) \
--supervisor $(basePythonTag) --version $(Build.SourceBranchName) \
--all -t /data --docker-hub homeassistant
displayName: 'Build Release'
if [ "${branch_version}" == "dev" ]; then
exit 0
elif [ "${setup_version}" != "${branch_version}" ]; then
echo "Version of tag ${branch_version} don't match with ${setup_version}!"
exit 1
fi
displayName: "Check version of branch/tag"
- job: "Release"
dependsOn:
- "VersionValidate"
pool:
vmImage: "ubuntu-latest"
steps:
- script: sudo docker login -u $(dockerUser) -p $(dockerPassword)
displayName: "Docker hub login"
- script: sudo docker pull homeassistant/amd64-builder:$(versionBuilder)
displayName: "Install Builder"
- script: |
sudo docker run --rm --privileged \
-v ~/.docker:/root/.docker \
-v /run/docker.sock:/run/docker.sock:rw -v $(pwd):/data:ro \
homeassistant/amd64-builder:$(versionBuilder) \
--supervisor $(basePythonTag) --version $(Build.SourceBranchName) \
--all -t /data --docker-hub homeassistant
displayName: "Build Release"

View File

@ -254,10 +254,10 @@ class AddonManager(CoreSysAttributes):
async def restore(self, slug: str, tar_file: tarfile.TarFile) -> None:
"""Restore state of an add-on."""
if slug not in self.local:
_LOGGER.debug("Add-on %s is not local available for restore")
_LOGGER.debug("Add-on %s is not local available for restore", slug)
addon = Addon(self.coresys, slug)
else:
_LOGGER.debug("Add-on %s is local available for restore")
_LOGGER.debug("Add-on %s is local available for restore", slug)
addon = self.local[slug]
await addon.restore(tar_file)

View File

@ -25,6 +25,9 @@ from .supervisor import APISupervisor
_LOGGER: logging.Logger = logging.getLogger(__name__)
MAX_CLIENT_SIZE: int = 1024 ** 2 * 16
class RestAPI(CoreSysAttributes):
"""Handle RESTful API for Hass.io."""
@ -33,7 +36,8 @@ class RestAPI(CoreSysAttributes):
self.coresys: CoreSys = coresys
self.security: SecurityMiddleware = SecurityMiddleware(coresys)
self.webapp: web.Application = web.Application(
middlewares=[self.security.token_validation]
client_max_size=MAX_CLIENT_SIZE,
middlewares=[self.security.token_validation],
)
# service stuff

View File

@ -21,7 +21,6 @@ from ..const import (
ATTR_MEMORY_PERCENT,
ATTR_NETWORK_RX,
ATTR_NETWORK_TX,
ATTR_PASSWORD,
ATTR_PORT,
ATTR_REFRESH_TOKEN,
ATTR_SSL,
@ -45,7 +44,6 @@ SCHEMA_OPTIONS = vol.Schema(
vol.Inclusive(ATTR_IMAGE, "custom_hass"): vol.Maybe(docker_image),
vol.Inclusive(ATTR_LAST_VERSION, "custom_hass"): vol.Maybe(vol.Coerce(str)),
vol.Optional(ATTR_PORT): network_port,
vol.Optional(ATTR_PASSWORD): vol.Maybe(vol.Coerce(str)),
vol.Optional(ATTR_SSL): vol.Boolean(),
vol.Optional(ATTR_WATCHDOG): vol.Boolean(),
vol.Optional(ATTR_WAIT_BOOT): vol.All(vol.Coerce(int), vol.Range(min=60)),
@ -92,10 +90,6 @@ class APIHomeAssistant(CoreSysAttributes):
if ATTR_PORT in body:
self.sys_homeassistant.api_port = body[ATTR_PORT]
if ATTR_PASSWORD in body:
self.sys_homeassistant.api_password = body[ATTR_PASSWORD]
self.sys_homeassistant.refresh_token = None
if ATTR_SSL in body:
self.sys_homeassistant.api_ssl = body[ATTR_SSL]
@ -107,7 +101,6 @@ class APIHomeAssistant(CoreSysAttributes):
if ATTR_REFRESH_TOKEN in body:
self.sys_homeassistant.refresh_token = body[ATTR_REFRESH_TOKEN]
self.sys_homeassistant.api_password = None
self.sys_homeassistant.save_data()

View File

@ -2,7 +2,7 @@
from pathlib import Path
from ipaddress import ip_network
HASSIO_VERSION = "194"
HASSIO_VERSION = "195"
URL_HASSIO_ADDONS = "https://github.com/home-assistant/hassio-addons"

View File

@ -112,13 +112,13 @@ class HassOS(CoreSysAttributes):
async def load(self) -> None:
"""Load HassOS data."""
try:
if self.sys_host.info.cpe is None:
raise TypeError()
cpe = CPE(self.sys_host.info.cpe)
if not self.sys_host.info.cpe:
raise NotImplementedError()
cpe = CPE(self.sys_host.info.cpe)
if cpe.get_product()[0] != "hassos":
raise TypeError()
except TypeError:
raise NotImplementedError()
except NotImplementedError:
_LOGGER.debug("Found no HassOS")
return
else:

View File

@ -22,7 +22,6 @@ from .const import (
ATTR_BOOT,
ATTR_IMAGE,
ATTR_LAST_VERSION,
ATTR_PASSWORD,
ATTR_PORT,
ATTR_REFRESH_TOKEN,
ATTR_SSL,
@ -31,7 +30,6 @@ from .const import (
ATTR_WAIT_BOOT,
ATTR_WATCHDOG,
FILE_HASSIO_HOMEASSISTANT,
HEADER_HA_ACCESS,
)
from .coresys import CoreSys, CoreSysAttributes
from .docker.homeassistant import DockerHomeAssistant
@ -122,16 +120,6 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
"""Set network port for Home Assistant instance."""
self._data[ATTR_PORT] = value
@property
def api_password(self) -> str:
"""Return password for Home Assistant instance."""
return self._data.get(ATTR_PASSWORD)
@api_password.setter
def api_password(self, value: str):
"""Set password for Home Assistant instance."""
self._data[ATTR_PASSWORD] = value
@property
def api_ssl(self) -> bool:
"""Return if we need ssl to Home Assistant instance."""
@ -500,10 +488,6 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
if content_type is not None:
headers[hdrs.CONTENT_TYPE] = content_type
# Set old API Password
if not self.refresh_token and self.api_password:
headers[HEADER_HA_ACCESS] = self.api_password
for _ in (1, 2):
# Prepare Access token
if self.refresh_token:

View File

@ -24,7 +24,6 @@ from ..const import (
ATTR_IMAGE,
ATTR_LAST_VERSION,
ATTR_NAME,
ATTR_PASSWORD,
ATTR_PORT,
ATTR_PROTECTED,
ATTR_REFRESH_TOKEN,
@ -37,16 +36,27 @@ from ..const import (
ATTR_WAIT_BOOT,
ATTR_WATCHDOG,
CRYPTO_AES128,
FOLDER_HOMEASSISTANT,
)
from ..coresys import CoreSys, CoreSysAttributes
from ..exceptions import AddonsError
from ..utils.json import write_json_file
from ..utils.tar import SecureTarFile, secure_path
from ..utils.tar import SecureTarFile, exclude_filter, secure_path
from .utils import key_to_iv, password_for_validating, password_to_key, remove_folder
from .validate import ALL_FOLDERS, SCHEMA_SNAPSHOT
_LOGGER: logging.Logger = logging.getLogger(__name__)
MAP_FOLDER_EXCLUDE = {
FOLDER_HOMEASSISTANT: [
"*.db-wal",
"*.db-shm",
"__pycache__/*",
"*.log",
"OZW_Log.txt",
]
}
class Snapshot(CoreSysAttributes):
"""A single Hass.io snapshot."""
@ -359,7 +369,11 @@ class Snapshot(CoreSysAttributes):
try:
_LOGGER.info("Snapshot folder %s", name)
with SecureTarFile(tar_name, "w", key=self._key) as tar_file:
tar_file.add(origin_dir, arcname=".")
tar_file.add(
origin_dir,
arcname=".",
filter=exclude_filter(MAP_FOLDER_EXCLUDE.get(name, [])),
)
_LOGGER.info("Snapshot folder %s done", name)
self._data[ATTR_FOLDERS].append(name)
@ -428,9 +442,6 @@ class Snapshot(CoreSysAttributes):
self.homeassistant[ATTR_REFRESH_TOKEN] = self._encrypt_data(
self.sys_homeassistant.refresh_token
)
self.homeassistant[ATTR_PASSWORD] = self._encrypt_data(
self.sys_homeassistant.api_password
)
def restore_homeassistant(self):
"""Write all data to the Home Assistant object."""
@ -451,9 +462,6 @@ class Snapshot(CoreSysAttributes):
self.sys_homeassistant.refresh_token = self._decrypt_data(
self.homeassistant[ATTR_REFRESH_TOKEN]
)
self.sys_homeassistant.api_password = self._decrypt_data(
self.homeassistant[ATTR_PASSWORD]
)
# save
self.sys_homeassistant.save_data()

View File

@ -11,7 +11,6 @@ from ..const import (
ATTR_IMAGE,
ATTR_LAST_VERSION,
ATTR_NAME,
ATTR_PASSWORD,
ATTR_PORT,
ATTR_PROTECTED,
ATTR_REFRESH_TOKEN,
@ -64,7 +63,6 @@ SCHEMA_SNAPSHOT = vol.Schema(
vol.Optional(ATTR_BOOT, default=True): vol.Boolean(),
vol.Optional(ATTR_SSL, default=False): vol.Boolean(),
vol.Optional(ATTR_PORT, default=8123): network_port,
vol.Optional(ATTR_PASSWORD): vol.Maybe(vol.Coerce(str)),
vol.Optional(ATTR_REFRESH_TOKEN): vol.Maybe(vol.Coerce(str)),
vol.Optional(ATTR_WATCHDOG, default=True): vol.Boolean(),
vol.Optional(ATTR_WAIT_BOOT, default=600): vol.All(

View File

@ -21,7 +21,6 @@ from .const import (
ATTR_LAST_BOOT,
ATTR_LAST_VERSION,
ATTR_LOGGING,
ATTR_PASSWORD,
ATTR_PORT,
ATTR_PORTS,
ATTR_REFRESH_TOKEN,
@ -110,7 +109,6 @@ SCHEMA_HASS_CONFIG = vol.Schema(
vol.Inclusive(ATTR_IMAGE, "custom_hass"): docker_image,
vol.Inclusive(ATTR_LAST_VERSION, "custom_hass"): vol.Coerce(str),
vol.Optional(ATTR_PORT, default=8123): network_port,
vol.Optional(ATTR_PASSWORD): 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_WATCHDOG, default=True): vol.Boolean(),