Skip to content

Commit

Permalink
Fix
Browse files Browse the repository at this point in the history
  • Loading branch information
pvizeli committed May 22, 2017
2 parents c516d46 + 8d4dd7d commit cb2dd3b
Show file tree
Hide file tree
Showing 14 changed files with 116 additions and 21 deletions.
7 changes: 7 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ The addons from `addons` are only installed one.
"last_version": "LAST_VERSION",
"arch": "armhf|aarch64|i386|amd64",
"beta_channel": "true|false",
"timezone": "TIMEZONE",
"addons": [
{
"name": "xy bla",
Expand Down Expand Up @@ -98,6 +99,7 @@ Optional:
```json
{
"beta_channel": "true|false",
"timezone": "TIMEZONE",
"addons_repositories": [
"REPO_URL"
]
Expand Down Expand Up @@ -176,6 +178,11 @@ Optional:
### Network

- GET `/network/info`
```json
{
"hostname": ""
}
```

- POST `/network/options`
```json
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ Hass.io is a Docker based system for managing your Home Assistant installation a

**HassIO is under active development and is not ready yet for production use.**

## Installing Hass.io
## Installation

Looks to our [website](https://home-assistant.io/hassio).
Installation instructions can be found at [https://home-assistant.io/hassio](https://home-assistant.io/hassio).

# HomeAssistant

Expand Down
8 changes: 7 additions & 1 deletion hassio/addons/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
FILE_HASSIO_ADDONS, ATTR_NAME, ATTR_VERSION, ATTR_SLUG, ATTR_DESCRIPTON,
ATTR_STARTUP, ATTR_BOOT, ATTR_MAP, ATTR_OPTIONS, ATTR_PORTS, BOOT_AUTO,
ATTR_SCHEMA, ATTR_IMAGE, ATTR_REPOSITORY, ATTR_URL, ATTR_ARCH,
ATTR_LOCATON, ATTR_DEVICES, ATTR_ENVIRONMENT)
ATTR_LOCATON, ATTR_DEVICES, ATTR_ENVIRONMENT, ATTR_HOST_NETWORK)
from ..config import Config
from ..tools import read_json_file, write_json_file

Expand Down Expand Up @@ -294,6 +294,12 @@ def get_ports(self, addon):
"""Return ports of addon."""
return self._system_data[addon].get(ATTR_PORTS)

def get_network_mode(self, addon):
"""Return network mode of addon."""
if self._system_data[addon][ATTR_HOST_NETWORK]:
return 'host'
return 'bridge'

def get_devices(self, addon):
"""Return devices of addon."""
return self._system_data[addon].get(ATTR_DEVICES)
Expand Down
19 changes: 16 additions & 3 deletions hassio/addons/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
ATTR_BOOT, ATTR_MAP, ATTR_OPTIONS, ATTR_PORTS, STARTUP_ONCE, STARTUP_AFTER,
STARTUP_BEFORE, STARTUP_INITIALIZE, BOOT_AUTO, BOOT_MANUAL, ATTR_SCHEMA,
ATTR_IMAGE, ATTR_URL, ATTR_MAINTAINER, ATTR_ARCH, ATTR_DEVICES,
ATTR_ENVIRONMENT, ARCH_ARMHF, ARCH_AARCH64, ARCH_AMD64, ARCH_I386)
ATTR_ENVIRONMENT, ATTR_HOST_NETWORK, ARCH_ARMHF, ARCH_AARCH64, ARCH_AMD64,
ARCH_I386)


MAP_VOLUME = r"^(config|ssl|addons|backup|share)(?::(rw|:ro))?$"
Expand All @@ -24,8 +25,19 @@
ARCH_ARMHF, ARCH_AARCH64, ARCH_AMD64, ARCH_I386
]


def check_network(data):
"""Validate network settings."""
host_network = data[ATTR_HOST_NETWORK]

if ATTR_PORTS in data and host_network:
raise vol.Invalid("Hostnetwork & ports are not allow!")

return data


# pylint: disable=no-value-for-parameter
SCHEMA_ADDON_CONFIG = vol.Schema({
SCHEMA_ADDON_CONFIG = vol.Schema(vol.All({
vol.Required(ATTR_NAME): vol.Coerce(str),
vol.Required(ATTR_VERSION): vol.Coerce(str),
vol.Required(ATTR_SLUG): vol.Coerce(str),
Expand All @@ -38,6 +50,7 @@
vol.Required(ATTR_BOOT):
vol.In([BOOT_AUTO, BOOT_MANUAL]),
vol.Optional(ATTR_PORTS): dict,
vol.Optional(ATTR_HOST_NETWORK, default=False): vol.Boolean(),
vol.Optional(ATTR_DEVICES): [vol.Match(r"^(.*):(.*):([rwm]{1,3})$")],
vol.Optional(ATTR_MAP, default=[]): [vol.Match(MAP_VOLUME)],
vol.Optional(ATTR_ENVIRONMENT): {vol.Match(r"\w*"): vol.Coerce(str)},
Expand All @@ -48,7 +61,7 @@
])
},
vol.Optional(ATTR_IMAGE): vol.Match(r"\w*/\w*"),
}, extra=vol.ALLOW_EXTRA)
}, check_network), extra=vol.ALLOW_EXTRA)


