mirror of https://github.com/mongodb/mongo
SERVER-99469 fallback to normal bazel call on wrapper script failure (#31245)
GitOrigin-RevId: 7da7cf364cb2b63c2895754cd93265fb4f88fc2b
This commit is contained in:
parent
dd87ed82e3
commit
f35b4b0c19
|
|
@ -1,5 +1,6 @@
|
||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
|
import platform
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -38,30 +39,38 @@ class DuplicateSourceNames(Exception):
|
||||||
wrapper_debug(f"wrapper hook script is using {sys.executable}")
|
wrapper_debug(f"wrapper hook script is using {sys.executable}")
|
||||||
|
|
||||||
|
|
||||||
def search_for_modules(deps, deps_installed, deps_needed, lockfile_changed=False):
|
def get_deps_dirs(deps):
|
||||||
bazel_out_dir = os.path.join(REPO_ROOT, "bazel-out")
|
bazel_out_dir = os.path.join(REPO_ROOT, "bazel-out")
|
||||||
if os.path.exists(bazel_out_dir):
|
bazel_bin = os.path.join(REPO_ROOT, "bazel-bin")
|
||||||
for dep in deps:
|
for dep in deps:
|
||||||
found = False
|
for child in os.listdir(bazel_out_dir):
|
||||||
for entry in os.listdir(bazel_out_dir):
|
yield f"{bazel_out_dir}/{child}/bin/external/poetry/{dep}", dep
|
||||||
if os.path.exists(f"{bazel_out_dir}/{entry}/bin/external/poetry/{dep}"):
|
yield f"{bazel_bin}/bin/external/poetry/{dep}", dep
|
||||||
if not lockfile_changed:
|
|
||||||
deps_installed.append(dep)
|
|
||||||
sys.path.append(f"{bazel_out_dir}/{entry}/bin/external/poetry/{dep}")
|
def search_for_modules(deps, deps_installed, lockfile_changed=False):
|
||||||
found = True
|
deps_not_found = deps.copy()
|
||||||
break
|
for target_dir, dep in get_deps_dirs(deps):
|
||||||
else:
|
if dep in deps_installed:
|
||||||
os.chmod(f"{bazel_out_dir}/{entry}/bin/external/poetry/{dep}", 0o777)
|
continue
|
||||||
for root, dirs, files in os.walk(
|
|
||||||
f"{bazel_out_dir}/{entry}/bin/external/poetry/{dep}"
|
if not os.path.exists(target_dir):
|
||||||
):
|
continue
|
||||||
for somedir in dirs:
|
|
||||||
os.chmod(os.path.join(root, somedir), 0o777)
|
if not lockfile_changed:
|
||||||
for file in files:
|
deps_installed.append(dep)
|
||||||
os.chmod(os.path.join(root, file), 0o777)
|
deps_not_found.remove(dep)
|
||||||
shutil.rmtree(f"{bazel_out_dir}/{entry}/bin/external/poetry/{dep}")
|
sys.path.append(target_dir)
|
||||||
if not found:
|
else:
|
||||||
deps_needed.append(dep)
|
os.chmod(target_dir, 0o777)
|
||||||
|
for root, dirs, files in os.walk(target_dir):
|
||||||
|
for somedir in dirs:
|
||||||
|
os.chmod(os.path.join(root, somedir), 0o777)
|
||||||
|
for file in files:
|
||||||
|
os.chmod(os.path.join(root, file), 0o777)
|
||||||
|
shutil.rmtree(target_dir)
|
||||||
|
|
||||||
|
return deps_not_found
|
||||||
|
|
||||||
|
|
||||||
def install_modules(bazel):
|
def install_modules(bazel):
|
||||||
|
|
@ -81,8 +90,9 @@ def install_modules(bazel):
|
||||||
|
|
||||||
deps = ["retry"]
|
deps = ["retry"]
|
||||||
deps_installed = []
|
deps_installed = []
|
||||||
deps_needed = []
|
deps_needed = search_for_modules(
|
||||||
search_for_modules(deps, deps_installed, deps_needed, lockfile_changed=old_hash != current_hash)
|
deps, deps_installed, lockfile_changed=old_hash != current_hash
|
||||||
|
)
|
||||||
|
|
||||||
if deps_needed:
|
if deps_needed:
|
||||||
need_to_install = True
|
need_to_install = True
|
||||||
|
|
@ -95,8 +105,7 @@ def install_modules(bazel):
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
[bazel, "build", "--config=local"] + ["@poetry//:install_" + dep for dep in deps_needed]
|
[bazel, "build", "--config=local"] + ["@poetry//:install_" + dep for dep in deps_needed]
|
||||||
)
|
)
|
||||||
deps_missing = []
|
deps_missing = search_for_modules(deps_needed, deps_installed)
|
||||||
search_for_modules(deps_needed, deps_installed, deps_missing)
|
|
||||||
if deps_missing:
|
if deps_missing:
|
||||||
raise Exception(f"Failed to install python deps {deps_missing}")
|
raise Exception(f"Failed to install python deps {deps_missing}")
|
||||||
|
|
||||||
|
|
@ -104,9 +113,10 @@ def install_modules(bazel):
|
||||||
def get_buildozer_output(autocomplete_query):
|
def get_buildozer_output(autocomplete_query):
|
||||||
from buildscripts.install_bazel import install_bazel
|
from buildscripts.install_bazel import install_bazel
|
||||||
|
|
||||||
buildozer = shutil.which("buildozer")
|
buildozer_name = "buildozer" if not platform.system() == "Windows" else "buildozer.exe"
|
||||||
|
buildozer = shutil.which(buildozer_name)
|
||||||
if not buildozer:
|
if not buildozer:
|
||||||
buildozer = os.path.expanduser("~/.local/bin/buildozer")
|
buildozer = os.path.expanduser(f"~/.local/bin/{buildozer_name}")
|
||||||
if not os.path.exists(buildozer):
|
if not os.path.exists(buildozer):
|
||||||
bazel_bin_dir = os.path.expanduser("~/.local/bin")
|
bazel_bin_dir = os.path.expanduser("~/.local/bin")
|
||||||
if not os.path.exists(bazel_bin_dir):
|
if not os.path.exists(bazel_bin_dir):
|
||||||
|
|
|
||||||
|
|
@ -412,13 +412,16 @@ def bazel_server_timeout_dumper(jvm_out, proc_pid, project_root):
|
||||||
|
|
||||||
def bazel_build_subproc_func(**kwargs):
|
def bazel_build_subproc_func(**kwargs):
|
||||||
project_root = os.path.abspath(".")
|
project_root = os.path.abspath(".")
|
||||||
output_base = subprocess.run(
|
try:
|
||||||
[Globals.bazel_executable, "info", "output_base"],
|
output_base = subprocess.run(
|
||||||
capture_output=True,
|
[Globals.bazel_executable, "info", "output_base"],
|
||||||
text=True,
|
capture_output=True,
|
||||||
check=True,
|
text=True,
|
||||||
env=kwargs["env"],
|
check=True,
|
||||||
).stdout.strip()
|
env=kwargs["env"],
|
||||||
|
).stdout.strip()
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
output_base = None
|
||||||
|
|
||||||
if os.environ.get("CI"):
|
if os.environ.get("CI"):
|
||||||
if os.path.exists(".bazel_real"):
|
if os.path.exists(".bazel_real"):
|
||||||
|
|
@ -429,14 +432,15 @@ def bazel_build_subproc_func(**kwargs):
|
||||||
|
|
||||||
bazel_proc = subprocess.Popen(**kwargs)
|
bazel_proc = subprocess.Popen(**kwargs)
|
||||||
|
|
||||||
t = threading.Thread(
|
if output_base:
|
||||||
target=bazel_server_timeout_dumper,
|
t = threading.Thread(
|
||||||
args=(jvm_out, bazel_proc.pid, project_root),
|
target=bazel_server_timeout_dumper,
|
||||||
)
|
args=(jvm_out, bazel_proc.pid, project_root),
|
||||||
|
)
|
||||||
|
|
||||||
# the bazel calls are wrapped in retries so we can rely on them to restart the attempt.
|
# the bazel calls are wrapped in retries so we can rely on them to restart the attempt.
|
||||||
t.daemon = True
|
t.daemon = True
|
||||||
t.start()
|
t.start()
|
||||||
|
|
||||||
return bazel_proc
|
return bazel_proc
|
||||||
|
|
||||||
|
|
@ -537,6 +541,17 @@ def perform_non_tty_bazel_build(bazel_cmd: str) -> None:
|
||||||
|
|
||||||
|
|
||||||
def run_bazel_command(env, bazel_cmd, tries_so_far=0):
|
def run_bazel_command(env, bazel_cmd, tries_so_far=0):
|
||||||
|
try:
|
||||||
|
server_pid = subprocess.run(
|
||||||
|
[Globals.bazel_executable, "info", "server_pid"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=True,
|
||||||
|
env={**os.environ.copy(), **Globals.bazel_env_variables},
|
||||||
|
).stdout.strip()
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
server_pid = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tty_import_fail = False
|
tty_import_fail = False
|
||||||
try:
|
try:
|
||||||
|
|
@ -565,13 +580,21 @@ def run_bazel_command(env, bazel_cmd, tries_so_far=0):
|
||||||
print(
|
print(
|
||||||
"Killing Bazel between retries on Windows to work around file access deadlock"
|
"Killing Bazel between retries on Windows to work around file access deadlock"
|
||||||
)
|
)
|
||||||
subprocess.run(
|
try:
|
||||||
[os.path.abspath(Globals.bazel_executable), "shutdown"],
|
subprocess.run(
|
||||||
check=True,
|
[os.path.abspath(Globals.bazel_executable), "shutdown"],
|
||||||
stdout=subprocess.PIPE,
|
check=True,
|
||||||
stderr=subprocess.STDOUT,
|
stdout=subprocess.PIPE,
|
||||||
env={**os.environ.copy(), **Globals.bazel_env_variables},
|
stderr=subprocess.STDOUT,
|
||||||
)
|
env={**os.environ.copy(), **Globals.bazel_env_variables},
|
||||||
|
)
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
proc = psutil.Process(server_pid)
|
||||||
|
if proc.is_running():
|
||||||
|
proc.terminate()
|
||||||
|
proc.wait(timeout=10)
|
||||||
|
proc.kill()
|
||||||
|
|
||||||
linker_jobs = 4
|
linker_jobs = 4
|
||||||
sanitizers = env.GetOption("sanitize")
|
sanitizers = env.GetOption("sanitize")
|
||||||
if sanitizers is not None and "fuzzer" in sanitizers.split(","):
|
if sanitizers is not None and "fuzzer" in sanitizers.split(","):
|
||||||
|
|
|
||||||
15
tools/bazel
15
tools/bazel
|
|
@ -1,7 +1,5 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Whenever Bazel is invoked, it first calls this script setting "BAZEL_REAL" to the path of the real Bazel binary.
|
# Whenever Bazel is invoked, it first calls this script setting "BAZEL_REAL" to the path of the real Bazel binary.
|
||||||
# Use this file as a wrapper for any logic that should run before bazel itself is executed.
|
# Use this file as a wrapper for any logic that should run before bazel itself is executed.
|
||||||
|
|
||||||
|
|
@ -76,14 +74,12 @@ if [[ $MONGO_BAZEL_WRAPPER_DEBUG == 1 ]]; then
|
||||||
wrapper_start_time="$(date -u +%s.%N)"
|
wrapper_start_time="$(date -u +%s.%N)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [[ "$OSTYPE" == "linux"* ]]; then
|
if [[ "$OSTYPE" == "linux"* ]]; then
|
||||||
os="linux"
|
os="linux"
|
||||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
os="macos"
|
os="macos"
|
||||||
else
|
else
|
||||||
echo "Unsupported OS $OSTYPE"
|
os="unknown"
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ARCH=$(uname -m)
|
ARCH=$(uname -m)
|
||||||
|
|
@ -119,6 +115,10 @@ python="$REPO_ROOT/bazel-$cur_dir/external/py_${os}_${ARCH}/dist/bin/python3"
|
||||||
if [ ! -f $python ]; then
|
if [ ! -f $python ]; then
|
||||||
>&2 echo "python prereq missing, using bazel to install python..."
|
>&2 echo "python prereq missing, using bazel to install python..."
|
||||||
>&2 $bazel_real build --config=local @py_${os}_${ARCH}//:all
|
>&2 $bazel_real build --config=local @py_${os}_${ARCH}//:all
|
||||||
|
if [[ $? != 0 ]]; then
|
||||||
|
>&2 echo "wrapper script failed to install python! falling back to normal bazel call..."
|
||||||
|
exec "$bazel_real" $@
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
autocomplete_query=0
|
autocomplete_query=0
|
||||||
|
|
@ -137,7 +137,10 @@ MONGO_BAZEL_WRAPPER_ARGS=$(mktemp)
|
||||||
MONGO_BAZEL_WRAPPER_ARGS=$MONGO_BAZEL_WRAPPER_ARGS \
|
MONGO_BAZEL_WRAPPER_ARGS=$MONGO_BAZEL_WRAPPER_ARGS \
|
||||||
MONGO_AUTOCOMPLETE_QUERY=$autocomplete_query \
|
MONGO_AUTOCOMPLETE_QUERY=$autocomplete_query \
|
||||||
$python $REPO_ROOT/bazel/wrapper_hook.py $bazel_real "$@"
|
$python $REPO_ROOT/bazel/wrapper_hook.py $bazel_real "$@"
|
||||||
|
if [[ $? != 0 ]]; then
|
||||||
|
>&2 echo "wrapper script failed! falling back to normal bazel call..."
|
||||||
|
exec "$bazel_real" $@
|
||||||
|
fi
|
||||||
new_args=$(<$MONGO_BAZEL_WRAPPER_ARGS)
|
new_args=$(<$MONGO_BAZEL_WRAPPER_ARGS)
|
||||||
|
|
||||||
if [[ $MONGO_BAZEL_WRAPPER_DEBUG == 1 ]] && [[ $autocomplete_query == 0 ]]; then
|
if [[ $MONGO_BAZEL_WRAPPER_DEBUG == 1 ]] && [[ $autocomplete_query == 0 ]]; then
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ setlocal EnableDelayedExpansion
|
||||||
|
|
||||||
echo common --//bazel/config:running_through_bazelisk > .bazelrc.bazelisk
|
echo common --//bazel/config:running_through_bazelisk > .bazelrc.bazelisk
|
||||||
|
|
||||||
set REPO_ROOT=%~dp0\..
|
set REPO_ROOT=%~dp0..
|
||||||
|
|
||||||
for %%I in (%REPO_ROOT%) do set cur_dir=%%~nxI
|
for %%I in (%REPO_ROOT%) do set cur_dir=%%~nxI
|
||||||
|
|
||||||
|
|
@ -12,12 +12,22 @@ set python="%REPO_ROOT%\bazel-%cur_dir%\external\py_windows_x86_64\dist\python.e
|
||||||
if not exist "%python%" (
|
if not exist "%python%" (
|
||||||
echo python prereq missing, using bazel to install python... 1>&2
|
echo python prereq missing, using bazel to install python... 1>&2
|
||||||
"%BAZEL_REAL%" build --config=local @py_windows_x86_64//:all 1>&2
|
"%BAZEL_REAL%" build --config=local @py_windows_x86_64//:all 1>&2
|
||||||
|
if %ERRORLEVEL% NEQ 0 (
|
||||||
|
echo wrapper script failed to install python! falling back to normal bazel call...
|
||||||
|
"%BAZEL_REAL%" %*
|
||||||
|
exit %ERRORLEVEL%
|
||||||
|
)
|
||||||
)
|
)
|
||||||
SET STARTTIME=%TIME%
|
SET STARTTIME=%TIME%
|
||||||
|
|
||||||
set "MONGO_BAZEL_WRAPPER_ARGS=%tmp%\bat~%RANDOM%.tmp"
|
set "MONGO_BAZEL_WRAPPER_ARGS=%tmp%\bat~%RANDOM%.tmp"
|
||||||
echo "" > %MONGO_BAZEL_WRAPPER_ARGS%
|
echo "" > %MONGO_BAZEL_WRAPPER_ARGS%
|
||||||
%python% %REPO_ROOT%/bazel/wrapper_hook.py "%BAZEL_REAL%" %*
|
%python% %REPO_ROOT%/bazel/wrapper_hook.py "%BAZEL_REAL%" %*
|
||||||
|
if %ERRORLEVEL% NEQ 0 (
|
||||||
|
echo wrapper script failed! falling back to normal bazel call...
|
||||||
|
"%BAZEL_REAL%" %*
|
||||||
|
exit %ERRORLEVEL%
|
||||||
|
)
|
||||||
for /f "Tokens=* Delims=" %%x in ( %MONGO_BAZEL_WRAPPER_ARGS% ) do set "new_args=!new_args!%%x"
|
for /f "Tokens=* Delims=" %%x in ( %MONGO_BAZEL_WRAPPER_ARGS% ) do set "new_args=!new_args!%%x"
|
||||||
del %MONGO_BAZEL_WRAPPER_ARGS%
|
del %MONGO_BAZEL_WRAPPER_ARGS%
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue