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

DRIVERS-3119 Enhanced cleanup and file permissions handling #615

Merged
merged 10 commits into from
Mar 3, 2025
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/auth_aws/teardown.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pushd $SCRIPT_DIR
# If we've gotten credentials, ensure the instance profile is set.
if [ -f secrets-export.sh ]; then
. ./activate-authawsvenv.sh
source secrets-export.sh
python ./lib/aws_assign_instance_profile.py
fi

Expand Down
15 changes: 15 additions & 0 deletions .evergreen/clean.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -eu

SCRIPT_DIR=$(dirname ${BASH_SOURCE[0]})
. $SCRIPT_DIR/handle-paths.sh

python3 $SCRIPT_DIR/orchestration/drivers_orchestration.py clean

pushd $DRIVERS_TOOLS > /dev/null
find . -type f -name '*.log' -exec rm {} \;
rm -rf "$${TMPDIR:-$${TEMP:-$${TMP:-/tmp}}}"/mongo*
find . -type f -name '*.env' -exec rm {} \;
find . -type f -name '*results.json' -exec rm {} \;

popd > /dev/null
4 changes: 2 additions & 2 deletions .evergreen/mongodl.py
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ def _expand_tgz(
strip_components,
mem.isdir(),
lambda: cast("IO[bytes]", tf.extractfile(mem)), # noqa: B023
mem.mode,
mem.mode | 0o222, # make sure file is writable
test=test,
)
return n_extracted
Expand All @@ -1021,7 +1021,7 @@ def _expand_zip(
strip_components,
item.filename.endswith("/"), ## Equivalent to: item.is_dir(),
lambda: zf.open(item, "r"), # noqa: B023
0o655,
0o777,
test=test,
)
return n_extracted
Expand Down
126 changes: 90 additions & 36 deletions .evergreen/orchestration/drivers_orchestration.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,30 @@
from datetime import datetime
from pathlib import Path

from mongodl import main as mongodl
from mongosh_dl import main as mongosh_dl

# Get global values.
HERE = Path(__file__).absolute().parent
EVG_PATH = HERE.parent
DRIVERS_TOOLS = EVG_PATH.parent
LOGGER = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO, format="%(levelname)-8s %(message)s")
PLATFORM = sys.platform.lower()
CRYPT_NAME_MAP = {
"win32": "mongo_crypt_v1.dll",
"darwin": "mongo_crypt_v1.dylib",
"linux": "mongo_crypt_v1.so",
}

# Top level files
URI_TXT = Path("uri.txt")
MO_EXPANSION_SH = Path("mo-expansion.sh")
MO_EXPANSION_YML = Path("mo-expansion.yml")


