mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-06-24 19:06:29 +00:00
Change handling with host files (#1223)
This commit is contained in:
parent
734fe3afde
commit
a2cf7ece70
@ -10,6 +10,7 @@ from ..coresys import CoreSys, CoreSysAttributes
|
||||
from ..exceptions import (
|
||||
AddonsError,
|
||||
AddonsNotSupportedError,
|
||||
CoreDNSError,
|
||||
DockerAPIError,
|
||||
HomeAssistantAPIError,
|
||||
HostAppArmorError,
|
||||
@ -74,6 +75,9 @@ class AddonManager(CoreSysAttributes):
|
||||
if tasks:
|
||||
await asyncio.wait(tasks)
|
||||
|
||||
# Sync DNS
|
||||
await self.sync_dns()
|
||||
|
||||
async def boot(self, stage: str) -> None:
|
||||
"""Boot add-ons with mode auto."""
|
||||
tasks = []
|
||||
@ -299,3 +303,17 @@ class AddonManager(CoreSysAttributes):
|
||||
_LOGGER.error("Can't repair %s", addon.slug)
|
||||
with suppress(AddonsError):
|
||||
await self.uninstall(addon.slug)
|
||||
|
||||
async def sync_dns(self) -> None:
|
||||
"""Sync add-ons DNS names."""
|
||||
# Update hosts
|
||||
for addon in self.installed:
|
||||
if not await addon.is_running():
|
||||
continue
|
||||
self.sys_dns.add_host(
|
||||
ipv4=addon.ip_address, names=[addon.hostname], write=False
|
||||
)
|
||||
|
||||
# Write hosts files
|
||||
with suppress(CoreDNSError):
|
||||
self.sys_dns.write_hosts()
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""Init file for Hass.io add-ons."""
|
||||
from contextlib import suppress
|
||||
from copy import deepcopy
|
||||
from ipaddress import IPv4Address, ip_address
|
||||
from ipaddress import IPv4Address
|
||||
import logging
|
||||
from pathlib import Path, PurePath
|
||||
import re
|
||||
@ -81,8 +81,6 @@ class Addon(AddonModel):
|
||||
@property
|
||||
def ip_address(self) -> IPv4Address:
|
||||
"""Return IP of Add-on instance."""
|
||||
if not self.is_installed:
|
||||
return ip_address("0.0.0.0")
|
||||
return self.instance.ip_address
|
||||
|
||||
@property
|
||||
|
@ -2,7 +2,7 @@
|
||||
import asyncio
|
||||
import logging
|
||||
from contextlib import suppress
|
||||
from ipaddress import IPv4Address, AddressValueError
|
||||
from ipaddress import IPv4Address
|
||||
from pathlib import Path
|
||||
from string import Template
|
||||
from typing import Awaitable, Dict, List, Optional
|
||||
@ -81,8 +81,7 @@ class CoreDNS(JsonConfig, CoreSysAttributes):
|
||||
|
||||
async def load(self) -> None:
|
||||
"""Load DNS setup."""
|
||||
with suppress(CoreDNSError):
|
||||
self._import_hosts()
|
||||
self._init_hosts()
|
||||
|
||||
# Check CoreDNS state
|
||||
try:
|
||||
@ -181,13 +180,15 @@ class CoreDNS(JsonConfig, CoreSysAttributes):
|
||||
_LOGGER.error("Can't start CoreDNS plugin")
|
||||
raise CoreDNSError() from None
|
||||
|
||||
def reset(self) -> None:
|
||||
async def reset(self) -> None:
|
||||
"""Reset Config / Hosts."""
|
||||
self.servers = DNS_SERVERS
|
||||
|
||||
with suppress(OSError):
|
||||
self.hosts.unlink()
|
||||
self._import_hosts()
|
||||
self._init_hosts()
|
||||
|
||||
await self.sys_addons.sync_dns()
|
||||
|
||||
def _write_corefile(self) -> None:
|
||||
"""Write CoreDNS config."""
|
||||
@ -207,43 +208,34 @@ class CoreDNS(JsonConfig, CoreSysAttributes):
|
||||
_LOGGER.error("Can't update corefile: %s", err)
|
||||
raise CoreDNSError() from None
|
||||
|
||||
def _import_hosts(self) -> None:
|
||||
def _init_hosts(self) -> None:
|
||||
"""Import hosts entry."""
|
||||
# Generate Default
|
||||
if not self.hosts.exists():
|
||||
self.add_host(self.sys_docker.network.supervisor, ["hassio", "supervisor"])
|
||||
self.add_host(
|
||||
self.sys_docker.network.gateway, ["homeassistant", "home-assistant"]
|
||||
)
|
||||
return
|
||||
self.add_host(
|
||||
self.sys_docker.network.supervisor, ["hassio", "supervisor"], write=False
|
||||
)
|
||||
self.add_host(
|
||||
self.sys_docker.network.gateway,
|
||||
["homeassistant", "home-assistant"],
|
||||
write=False,
|
||||
)
|
||||
|
||||
# Import Exists host table
|
||||
try:
|
||||
with self.hosts.open("r") as hosts:
|
||||
for line in hosts.readlines():
|
||||
try:
|
||||
data = line.split(" ")
|
||||
self._hosts[IPv4Address(data[0])] = data[1:]
|
||||
except AddressValueError:
|
||||
_LOGGER.warning("Fails to read %s", line)
|
||||
|
||||
except OSError as err:
|
||||
_LOGGER.error("Can't read hosts file: %s", err)
|
||||
raise CoreDNSError() from None
|
||||
|
||||
def _write_hosts(self) -> None:
|
||||
def write_hosts(self) -> None:
|
||||
"""Write hosts from memory to file."""
|
||||
try:
|
||||
with self.hosts.open("w") as hosts:
|
||||
for address, hostnames in self._hosts.items():
|
||||
host = " ".join(hostnames)
|
||||
hosts.write(f"{address!s} {host}")
|
||||
hosts.write(f"{address!s} {host}\n")
|
||||
except OSError as err:
|
||||
_LOGGER.error("Can't write hosts file: %s", err)
|
||||
raise CoreDNSError() from None
|
||||
|
||||
def add_host(self, ipv4: IPv4Address, names: List[str]) -> None:
|
||||
def add_host(self, ipv4: IPv4Address, names: List[str], write: bool = True) -> None:
|
||||
"""Add a new host entry."""
|
||||
if not ipv4 or ipv4 == IPv4Address("0.0.0.0"):
|
||||
return
|
||||
|
||||
hostnames: List[str] = []
|
||||
for name in names:
|
||||
hostnames.append(name)
|
||||
@ -252,10 +244,14 @@ class CoreDNS(JsonConfig, CoreSysAttributes):
|
||||
self._hosts[ipv4] = hostnames
|
||||
_LOGGER.debug("Add Host entry %s -> %s", ipv4, hostnames)
|
||||
|
||||
self._write_hosts()
|
||||
if write:
|
||||
self.write_hosts()
|
||||
|
||||
def delete_host(
|
||||
self, ipv4: Optional[IPv4Address] = None, host: Optional[str] = None
|
||||
self,
|
||||
ipv4: Optional[IPv4Address] = None,
|
||||
host: Optional[str] = None,
|
||||
write: bool = True,
|
||||
) -> None:
|
||||
"""Remove a entry from hosts."""
|
||||
if host:
|
||||
@ -270,7 +266,8 @@ class CoreDNS(JsonConfig, CoreSysAttributes):
|
||||
_LOGGER.debug("Remove Host entry %s", ipv4)
|
||||
self._hosts.pop(ipv4, None)
|
||||
|
||||
self._write_hosts()
|
||||
if write:
|
||||
self.write_hosts()
|
||||
else:
|
||||
_LOGGER.warning("Can't remove Host entry: %s/%s", ipv4, host)
|
||||
|
||||
@ -336,7 +333,7 @@ class CoreDNS(JsonConfig, CoreSysAttributes):
|
||||
try:
|
||||
with RESOLV_CONF.open("w") as resolv:
|
||||
for line in resolv_lines:
|
||||
resolv.write(line)
|
||||
resolv.write(f"{line}\n")
|
||||
except OSError as err:
|
||||
_LOGGER.error("Can't write local resolv: %s", err)
|
||||
raise CoreDNSError() from None
|
||||
|
@ -228,7 +228,7 @@ class Tasks(CoreSysAttributes):
|
||||
|
||||
if await self.sys_dns.is_fails():
|
||||
_LOGGER.warning("CoreDNS plugin is in fails state / Reset config")
|
||||
self.sys_dns.reset()
|
||||
await self.sys_dns.reset()
|
||||
|
||||
try:
|
||||
await self.sys_dns.start()
|
||||
|
Loading…
x
Reference in New Issue
Block a user