Skip to content
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

Autogenerate Dockerfile #104669

Merged
merged 1 commit into from
Nov 29, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Automatically generated by hassfest.
#
# To update, run python3 -m script.hassfest -p docker
ARG BUILD_FROM
FROM ${BUILD_FROM}

Expand Down
2 changes: 2 additions & 0 deletions script/hassfest/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
coverage,
dependencies,
dhcp,
docker,
json,
manifest,
metadata,
Expand Down Expand Up @@ -50,6 +51,7 @@
]
HASS_PLUGINS = [
coverage,
docker,
mypy_config,
metadata,
]
Expand Down
89 changes: 89 additions & 0 deletions script/hassfest/docker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"""Generate and validate the dockerfile."""
from homeassistant import core
from homeassistant.util import executor, thread

from .model import Config, Integration

DOCKERFILE_TEMPLATE = """# Automatically generated by hassfest.
#
# To update, run python3 -m script.hassfest -p docker
ARG BUILD_FROM
FROM ${{BUILD_FROM}}

# Synchronize with homeassistant/core.py:async_stop
ENV \\
S6_SERVICES_GRACETIME={timeout}

ARG QEMU_CPU

WORKDIR /usr/src

## Setup Home Assistant Core dependencies
COPY requirements.txt homeassistant/
COPY homeassistant/package_constraints.txt homeassistant/homeassistant/
RUN \\
pip3 install \\
--only-binary=:all: \\
-r homeassistant/requirements.txt

COPY requirements_all.txt home_assistant_frontend-* home_assistant_intents-* homeassistant/
RUN \\
if ls homeassistant/home_assistant_frontend*.whl 1> /dev/null 2>&1; then \\
pip3 install homeassistant/home_assistant_frontend-*.whl; \\
fi \\
&& if ls homeassistant/home_assistant_intents*.whl 1> /dev/null 2>&1; then \\
pip3 install homeassistant/home_assistant_intents-*.whl; \\
fi \\
&& \\
LD_PRELOAD="/usr/local/lib/libjemalloc.so.2" \\
MALLOC_CONF="background_thread:true,metadata_thp:auto,dirty_decay_ms:20000,muzzy_decay_ms:20000" \\
pip3 install \\
--only-binary=:all: \\
-r homeassistant/requirements_all.txt

## Setup Home Assistant Core
COPY . homeassistant/
RUN \\
pip3 install \\
--only-binary=:all: \\
-e ./homeassistant \\
&& python3 -m compileall \\
homeassistant/homeassistant

# Home Assistant S6-Overlay
COPY rootfs /

WORKDIR /config
"""


def _generate_dockerfile() -> str:
timeout = (
core.STAGE_1_SHUTDOWN_TIMEOUT
+ core.STAGE_2_SHUTDOWN_TIMEOUT
+ core.STAGE_3_SHUTDOWN_TIMEOUT
+ executor.EXECUTOR_SHUTDOWN_TIMEOUT
+ thread.THREADING_SHUTDOWN_TIMEOUT
+ 10
)
return DOCKERFILE_TEMPLATE.format(timeout=timeout * 1000)


def validate(integrations: dict[str, Integration], config: Config) -> None:
"""Validate dockerfile."""
dockerfile_content = _generate_dockerfile()
config.cache["dockerfile"] = dockerfile_content

dockerfile_path = config.root / "Dockerfile"
if dockerfile_path.read_text() != dockerfile_content:
config.add_error(
"docker",
"File Dockerfile is not up to date. Run python3 -m script.hassfest",
fixable=True,
)


def generate(integrations: dict[str, Integration], config: Config) -> None:
"""Generate dockerfile."""
dockerfile_path = config.root / "Dockerfile"
dockerfile_path.write_text(config.cache["dockerfile"])