def get_options():
parser = argparse.ArgumentParser(
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument("command", choices=["run", "start", "stop"])
parser.add_argument("command", choices=["run", "start", "stop", "clean"])
parser.add_argument(
"--verbose", "-v", action="store_true", help="Whether to log at the DEBUG level"
)
Expand Down Expand Up @@ -188,25 +196,58 @@ def traverse(root):


def normalize_path(path: Path | str) -> str:
if os.name != "nt":
if PLATFORM != "win32":
return str(path)
path = Path(path).as_posix()
return re.sub("/cygdrive/(.*?)(/)", r"\1://", path, count=1)


def run_command(cmd: str, **kwargs):
LOGGER.debug(f"Running command {cmd}...")
try:
proc = subprocess.run(
shlex.split(cmd),
check=True,
encoding="utf-8",
stderr=subprocess.STDOUT,
stdout=subprocess.PIPE,
**kwargs,
)
LOGGER.info(proc.stdout)
except subprocess.CalledProcessError as e:
LOGGER.error(e.output)
LOGGER.error(str(e))
sys.exit(e.returncode)
LOGGER.debug(f"Running command {cmd}... done.")


def clean_run(opts):
mdb_binaries = Path(opts.mongodb_binaries)
mdb_binaries_str = normalize_path(mdb_binaries)
shutil.rmtree(mdb_binaries_str, ignore_errors=True)

mongodb_dir = DRIVERS_TOOLS / "mongodb"
if mongodb_dir.exists():
shutil.rmtree(normalize_path(mongodb_dir), ignore_errors=True)

for path in [URI_TXT, MO_EXPANSION_SH, MO_EXPANSION_YML]:
path.unlink(missing_ok=True)

crypt_path = DRIVERS_TOOLS / CRYPT_NAME_MAP[PLATFORM]
crypt_path.unlink(missing_ok=True)


def run(opts):
# Deferred import so we can run as a script without the cli installed.
from mongodl import main as mongodl
from mongosh_dl import main as mongosh_dl

LOGGER.info("Running orchestration...")
clean_run(opts)

# Clean up previous files.
mdb_binaries = Path(opts.mongodb_binaries)
# NOTE: in general, we need to normalize paths to account for cygwin/Windows.
mdb_binaries = Path(opts.mongodb_binaries)
mdb_binaries_str = normalize_path(mdb_binaries)
shutil.rmtree(mdb_binaries, ignore_errors=True)
expansion_yaml = Path("mo-expansion.yml")
expansion_yaml.unlink(missing_ok=True)
expansion_sh = Path("mo-expansion.sh")
expansion_sh.unlink(missing_ok=True)
uri_txt = DRIVERS_TOOLS / "uri.txt"

# The evergreen directory to path.
os.environ["PATH"] = f"{EVG_PATH}:{os.environ['PATH']}"
Expand All @@ -231,7 +272,7 @@ def run(opts):
LOGGER.info(f"Using existing mongod binaries dir: {opts.existing_binaries_dir}")
shutil.copytree(opts.existing_binaries_dir, mdb_binaries)

subprocess.run([f"{mdb_binaries_str}/mongod", "--version"], check=True)
run_command(f"{mdb_binaries_str}/mongod --version")

# Download legacy shell.
if opts.install_legacy_shell:
Expand All @@ -247,22 +288,23 @@ def run(opts):
# We download crypt_shared to DRIVERS_TOOLS so that it is on a different
# path location than the other binaries, which is required for
# https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/tests/README.md#via-bypassautoencryption
args = default_args.replace(mdb_binaries_str, normalize_path(DRIVERS_TOOLS))
args += (
args = default_args + (
f" --version {version} --strip-path-components 1 --component crypt_shared"
)
LOGGER.info("Downloading crypt_shared...")
mongodl(shlex.split(args))
LOGGER.info("Downloading crypt_shared... done.")
crypt_shared_path = None
expected = [f"mongo_crypt_v1.{ext}" for ext in ["dll", "so", "dylib"]]
for fname in os.listdir(DRIVERS_TOOLS):
if fname in expected:
crypt_shared_path = DRIVERS_TOOLS / fname
assert crypt_shared_path is not None
crypt_shared_path = mdb_binaries / CRYPT_NAME_MAP[PLATFORM]
if crypt_shared_path.exists():
shutil.move(crypt_shared_path, DRIVERS_TOOLS)
crypt_shared_path = DRIVERS_TOOLS / crypt_shared_path.name
else:
raise RuntimeError(
f"Could not find expected crypt_shared_path: {crypt_shared_path}"
)
crypt_text = f'CRYPT_SHARED_LIB_PATH: "{normalize_path(crypt_shared_path)}"'
expansion_yaml.write_text(crypt_text)
expansion_sh.write_text(crypt_text.replace(": ", "="))
MO_EXPANSION_YML.write_text(crypt_text)
MO_EXPANSION_SH.write_text(crypt_text.replace(": ", "="))

# Download mongosh
args = f"--out {mdb_binaries_str} --strip-path-components 2 --retries 5"
Expand Down Expand Up @@ -350,9 +392,11 @@ def run(opts):

# Handle the cluster uri.
uri = resp.get("mongodb_auth_uri", resp["mongodb_uri"])
expansion_yaml.touch()
expansion_yaml.write_text(expansion_yaml.read_text() + f'\nMONGODB_URI: "{uri}"')
uri_txt.write_text(uri)
MO_EXPANSION_YML.touch()
MO_EXPANSION_YML.write_text(
MO_EXPANSION_YML.read_text() + f'\nMONGODB_URI: "{uri}"'
)
URI_TXT.write_text(uri)
LOGGER.info(f"Cluster URI: {uri}")

# Write the results file.
Expand Down Expand Up @@ -380,6 +424,19 @@ def run(opts):
LOGGER.info("Running orchestration... done.")


def clean_start(opts):
mo_home = Path(opts.mongo_orchestration_home)
for fname in [
"out.log",
"server.log",
"orchestration.config",
"config.json",
"server.pid",
]:
if (mo_home / fname).exists():
(mo_home / fname).unlink()


def start(opts):
# Start mongo-orchestration

Expand All @@ -389,9 +446,7 @@ def start(opts):
stop()

# Clean up previous files.
for fname in ["out.log", "server.log", "orchestration.config", "config.json"]:
if (mo_home / fname).exists():
(mo_home / fname).unlink()
clean_start(opts)

# Set up the mongo orchestration config.
os.makedirs(mo_home / "lib", exist_ok=True)
Expand All @@ -404,7 +459,7 @@ def start(opts):
command = f"{sys_executable} -m mongo_orchestration.server"

# Handle Windows-specific concerns.
if os.name == "nt":
if PLATFORM == "win32":
# Copy default client certificate.
src = DRIVERS_TOOLS / ".evergreen/x509gen/client.pem"
dst = mo_home / "lib/client.pem"
Expand Down Expand Up @@ -474,11 +529,7 @@ def start(opts):
def stop():
LOGGER.info("Stopping mongo-orchestration...")
py_exe = normalize_path(sys.executable)
args = f"{py_exe} -m mongo_orchestration.server stop"
proc = subprocess.run(
shlex.split(args), check=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE
)
LOGGER.debug(proc.stdout.decode("utf-8"))
run_command(f"{py_exe} -m mongo_orchestration.server stop")
LOGGER.info("Stopping mongo-orchestration... done.")


Expand All @@ -490,6 +541,9 @@ def main():
start(opts)
elif opts.command == "stop":
stop()
elif opts.command == "clean":
clean_run(opts)
clean_start(opts)


if __name__ == "__main__":
Expand Down
4 changes: 3 additions & 1 deletion .evergreen/tests/test-cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ SCRIPT_DIR=$(dirname ${BASH_SOURCE[0]})

pushd $SCRIPT_DIR/..

# Ensure we can run clean before the cli is installed.
make clean

bash install-cli.sh .
DOWNLOAD_DIR=mongodl_test

Expand All @@ -32,7 +35,6 @@ fi
export PATH="${DOWNLOAD_DIR}/bin:$PATH"
if [ "${OS:-}" != "Windows_NT" ]; then
./mongosh-dl --version 2.1.1 --out ${DOWNLOAD_DIR} --strip-path-components 1 --retries 5
chmod +x ./mongodl_test/bin/mongosh
./mongodl_test/bin/mongosh --version
else
./mongosh-dl --version 2.1.1 --out ${DOWNLOAD_DIR} --strip-path-components 1 --retries 5
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ jobs:
- id: test-mongodb
name: "Test GitHub Action"
run: |
chmod +x mongodb/bin/mongosh
URI=$(cat uri.txt)
ARGS=""
if [ ${{ matrix.ssl }} == "ssl" ]; then
Expand Down
5 changes: 2 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ all:

clean:
@echo "Cleaning files..."
rm -rf ./mongodb .env results.json mo-expansion*
rm -rf "$${TMPDIR:-$${TEMP:-$${TMP:-/tmp}}}"/mongo*
.evergreen/clean.sh

run-server: clean
run-server:
@echo "Running server..."
.evergreen/run-orchestration.sh

Expand Down
Loading