Skip to content

Atomic writes, chmod and more logging #162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion hass_nabucasa/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ def write_user_info(self) -> None:
if not base_path.exists():
base_path.mkdir()

with atomic_write(str(self.user_info_path), overwrite=True) as fp:
with atomic_write(self.user_info_path, overwrite=True) as fp:
fp.write(
json.dumps(
{
Expand All @@ -210,6 +210,7 @@ def write_user_info(self) -> None:
indent=4,
)
)
self.user_info_path.chmod(0o600)

async def start(self):
"""Start the cloud component."""
Expand Down
14 changes: 10 additions & 4 deletions hass_nabucasa/acme.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import OpenSSL
from acme import challenges, client, crypto_util, errors, messages
import async_timeout
from atomicwrites import atomic_write
import attr
from cryptography import x509
from cryptography.hazmat.backends import default_backend
Expand Down Expand Up @@ -280,7 +281,8 @@ def _finish_challenge(self, handler: ChallengeHandler) -> None:
else:
_LOGGER.info("Create new certificate: %s", self.path_fullchain)

self.path_fullchain.write_text(order.fullchain_pem)
with atomic_write(self.path_fullchain, overwrite=True) as fp:
fp.write(order.fullchain_pem)
self.path_fullchain.chmod(0o600)

async def load_certificate(self) -> None:
Expand Down Expand Up @@ -368,9 +370,13 @@ async def issue_certificate(self) -> None:
await self.cloud.run_executor(self._finish_challenge, challenge)
await self.load_certificate()
finally:
await cloud_api.async_remote_challenge_cleanup(
self.cloud, challenge.validation
)
try:
async with async_timeout.timeout(30):
await cloud_api.async_remote_challenge_cleanup(
self.cloud, challenge.validation
)
except asyncio.TimeoutError:
_LOGGER.error("Failed to clean up challenge from NabuCasa DNS!")

async def reset_acme(self) -> None:
"""Revoke and deactivate acme certificate/account."""
Expand Down
7 changes: 7 additions & 0 deletions hass_nabucasa/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,14 @@ async def _finish_load_backend(self) -> None:

await self._acme.hardening_files()

_LOGGER.debug("Waiting for aiohttp runner to come available")

# aiohttp_runner comes available when Home Assistant has started.
while self.cloud.client.aiohttp_runner is None:
await asyncio.sleep(1)

# Setup snitun / aiohttp wrapper
_LOGGER.debug("Initializing remote backend")
context = await self._create_context()
self._snitun = SniTunClientAioHttp(
self.cloud.client.aiohttp_runner,
Expand All @@ -188,9 +191,13 @@ async def _finish_load_backend(self) -> None:
snitun_port=443,
)

_LOGGER.debug("Starting remote backend")
await self._snitun.start()
self.cloud.client.dispatcher_message(const.DISPATCH_REMOTE_BACKEND_UP)

_LOGGER.debug(
"Connecting remote backend: %s", self.cloud.client.remote_autostart
)
# Connect to remote is autostart enabled
if self.cloud.client.remote_autostart:
self.cloud.run_task(self.connect())
Expand Down
2 changes: 1 addition & 1 deletion tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def test_write_user_info(cloud_client):
cl.access_token = "test-access-token"
cl.refresh_token = "test-refresh-token"

with patch("hass_nabucasa.atomic_write",) as mock_write:
with patch("pathlib.Path.chmod"), patch("hass_nabucasa.atomic_write") as mock_write:
cl.write_user_info()

mock_file = mock_write.return_value.__enter__.return_value
Expand Down