# pylint: disable=no-value-for-parameter
Expand Down
29 changes: 23 additions & 6 deletions hassio/api/network.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
"""Init file for HassIO network rest api."""
import logging

from .util import api_process_hostcontrol
import voluptuous as vol

from .util import api_process, api_process_hostcontrol, api_validate
from ..const import ATTR_HOSTNAME

_LOGGER = logging.getLogger(__name__)


SCHEMA_OPTIONS = vol.Schema({
vol.Optional(ATTR_HOSTNAME): vol.Coerce(str),
})


class APINetwork(object):
"""Handle rest api for network functions."""

Expand All @@ -15,12 +23,21 @@ def __init__(self, config, loop, host_control):
self.loop = loop
self.host_control = host_control

@api_process_hostcontrol
def info(self, request):
@api_process
async def info(self, request):
"""Show network settings."""
pass
return {
ATTR_HOSTNAME: self.host_control.hostname,
}

@api_process_hostcontrol
def options(self, request):
async def options(self, request):
"""Edit network settings."""
pass
body = await api_validate(SCHEMA_OPTIONS, request)

# hostname
if ATTR_HOSTNAME in body:
if self.host_control.hostname != body[ATTR_HOSTNAME]:
await self.host_control.set_hostname(body[ATTR_HOSTNAME])

return True
8 changes: 7 additions & 1 deletion hassio/api/supervisor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@
HASSIO_VERSION, ATTR_ADDONS_REPOSITORIES, ATTR_REPOSITORIES,
ATTR_REPOSITORY, ATTR_DESCRIPTON, ATTR_NAME, ATTR_SLUG, ATTR_INSTALLED,
ATTR_DETACHED, ATTR_SOURCE, ATTR_MAINTAINER, ATTR_URL, ATTR_ARCH,
ATTR_BUILD)
ATTR_BUILD, ATTR_TIMEZONE)
from ..tools import validate_timezone

_LOGGER = logging.getLogger(__name__)

SCHEMA_OPTIONS = vol.Schema({
# pylint: disable=no-value-for-parameter
vol.Optional(ATTR_BETA_CHANNEL): vol.Boolean(),
vol.Optional(ATTR_ADDONS_REPOSITORIES): [vol.Url()],
vol.Optional(ATTR_TIMEZONE): validate_timezone,
})

SCHEMA_VERSION = vol.Schema({
Expand Down Expand Up @@ -92,6 +94,7 @@ async def info(self, request):
ATTR_LAST_VERSION: self.config.last_hassio,
ATTR_BETA_CHANNEL: self.config.upstream_beta,
ATTR_ARCH: self.addons.arch,
ATTR_TIMEZONE: self.config.timezone,
ATTR_ADDONS: self._addons_list(only_installed=True),
ATTR_ADDONS_REPOSITORIES: self.config.addons_repositories,
}
Expand All @@ -112,6 +115,9 @@ async def options(self, request):
if ATTR_BETA_CHANNEL in body:
self.config.upstream_beta = body[ATTR_BETA_CHANNEL]

if ATTR_TIMEZONE in body:
self.config.timezone = body[ATTR_TIMEZONE]

if ATTR_ADDONS_REPOSITORIES in body:
new = set(body[ATTR_ADDONS_REPOSITORIES])
old = set(self.config.addons_repositories)
Expand Down
16 changes: 14 additions & 2 deletions hassio/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from .const import FILE_HASSIO_CONFIG, HASSIO_SHARE
from .tools import (
fetch_last_versions, write_json_file, read_json_file)
fetch_last_versions, write_json_file, read_json_file, validate_timezone)

_LOGGER = logging.getLogger(__name__)

Expand All @@ -35,8 +35,8 @@
SHARE_DATA = PurePath("share")

UPSTREAM_BETA = 'upstream_beta'

API_ENDPOINT = 'api_endpoint'
TIMEZONE = 'timezone'

