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

Make UV_HTTP_TIMEOUT default value bigger in WSL2 environment #38742

Merged
merged 2 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions dev/breeze/src/airflow_breeze/global_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
PIP_VERSION = "24.0"

DEFAULT_UV_HTTP_TIMEOUT = 300
DEFAULT_WSL2_HTTP_TIMEOUT = 900

# packages that providers docs
REGULAR_DOC_PACKAGES = [
Expand Down
5 changes: 4 additions & 1 deletion dev/breeze/src/airflow_breeze/params/build_ci_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ def prepare_arguments_for_docker_build_command(self) -> list[str]:
self._req_arg("AIRFLOW_IMAGE_REPOSITORY", self.airflow_image_repository)
self._req_arg("AIRFLOW_PRE_CACHED_PIP_PACKAGES", self.airflow_pre_cached_pip_packages)
self._req_arg("AIRFLOW_USE_UV", self.use_uv)
self._opt_arg("UV_HTTP_TIMEOUT", self.uv_http_timeout)
if self.use_uv:
from airflow_breeze.utils.uv_utils import get_uv_timeout

self._opt_arg("UV_HTTP_TIMEOUT", get_uv_timeout(self))
self._req_arg("AIRFLOW_VERSION", self.airflow_version)
self._req_arg("BUILD_ID", self.build_id)
self._req_arg("CONSTRAINTS_GITHUB_REPOSITORY", self.constraints_github_repository)
Expand Down
5 changes: 4 additions & 1 deletion dev/breeze/src/airflow_breeze/params/build_prod_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,10 @@ def prepare_arguments_for_docker_build_command(self) -> list[str]:
self._req_arg("AIRFLOW_IMAGE_REPOSITORY", self.airflow_image_repository)
self._req_arg("AIRFLOW_PRE_CACHED_PIP_PACKAGES", self.airflow_pre_cached_pip_packages)
self._opt_arg("AIRFLOW_USE_UV", self.use_uv)
self._opt_arg("UV_HTTP_TIMEOUT", self.uv_http_timeout)
if self.use_uv:
from airflow_breeze.utils.uv_utils import get_uv_timeout

self._req_arg("UV_HTTP_TIMEOUT", get_uv_timeout(self))
self._req_arg("AIRFLOW_VERSION", self.airflow_version)
self._req_arg("BUILD_ID", self.build_id)
self._req_arg("CONSTRAINTS_GITHUB_REPOSITORY", self.constraints_github_repository)
Expand Down
59 changes: 59 additions & 0 deletions dev/breeze/src/airflow_breeze/utils/platforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,69 @@
# under the License.
from __future__ import annotations

import platform
import sys
from pathlib import Path


def get_real_platform(single_platform: str) -> str:
"""
Replace different platform variants of the platform provided platforms with the two canonical ones we
are using: amd64 and arm64.
"""
return single_platform.replace("x86_64", "amd64").replace("aarch64", "arm64").replace("/", "-")


def _exists_no_permission_error(p: str) -> bool:
try:
return Path(p).exists()
except PermissionError:
return False


def message_on_wsl1_detected(release_name: str | None, kernel_version: tuple[int, ...] | None):
from airflow_breeze.utils.console import get_console

get_console().print("[error]You are running WSL1 - Breeze requires WSL2! Quitting.\n")
get_console().print("[warning]It can also be that our detection mechanism is wrong:[/]\n\n")
if release_name:
get_console().print(f"[info]We based our WSL1 detection on the release name: `{release_name}`\n")
elif kernel_version:
get_console().print(f"[info]We based our WSL1 detection on the kernel version: `{kernel_version}`\n")
get_console().print(
"[info]If you are running WSL2, please report this issue to the maintainers\n"
"of Airflow, so we can improve the detection mechanism.\n"
"You can also try to run the command with `--uv-http-timeout 900` or "
"`--no-use-uv` flag to skip the WSL1 check.\n"
)


def is_wsl2() -> bool:
"""
Check if the current platform is WSL
:return: True if the current platform is WSL
"""
release_name = platform.uname().release
potiuk marked this conversation as resolved.
Show resolved Hide resolved
has_wsl_interop = _exists_no_permission_error("/proc/sys/fs/binfmt_misc/WSLInterop")
microsoft_in_release = "microsoft" in release_name.lower()
wsl_conf = _exists_no_permission_error("/etc/wsl.conf")
if not has_wsl_interop and not microsoft_in_release and not wsl_conf:
return False
if microsoft_in_release:
# Release name WSL1 detection
if "Microsoft" in release_name:
message_on_wsl1_detected(release_name=release_name, kernel_version=None)
sys.exit(1)
return True

# Kernel WSL1 detection
kernel_version: tuple[int, ...] = (0, 0)
if len(parts := release_name.split(".", 2)[:2]) == 2:
try:
kernel_version = tuple(map(int, parts))
except (TypeError, ValueError):
pass
if kernel_version < (4, 19):
message_on_wsl1_detected(release_name=None, kernel_version=kernel_version)
sys.exit(1)
return True
43 changes: 43 additions & 0 deletions dev/breeze/src/airflow_breeze/utils/uv_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from __future__ import annotations

from typing import TYPE_CHECKING

from airflow_breeze.global_constants import DEFAULT_UV_HTTP_TIMEOUT, DEFAULT_WSL2_HTTP_TIMEOUT

if TYPE_CHECKING:
from airflow_breeze.params.common_build_params import CommonBuildParams
from airflow_breeze.utils.platforms import is_wsl2


def get_uv_timeout(build_params: CommonBuildParams) -> int:
"""
Get the timeout for the uvicorn server. We do not want to change the default value to not slow down
the --help and command line in general and also it might be useful to give escape hatch in case our
WSL1 detection is wrong (it will fail default --use-uv build, but you will be able to skip the check by
manually specifying --uv-http-timeout or --no-use-uv). So we only check for wsl2 when default value is
used and when uv is enabled.
"""

if build_params.uv_http_timeout != DEFAULT_UV_HTTP_TIMEOUT:
# a bit of hack: if you specify 300 in command line it will also be overridden in case of WSL2
# but this is a corner case
return build_params.uv_http_timeout
if is_wsl2():
return DEFAULT_WSL2_HTTP_TIMEOUT
return build_params.uv_http_timeout
Loading