Use uv instead of pip on production images (#112496)

This commit is contained in:
Robert Resch 2024-03-22 16:50:07 +01:00 committed by GitHub
parent cad3be8213
commit c282172252
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 56 additions and 24 deletions

View File

@ -95,6 +95,7 @@ jobs:
packages: write packages: write
id-token: write id-token: write
strategy: strategy:
fail-fast: false
matrix: matrix:
arch: ${{ fromJson(needs.init.outputs.architectures) }} arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps: steps:

View File

@ -6,47 +6,50 @@ FROM ${BUILD_FROM}
# Synchronize with homeassistant/core.py:async_stop # Synchronize with homeassistant/core.py:async_stop
ENV \ ENV \
S6_SERVICES_GRACETIME=240000 S6_SERVICES_GRACETIME=240000 \
UV_SYSTEM_PYTHON=true
ARG QEMU_CPU ARG QEMU_CPU
# Install uv
RUN pip3 install uv==0.1.22
WORKDIR /usr/src WORKDIR /usr/src
## Setup Home Assistant Core dependencies ## Setup Home Assistant Core dependencies
COPY requirements.txt homeassistant/ COPY requirements.txt homeassistant/
COPY homeassistant/package_constraints.txt homeassistant/homeassistant/ COPY homeassistant/package_constraints.txt homeassistant/homeassistant/
RUN \ RUN \
pip3 install \ uv pip install \
--only-binary=:all: \ --no-build \
-r homeassistant/requirements.txt -r homeassistant/requirements.txt
COPY requirements_all.txt home_assistant_frontend-* home_assistant_intents-* homeassistant/ COPY requirements_all.txt home_assistant_frontend-* home_assistant_intents-* homeassistant/
RUN \ RUN \
if ls homeassistant/home_assistant_frontend*.whl 1> /dev/null 2>&1; then \ if ls homeassistant/home_assistant_frontend*.whl 1> /dev/null 2>&1; then \
pip3 install homeassistant/home_assistant_frontend-*.whl; \ uv pip install homeassistant/home_assistant_frontend-*.whl; \
fi \ fi \
&& if ls homeassistant/home_assistant_intents*.whl 1> /dev/null 2>&1; then \ && if ls homeassistant/home_assistant_intents*.whl 1> /dev/null 2>&1; then \
pip3 install homeassistant/home_assistant_intents-*.whl; \ uv pip install homeassistant/home_assistant_intents-*.whl; \
fi \ fi \
&& if [ "${BUILD_ARCH}" = "i386" ]; then \ && if [ "${BUILD_ARCH}" = "i386" ]; then \
LD_PRELOAD="/usr/local/lib/libjemalloc.so.2" \ LD_PRELOAD="/usr/local/lib/libjemalloc.so.2" \
MALLOC_CONF="background_thread:true,metadata_thp:auto,dirty_decay_ms:20000,muzzy_decay_ms:20000" \ MALLOC_CONF="background_thread:true,metadata_thp:auto,dirty_decay_ms:20000,muzzy_decay_ms:20000" \
linux32 pip3 install \ linux32 uv pip install \
--only-binary=:all: \ --no-build \
-r homeassistant/requirements_all.txt; \ -r homeassistant/requirements_all.txt; \
else \ else \
LD_PRELOAD="/usr/local/lib/libjemalloc.so.2" \ LD_PRELOAD="/usr/local/lib/libjemalloc.so.2" \
MALLOC_CONF="background_thread:true,metadata_thp:auto,dirty_decay_ms:20000,muzzy_decay_ms:20000" \ MALLOC_CONF="background_thread:true,metadata_thp:auto,dirty_decay_ms:20000,muzzy_decay_ms:20000" \
pip3 install \ uv pip install \
--only-binary=:all: \ --no-build \
-r homeassistant/requirements_all.txt; \ -r homeassistant/requirements_all.txt; \
fi fi
## Setup Home Assistant Core ## Setup Home Assistant Core
COPY . homeassistant/ COPY . homeassistant/
RUN \ RUN \
pip3 install \ uv pip install \
--only-binary=:all: \
-e ./homeassistant \ -e ./homeassistant \
&& python3 -m compileall \ && python3 -m compileall \
homeassistant/homeassistant homeassistant/homeassistant

View File

@ -51,4 +51,4 @@ types-pytz==2023.3.1.1
types-PyYAML==6.0.12.12 types-PyYAML==6.0.12.12
types-requests==2.31.0.3 types-requests==2.31.0.3
types-xmltodict==0.13.0.3 types-xmltodict==0.13.0.3
uv==0.1.17 uv==0.1.22

View File

@ -4,6 +4,7 @@ from homeassistant import core
from homeassistant.util import executor, thread from homeassistant.util import executor, thread
from .model import Config, Integration from .model import Config, Integration
from .requirements import PACKAGE_REGEX, PIP_VERSION_RANGE_SEPARATOR
DOCKERFILE_TEMPLATE = r"""# Automatically generated by hassfest. DOCKERFILE_TEMPLATE = r"""# Automatically generated by hassfest.
# #
@ -13,47 +14,50 @@ FROM ${{BUILD_FROM}}
# Synchronize with homeassistant/core.py:async_stop # Synchronize with homeassistant/core.py:async_stop
ENV \ ENV \
S6_SERVICES_GRACETIME={timeout} S6_SERVICES_GRACETIME={timeout} \
UV_SYSTEM_PYTHON=true
ARG QEMU_CPU ARG QEMU_CPU
# Install uv
RUN pip3 install uv=={uv_version}
WORKDIR /usr/src WORKDIR /usr/src
## Setup Home Assistant Core dependencies ## Setup Home Assistant Core dependencies
COPY requirements.txt homeassistant/ COPY requirements.txt homeassistant/
COPY homeassistant/package_constraints.txt homeassistant/homeassistant/ COPY homeassistant/package_constraints.txt homeassistant/homeassistant/
RUN \ RUN \
pip3 install \ uv pip install \
--only-binary=:all: \ --no-build \
-r homeassistant/requirements.txt -r homeassistant/requirements.txt
COPY requirements_all.txt home_assistant_frontend-* home_assistant_intents-* homeassistant/ COPY requirements_all.txt home_assistant_frontend-* home_assistant_intents-* homeassistant/
RUN \ RUN \
if ls homeassistant/home_assistant_frontend*.whl 1> /dev/null 2>&1; then \ if ls homeassistant/home_assistant_frontend*.whl 1> /dev/null 2>&1; then \
pip3 install homeassistant/home_assistant_frontend-*.whl; \ uv pip install homeassistant/home_assistant_frontend-*.whl; \
fi \ fi \
&& if ls homeassistant/home_assistant_intents*.whl 1> /dev/null 2>&1; then \ && if ls homeassistant/home_assistant_intents*.whl 1> /dev/null 2>&1; then \
pip3 install homeassistant/home_assistant_intents-*.whl; \ uv pip install homeassistant/home_assistant_intents-*.whl; \
fi \ fi \
&& if [ "${{BUILD_ARCH}}" = "i386" ]; then \ && if [ "${{BUILD_ARCH}}" = "i386" ]; then \
LD_PRELOAD="/usr/local/lib/libjemalloc.so.2" \ LD_PRELOAD="/usr/local/lib/libjemalloc.so.2" \
MALLOC_CONF="background_thread:true,metadata_thp:auto,dirty_decay_ms:20000,muzzy_decay_ms:20000" \ MALLOC_CONF="background_thread:true,metadata_thp:auto,dirty_decay_ms:20000,muzzy_decay_ms:20000" \
linux32 pip3 install \ linux32 uv pip install \
--only-binary=:all: \ --no-build \
-r homeassistant/requirements_all.txt; \ -r homeassistant/requirements_all.txt; \
else \ else \
LD_PRELOAD="/usr/local/lib/libjemalloc.so.2" \ LD_PRELOAD="/usr/local/lib/libjemalloc.so.2" \
MALLOC_CONF="background_thread:true,metadata_thp:auto,dirty_decay_ms:20000,muzzy_decay_ms:20000" \ MALLOC_CONF="background_thread:true,metadata_thp:auto,dirty_decay_ms:20000,muzzy_decay_ms:20000" \
pip3 install \ uv pip install \
--only-binary=:all: \ --no-build \
-r homeassistant/requirements_all.txt; \ -r homeassistant/requirements_all.txt; \
fi fi
## Setup Home Assistant Core ## Setup Home Assistant Core
COPY . homeassistant/ COPY . homeassistant/
RUN \ RUN \
pip3 install \ uv pip install \
--only-binary=:all: \
-e ./homeassistant \ -e ./homeassistant \
&& python3 -m compileall \ && python3 -m compileall \
homeassistant/homeassistant homeassistant/homeassistant
@ -65,6 +69,28 @@ WORKDIR /config
""" """
def _get_uv_version() -> str:
with open("requirements_test.txt") as fp:
for _, line in enumerate(fp):
if match := PACKAGE_REGEX.match(line):
pkg, sep, version = match.groups()
if pkg != "uv":
continue
if sep != "==" or not version:
raise RuntimeError(
'Requirement uv need to be pinned "uv==<version>".'
)
for part in version.split(";", 1)[0].split(","):
version_part = PIP_VERSION_RANGE_SEPARATOR.match(part)
if version_part:
return version_part.group(2)
raise RuntimeError("Invalid uv requirement in requirements_test.txt")
def _generate_dockerfile() -> str: def _generate_dockerfile() -> str:
timeout = ( timeout = (
core.STOPPING_STAGE_SHUTDOWN_TIMEOUT core.STOPPING_STAGE_SHUTDOWN_TIMEOUT
@ -75,7 +101,9 @@ def _generate_dockerfile() -> str:
+ thread.THREADING_SHUTDOWN_TIMEOUT + thread.THREADING_SHUTDOWN_TIMEOUT
+ 10 + 10
) )
return DOCKERFILE_TEMPLATE.format(timeout=timeout * 1000) return DOCKERFILE_TEMPLATE.format(
timeout=timeout * 1000, uv_version=_get_uv_version()
)
def validate(integrations: dict[str, Integration], config: Config) -> None: def validate(integrations: dict[str, Integration], config: Config) -> None: