Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .evergreen/orchestration/configs/servers/auth-ssl.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"id" : "standalonessl",
"auth_key": "secret",
"name": "mongod",
"login": "bob",
"password": "pwd123",
Expand Down
75 changes: 68 additions & 7 deletions .evergreen/orchestration/mongodb_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,48 @@ def _normalize_path(path: Union[Path, str]) -> str:
return re.sub("/cygdrive/(.*?)(/)", r"\1://", path, count=1)


_MR_VERSION = "6.7.1"


def _install_mongodb_runner() -> Path:
"""Install mongodb-runner via npm with overrides to pin @mongodb-js/oidc-mock-provider.

npx does not support npm overrides, so we manage the install manually.
@mongodb-js/oidc-mock-provider 0.13.8+ switched to yargs@18 (ESM-only), which
cannot be require()'d on Node 16. Pinning to 0.13.7 keeps it on yargs@17.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's necessary, we can undo the yargs bump.

But it might also be worth calling out that Node.js 16 has been EOL since 2023, and starting next month Node.js 22 will be the oldest supported release line.

"""
install_dir = TMPDIR / f"mongodb-runner-{_MR_VERSION}"
ext = ".cmd" if PLATFORM == "win32" else ""
runner_bin = install_dir / "node_modules" / ".bin" / f"mongodb-runner{ext}"
if not runner_bin.exists():
pkg = {
"name": "mongodb-runner-wrapper",
"version": "1.0.0",
"dependencies": {"mongodb-runner": _MR_VERSION},
"overrides": {"@mongodb-js/oidc-mock-provider": "0.13.7"},
}
install_dir.mkdir(parents=True, exist_ok=True)
(install_dir / "package.json").write_text(json.dumps(pkg, indent=2))
npm = shutil.which("npm")
if npm is None:
raise RuntimeError(
"npm not found. Source init-node-and-npm-env.sh or install Node before running this script."
)
if PLATFORM == "win32":
# .cmd files require shell=True on Windows; pass as string to avoid quoting issues.
subprocess.run(
f'"{npm}" install --silent',
Comment thread
aclark4life marked this conversation as resolved.
cwd=str(install_dir),
check=True,
shell=True,
)
else:
subprocess.run(
[npm, "install", "--silent"], cwd=str(install_dir), check=True
)
return runner_bin


def start_mongodb_runner(opts, data):
mo_home = Path(opts.mongo_orchestration_home)
server_log = mo_home / "server.log"
Expand All @@ -80,20 +122,39 @@ def start_mongodb_runner(opts, data):
binary = shutil.which("node")
target = HERE / "devtools-shared/packages/mongodb-runner/bin/runner.js"
target = _normalize_path(target)
binary = _normalize_path(binary)
cmd = f"{binary} {target} start --debug --config {config_file}"
else:
binary = shutil.which("npx")
target = "-y mongodb-runner@^6.7.1"
binary = _normalize_path(binary)
cmd = f"{binary} {target} start --debug --config {config_file}"
LOGGER.info(f"Running mongodb-runner using {binary} {target}...")
binary = _normalize_path(_install_mongodb_runner())
cmd = f"{binary} start --debug --config {config_file}"
LOGGER.info(f"Running mongodb-runner using {binary}...")
env = os.environ.copy()
node_bin = shutil.which("node")
if node_bin:
try:
node_ver = subprocess.check_output(
[node_bin, "--version"], encoding="utf-8"
).strip()
node_major = int(node_ver.lstrip("v").split(".")[0])
# Node < 19 doesn't expose WebCrypto as a global; mongodb driver needs it.
# The flag was removed in Node 22, so only add it for Node 16-18.
if node_major < 19:
existing = env.get("NODE_OPTIONS", "")
env["NODE_OPTIONS"] = (
f"{existing} --experimental-global-webcrypto".strip()
)
except (subprocess.CalledProcessError, ValueError):
pass
try:
with server_log.open("w") as fid:
# Capture output while still streaming it to the file
proc = subprocess.Popen(
shlex.split(cmd),
cmd if PLATFORM == "win32" else shlex.split(cmd),
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
env=env,
shell=(PLATFORM == "win32"),
)
output_lines = []
for line in proc.stdout:
Expand All @@ -109,7 +170,7 @@ def start_mongodb_runner(opts, data):
LOGGER.error("server.log: %s", server_log.read_text())
LOGGER.error(str(e))
raise e
LOGGER.info(f"Running mongodb-runner using {binary} {target}... done.")
LOGGER.info(f"Running mongodb-runner using {binary}... done.")
cluster_file = Path(config["runnerDir"]) / f"m-{config['id']}.json"
server_info = json.loads(cluster_file.read_text())
cluster_file.unlink()
Expand Down
14 changes: 13 additions & 1 deletion .evergreen/tests/test-install-binaries.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,19 @@ SCRIPT_DIR=$(dirname ${BASH_SOURCE[0]})
pushd $SCRIPT_DIR/..

