summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Samuels <richard.l.samuels@gmail.com>2022-03-30 13:20:48 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-03-30 14:08:19 +0000
commitd4206bdeb19f4c5862280c04cd6b831c9ec03a40 (patch)
treecac56a77ed5ba54eb5ec167bd5c7cef5ee73f41d
parent93243e0c29ba1f3eae4dc0251e775dc4f6a90c6c (diff)
downloadmongo-d4206bdeb19f4c5862280c04cd6b831c9ec03a40.tar.gz
SERVER-62992 Remove need for resmoke.ini
-rw-r--r--SConstruct18
-rw-r--r--buildscripts/resmoke.ini.in2
-rw-r--r--buildscripts/resmokelib/configure_resmoke.py44
-rw-r--r--site_scons/site_tools/auto_archive.py9
-rw-r--r--site_scons/site_tools/ninja.py1
-rw-r--r--src/mongo/SConscript1
-rw-r--r--src/mongo/resmoke/SConscript28
-rw-r--r--src/mongo/resmoke/resmoke.py.in55
8 files changed, 136 insertions, 22 deletions
diff --git a/SConstruct b/SConstruct
index 534b67216ce..cdf1d1ab9dc 100644
--- a/SConstruct
+++ b/SConstruct
@@ -5362,24 +5362,6 @@ if has_option("cache"):
addNoCacheEmitter(env['BUILDERS']['SharedLibrary'])
addNoCacheEmitter(env['BUILDERS']['LoadableModule'])
-
-# We need to be explicit about including $DESTDIR here, unlike most
-# other places. Normally, auto_install_binaries will take care of
-# injecting DESTDIR for us, but we aren't using that now.
-resmoke_install_dir = env.subst("$DESTDIR/$PREFIX_BINDIR")
-resmoke_install_dir = os.path.normpath(resmoke_install_dir).replace("\\", r"\\")
-
-# Much blood sweat and tears were shed getting to this point. Any version of
-# this that uses SCons builders and a scanner will either not regenerate when it
-# should, cause everything to rebuild, or conflict with ninja. Sometimes all
-# three. So we've decided it's best to just write this file here every time
-# because it's the only solution that always works.
-with open("resmoke.ini", "w") as resmoke_config:
- resmoke_config.write("""
-[resmoke]
-install_dir = {install_dir}
-""".format(install_dir=resmoke_install_dir))
-
env.SConscript(
dirs=[
'src',
diff --git a/buildscripts/resmoke.ini.in b/buildscripts/resmoke.ini.in
deleted file mode 100644
index 5ee714b6dd2..00000000000
--- a/buildscripts/resmoke.ini.in
+++ /dev/null
@@ -1,2 +0,0 @@
-[resmoke]
-install_dir = @install_dir@ \ No newline at end of file
diff --git a/buildscripts/resmokelib/configure_resmoke.py b/buildscripts/resmokelib/configure_resmoke.py
index cc474d4dc59..ae3e05df25d 100644
--- a/buildscripts/resmokelib/configure_resmoke.py
+++ b/buildscripts/resmokelib/configure_resmoke.py
@@ -9,6 +9,9 @@ import distutils.spawn
import sys
import platform
import random
+import glob
+import textwrap
+import shlex
import pymongo.uri_parser
@@ -133,6 +136,19 @@ def _validate_config(parser): # pylint: disable=too-many-branches
parser.error(f"Found '{resolved_path}', but it is not an executable file")
+def _find_resmoke_wrappers():
+ # This is technically incorrect. PREFIX_BINDIR defaults to $PREFIX/bin, so
+ # if the user changes it to any some other value, this glob will fail to
+ # detect the resmoke wrapper.
+ # Additionally, the resmoke wrapper will not be found if a user performs
+ # their builds outside of the git repository root, (ex checkout at
+ # /data/mongo, build-dir at /data/build)
+ # We assume that users who fall under either case will explicitly pass the
+ # --installDir argument.
+ candidate_installs = glob.glob("**/bin/resmoke.py", recursive=True)
+ return list(map(os.path.dirname, candidate_installs))
+
+
def _update_config_vars(values): # pylint: disable=too-many-statements,too-many-locals,too-many-branches
"""Update the variables of the config module."""
@@ -148,11 +164,25 @@ def _update_config_vars(values): # pylint: disable=too-many-statements,too-many
config[cmdline_key] = cmdline_vars[cmdline_key]
if os.path.isfile("resmoke.ini"):
+ err = textwrap.dedent("""\
+Support for resmoke.ini has been removed. You must delete
+resmoke.ini and rerun your build to run resmoke. If only one testable
+installation is present, resmoke will automatically locate that installation.
+If you have multiple installations, you must either pass an explicit
+--installDir argument to the run subcommand to identify the installation you
+would like to test, or invoke the customized resmoke.py wrapper script staged
+into the bin directory of each installation.""")
config_parser = configparser.ConfigParser()
config_parser.read("resmoke.ini")
if "resmoke" in config_parser.sections():
user_config = dict(config_parser["resmoke"])
- config.update(user_config)
+ err += textwrap.dedent(f"""
+
+Based on the current value of resmoke.ini, after rebuilding, resmoke.py should
+be invoked as either:
+- {shlex.quote(f"{user_config['install_dir']}/resmoke.py")}
+- buildscripts/resmoke.py --installDir {shlex.quote(user_config['install_dir'])}""")
+ raise RuntimeError(err)
def setup_feature_flags():
_config.RUN_ALL_FEATURE_FLAG_TESTS = config.pop("run_all_feature_flag_tests")
@@ -224,6 +254,18 @@ def _update_config_vars(values): # pylint: disable=too-many-statements,too-many
_config.MULTIVERSION_BIN_VERSION = config.pop("old_bin_version")
_config.INSTALL_DIR = config.pop("install_dir")
+ if _config.INSTALL_DIR is None:
+ resmoke_wrappers = _find_resmoke_wrappers()
+ if len(resmoke_wrappers) == 1:
+ _config.INSTALL_DIR = resmoke_wrappers[0]
+ elif len(resmoke_wrappers) > 1:
+ err = textwrap.dedent(f"""\
+Multiple testable installations were found, but installDir was not specified.
+You must either call resmoke via one of the following scripts:
+{os.linesep.join(shlex.quote(resmoke_wrappers))}
+
+or explicitly pass --installDir to the run subcommand of buildscripts/resmoke.py.""")
+ raise RuntimeError(err)
if _config.INSTALL_DIR is not None:
# Normalize the path so that on Windows dist-test/bin
# translates to .\dist-test\bin then absolutify it since the
diff --git a/site_scons/site_tools/auto_archive.py b/site_scons/site_tools/auto_archive.py
index f4c7201b33e..b3c9ddd99a4 100644
--- a/site_scons/site_tools/auto_archive.py
+++ b/site_scons/site_tools/auto_archive.py
@@ -133,7 +133,14 @@ def collect_transitive_files(env, entry):
# anyway.
stack.extend(env.GetTransitivelyInstalledFiles(s))
- return sorted(files)
+ # Setting the AIB_NO_ARCHIVE attribute to True prevents outputs from an
+ # AutoInstall builder from being included into archives produced by this
+ # tool
+ # Usage:
+ # node = env.AutoInstall(...)
+ # setattr(node[0].attributes, 'AIB_NO_ARCHIVE', True)
+ # TODO SERVER-61013 Update documentation once AutoInstall is a real builder
+ return sorted(f for f in files if not getattr(f.attributes, 'AIB_NO_ARCHIVE', False))
def auto_archive_gen(first_env, make_archive_script, pkg_fmt):
diff --git a/site_scons/site_tools/ninja.py b/site_scons/site_tools/ninja.py
index 5826be827f4..c755e12b469 100644
--- a/site_scons/site_tools/ninja.py
+++ b/site_scons/site_tools/ninja.py
@@ -660,6 +660,7 @@ class NinjaState:
kwargs['pool'] = 'local_pool'
ninja.rule(rule, **kwargs)
+ # TODO SERVER-64664
generated_source_files = sorted({
output
# First find builds which have header files in their outputs.
diff --git a/src/mongo/SConscript b/src/mongo/SConscript
index 82e6e06b67c..8696da79339 100644
--- a/src/mongo/SConscript
+++ b/src/mongo/SConscript
@@ -35,6 +35,7 @@ env.SConscript(
'installer',
'logv2',
'platform',
+ 'resmoke',
'rpc',
's',
'scripting',
diff --git a/src/mongo/resmoke/SConscript b/src/mongo/resmoke/SConscript
new file mode 100644
index 00000000000..fb80ab1a713
--- /dev/null
+++ b/src/mongo/resmoke/SConscript
@@ -0,0 +1,28 @@
+# -*- mode: python -*-
+import os
+import SCons
+Import('env')
+
+env = env.Clone()
+
+install_dir = env.Dir('$DESTDIR/$PREFIX_BINDIR').path.replace("\\", r"\\")
+resmoke_py = env.Substfile(
+ target="resmoke.py",
+ source='resmoke.py.in',
+ SUBST_DICT = {
+ '@install_dir@': install_dir,
+ }
+)
+resmoke_py_install = env.AutoInstall(
+ '$PREFIX_BINDIR',
+ source=resmoke_py,
+ AIB_COMPONENT='common',
+ AIB_ROLE='runtime',
+)
+# TODO SERVER-61013: We shouldn't have to setattr this once AutoInstall is a
+# real builder
+setattr(resmoke_py_install[0].attributes, 'AIB_NO_ARCHIVE', True)
+env.AddPostAction(
+ resmoke_py_install,
+ action=SCons.Defaults.Chmod('$TARGET', "u+x"),
+)
diff --git a/src/mongo/resmoke/resmoke.py.in b/src/mongo/resmoke/resmoke.py.in
new file mode 100644
index 00000000000..8b5d4106480
--- /dev/null
+++ b/src/mongo/resmoke/resmoke.py.in
@@ -0,0 +1,55 @@
+#!/usr/bin/env python3
+import importlib.util
+import os
+import os.path
+import argparse
+import sys
+import shlex
+import textwrap
+
+BUILD_BIN_DIR=r"@install_dir@"
+
+class _SilentArgumentParser(argparse.ArgumentParser):
+ """ArgumentParser variant that silently swallows errors."""
+ def error(self, message):
+ pass
+
+# We do not want people to use this wrapper and provide --installDir,
+# especially if the user tries to supply the wrong installDir. Prevent that
+# by parsing the command line flags and make sure that --installDir is not
+# passed in. (only the run command supports this flag)
+try:
+ parser = _SilentArgumentParser(add_help=False)
+
+ subparsers = parser.add_subparsers(dest="cmd")
+ run = subparsers.add_parser("run")
+ run.add_argument("--installDir")
+ args, _ = parser.parse_known_args()
+ if "installDir" in args and args.installDir is not None:
+ err = textwrap.dedent(f"""\
+Argument '--installDir' passed to resmoke wrapper script, but this action can
+have unforeseen consequences. Either remove --installDir, or call resmoke as
+`buildscripts/resmoke.py run --installDir={shlex.quote(args.installDir)}`""")
+ raise RuntimeError(err)
+
+ run_cmd_called = args.cmd == "run"
+except RuntimeError:
+ raise
+except:
+ run_cmd_called = False
+
+# If the run subcommand is being used, inject installDir
+if run_cmd_called:
+ i = sys.argv.index("run")
+ sys.argv.insert(i+1, "--installDir")
+ sys.argv.insert(i+2, BUILD_BIN_DIR)
+
+path_to_resmoke_py = os.path.join("buildscripts", "resmoke.py")
+
+# import and run the cli
+spec = importlib.util.spec_from_file_location("__main__", path_to_resmoke_py)
+resmoke = importlib.util.module_from_spec(spec)
+resmoke.__package__ = None
+spec.loader.exec_module(resmoke)
+
+# -*- mode: python -*-