SECURITY_INITIALIZE = 'security_initialize'
SECURITY_TOTP = 'security_totp'
Expand All @@ -48,6 +48,7 @@
SCHEMA_CONFIG = vol.Schema({
vol.Optional(UPSTREAM_BETA, default=False): vol.Boolean(),
vol.Optional(API_ENDPOINT): vol.Coerce(str),
vol.Optional(TIMEZONE, default='UTC'): validate_timezone,
vol.Optional(HOMEASSISTANT_LAST): vol.Coerce(str),
vol.Optional(HASSIO_LAST): vol.Coerce(str),
vol.Optional(HASSIO_CLEANUP): vol.Coerce(str),
Expand Down Expand Up @@ -136,6 +137,17 @@ def upstream_beta(self, value):
"""Set beta upstream mode."""
self._data[UPSTREAM_BETA] = bool(value)

@property
def timezone(self):
"""Return system timezone."""
return self._data[TIMEZONE]

@timezone.setter
def timezone(self, value):
"""Set system timezone."""
self._data[TIMEZONE] = value
self.save()

@property
def hassio_cleanup(self):
"""Return Version they need to cleanup."""
Expand Down
4 changes: 3 additions & 1 deletion hassio/const.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Const file for HassIO."""
from pathlib import Path

HASSIO_VERSION = '0.31'
HASSIO_VERSION = '0.32'

URL_HASSIO_VERSION = ('https://raw.githubusercontent.com/home-assistant/'
'hassio/master/version.json')
Expand Down Expand Up @@ -43,6 +43,7 @@

ATTR_ARCH = 'arch'
ATTR_HOSTNAME = 'hostname'
ATTR_TIMEZONE = 'timezone'
ATTR_OS = 'os'
ATTR_TYPE = 'type'
ATTR_SOURCE = 'source'
Expand Down Expand Up @@ -77,6 +78,7 @@
ATTR_BUILD = 'build'
ATTR_DEVICES = 'devices'
ATTR_ENVIRONMENT = 'environment'
ATTR_HOST_NETWORK = 'host_network'

STARTUP_INITIALIZE = 'initialize'
STARTUP_BEFORE = 'before'
Expand Down
16 changes: 13 additions & 3 deletions hassio/dock/addon.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ def docker_name(self):
"""Return name of docker container."""
return "addon_{}".format(self.addon)

@property
def environment(self):
"""Return environment for docker add-on."""
addon_env = self.addons_data.get_environment(self.addon) or {}

return {
**addon_env,
'TZ': self.config.timezone,
}

@property
def volumes(self):
"""Generate volumes for mappings."""
Expand Down Expand Up @@ -86,11 +96,11 @@ def _run(self):
self.image,
name=self.docker_name,
detach=True,
network_mode='bridge',
network_mode=self.addons_data.get_network_mode(self.addon),
ports=self.addons_data.get_ports(self.addon),
devices=self.addons_data.get_devices(self.addon),
environment=self.addons_data.get_environment(self.addon),
volumes=self.volumes,
environment=self.environment,
volumes=self.volumes
)

self.process_metadata()
Expand Down
1 change: 1 addition & 0 deletions hassio/dock/homeassistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def _run(self):
network_mode='host',
environment={
'HASSIO': self.config.api_endpoint,
'TZ': self.config.timezone,
},
volumes={
str(self.config.path_extern_config):
Expand Down
5 changes: 5 additions & 0 deletions hassio/host_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
FEATURES_SHUTDOWN = 'shutdown'
FEATURES_REBOOT = 'reboot'
FEATURES_UPDATE = 'update'
FEATURES_HOSTNAME = 'hostname'
FEATURES_NETWORK_INFO = 'network_info'
FEATURES_NETWORK_CONTROL = 'network_control'

Expand Down Expand Up @@ -117,3 +118,7 @@ def update(self, version=None):
if version:
return self._send_command("update {}".format(version))
return self._send_command("update")

def set_hostname(self, hostname):
"""Update hostname on host."""
return self._send_command("hostname {}".format(hostname))
15 changes: 15 additions & 0 deletions hassio/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import aiohttp
import async_timeout
import pytz
import voluptuous as vol

from .const import URL_HASSIO_VERSION, URL_HASSIO_VERSION_BETA

Expand Down Expand Up @@ -90,3 +92,16 @@ def read_json_file(jsonfile):
"""Read a json file and return a dict."""
with jsonfile.open('r') as cfile:
return json.loads(cfile.read())


def validate_timezone(timezone):
"""Validate voluptuous timezone."""
try:
pytz.timezone(timezone)
except pytz.exceptions.UnknownTimeZoneError:
raise vol.Invalid(
"Invalid time zone passed in. Valid options can be found here: "
"http://en.wikipedia.org/wiki/List_of_tz_database_time_zones") \
from None

return timezone
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
'voluptuous',
'gitpython',
'pyotp',
'pyqrcode'
'pyqrcode',
'pytz'
]
)
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"hassio": "0.31",
"hassio": "0.32",
"homeassistant": "0.45",
"resinos": "0.8",
"resinhup": "0.1",
Expand Down

0 comments on commit cb2dd3b

Please sign in to comment.