./install-node.sh
npx -y mongodb-runner --help
. ./init-node-and-npm-env.sh
MR_INSTALL_DIR=$(mktemp -d)
case "$(uname -s)" in
CYGWIN*) MR_INSTALL_DIR=$(cygpath -m "$MR_INSTALL_DIR") ;;
esac
trap 'rm -rf "$MR_INSTALL_DIR"' EXIT
printf '{"name":"t","version":"1.0.0","dependencies":{"mongodb-runner":"6.7.1"},"overrides":{"@mongodb-js/oidc-mock-provider":"0.13.7"}}' > "$MR_INSTALL_DIR/package.json"
# Use a subshell + cd so npm install uses process.cwd() instead of --prefix,
# which avoids MSYS2/Cygwin path translation issues on Windows.
(cd "$MR_INSTALL_DIR" && npm install --silent)
# Invoke node directly to bypass the .bin/ POSIX shim, which can fail on
Comment thread
aclark4life marked this conversation as resolved.
# Windows (CRLF shebang line or missing interpreter).
node "$MR_INSTALL_DIR/node_modules/mongodb-runner/bin/runner.js" --help

source ./install-rust.sh
rustup install stable
Expand Down
31 changes: 28 additions & 3 deletions .evergreen/tests/test-mongodb-runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,64 @@ pushd $SCRIPT_DIR/.. > /dev/null
# shellcheck disable=SC2120
function connect_mongodb() {
local use_tls=false
local use_auth=false
local eval_cmd='db.runCommand({"ping":1})'

# Parse flags
while [[ $# -gt 0 ]]; do
case "$1" in
--ssl) use_tls=true; shift ;;
--auth) use_auth=true; shift ;;
--eval-cmd)
if [[ -z "${2:-}" ]]; then
echo "Missing value for --eval-cmd"
return 1
fi
eval_cmd="$2"
shift 2
;;
*) echo "Unknown option: $1"; return 1 ;;
esac
done

URI="mongodb://localhost:27017/?directConnection=true&serverSelectionTimeoutMS=10000"
if [[ "$use_auth" == "true" ]]; then
URI="mongodb://bob:pwd123@localhost:27017/?directConnection=true&serverSelectionTimeoutMS=10000&authSource=admin"
fi
local TLS_OPTS=()
if [[ "$use_tls" == "true" ]]; then
TLS_OPTS+=("--tls" "--tlsCertificateKeyFile" "${DRIVERS_TOOLS}/.evergreen/x509gen/server.pem")
TLS_OPTS+=("--tlsCAFile" "${DRIVERS_TOOLS}/.evergreen/x509gen/ca.pem")
fi
local result=0
echo "Connecting to server..."
# shellcheck disable=SC2068
$MONGODB_BINARIES/mongosh "$URI" ${TLS_OPTS[@]:-} --eval "db.runCommand({\"ping\":1})"
$MONGODB_BINARIES/mongosh "$URI" ${TLS_OPTS[@]:-} --eval "$eval_cmd" || result=$?
echo "Connecting to server... done."
return $result
}

# Test for default, then test cli options.
bash ./run-mongodb.sh start
connect_mongodb

bash ./run-mongodb.sh start --topology standalone --auth
connect_mongodb
connect_mongodb --auth

bash ./run-mongodb.sh start --version 7.0 --topology replica_set --ssl
connect_mongodb --ssl

bash ./run-mongodb.sh start --version latest --topology sharded_cluster --auth --ssl
connect_mongodb --ssl
connect_mongodb --ssl --auth

# Verify that auth is enforced when starting with AUTH=auth SSL=yes.
# An unauthenticated connection must be rejected, and an authenticated one must succeed.
AUTH=auth SSL=yes bash ./run-mongodb.sh start
if connect_mongodb --ssl --eval-cmd 'db.adminCommand({listDatabases:1})' 2>/dev/null; then
echo "ERROR: unauthenticated connection should have been rejected on an auth+ssl server"
exit 1
fi
connect_mongodb --ssl --auth
Comment thread
aclark4life marked this conversation as resolved.

# Ensure that we can use a downloaded mongodb directory.
DOWNLOAD_DIR=mongodl_test
Expand Down
Loading