From e95a1933427af07d9d3479bb9971148907c214d1 Mon Sep 17 00:00:00 2001 From: runck014 Date: Sun, 18 Oct 2026 16:34:35 -0500 Subject: [PATCH] device_monitoring cron: notification email off by default (DEVICEMON_EMAIL=1 to send) The MSI job emailed a full report on every run; the dashboard is now where the results are read. The script passes --no-email unless DEVICEMON_EMAIL=1 and logs which way it went. New test covers both paths (39/39 device_monitoring tests). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0149VSJ7dmCkXd4UcUjQbG9R --- src/rtgs_lab_tools/device_monitoring/README.md | 3 ++- .../scheduled_device_monitoring.sh | 8 ++++++++ tests/device_monitoring/test_cron_script.py | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/rtgs_lab_tools/device_monitoring/README.md b/src/rtgs_lab_tools/device_monitoring/README.md index 9f0908d..3da9e6d 100644 --- a/src/rtgs_lab_tools/device_monitoring/README.md +++ b/src/rtgs_lab_tools/device_monitoring/README.md @@ -50,7 +50,8 @@ The monitoring script runs from the lab's shared workspace on Bryan's scrontab: Paths are overridable from the scrontab environment (never from the credentials file): DEVICEMON_BASE_DIR, DEVICEMON_WORK_DIR, DEVICEMON_LOG_DIR, DEVICEMON_CREDS_FILE, DEVICEMON_RELEASE_FILE, DEVICEMON_SA_KEY, DEVICEMON_TOKEN_SECRET, DEVICEMON_PYTHON_MODULE -(default `python3/3.12.4_anaconda2024.06-1_libmamba`), DEVICEMON_PYTHON (absolute path). +(default `python3/3.12.4_anaconda2024.06-1_libmamba`), DEVICEMON_PYTHON (absolute path), +DEVICEMON_EMAIL (`1` sends the notification email after each run; off by default). Ownership (the script refuses to run if the code side is group- or world-writable): ``` diff --git a/src/rtgs_lab_tools/device_monitoring/scheduled_device_monitoring.sh b/src/rtgs_lab_tools/device_monitoring/scheduled_device_monitoring.sh index d3401f9..b56fab0 100755 --- a/src/rtgs_lab_tools/device_monitoring/scheduled_device_monitoring.sh +++ b/src/rtgs_lab_tools/device_monitoring/scheduled_device_monitoring.sh @@ -31,6 +31,8 @@ # `module load python` left /usr/bin/python3 = 3.6.8 on PATH) # DEVICEMON_PYTHON interpreter to build the venv with (absolute path); skips the # module lookup +# DEVICEMON_EMAIL 1 = send the notification email after each run; default off +# (the dashboard is the place to look; Bryan, 2026-10-18) # # Paths (defaults = the lab's shared MSI workspace): # DEVICEMON_BASE_DIR /projects/standard/runck014/shared/device_monitoring @@ -379,6 +381,12 @@ MONITOR_ARGS=(monitor) [ -z "$END_DATE" ] || MONITOR_ARGS+=("--end-date=$END_DATE") [ -z "$NODE_IDS" ] || MONITOR_ARGS+=("--node-ids=$NODE_IDS") [ "$PROJECT" = "ALL" ] || MONITOR_ARGS+=("--project=$PROJECT") +if [ "${DEVICEMON_EMAIL:-0}" = "1" ]; then + log "Notification email: on (DEVICEMON_EMAIL=1)" +else + MONITOR_ARGS+=("--no-email") + log "Notification email: off (set DEVICEMON_EMAIL=1 to send it)" +fi # Pin one timestamp for the whole day and keep it across retries, so a retried # report replaces the rows of the attempt it is repeating. UTC throughout. diff --git a/tests/device_monitoring/test_cron_script.py b/tests/device_monitoring/test_cron_script.py index 1d3d09e..6436dc9 100644 --- a/tests/device_monitoring/test_cron_script.py +++ b/tests/device_monitoring/test_cron_script.py @@ -209,6 +209,24 @@ def test_builds_lean_venv_and_runs_the_devmon_cli(ws): assert r.returncode == 0 and "-m pip" not in log.read_text() +def test_email_off_by_default_and_opt_in(ws): + sha = release_with_requirements(ws) + log = ws["tmp"] / "py.log" + pin = f"devmon-v0.0.2 {sha}\n" + + def monitor_call(**extra): + log.write_text("") + r = run(ws, pin, DEVICEMON_PYTHON=str(stub_python(ws)), STUB_LOG=str(log), **extra) + assert r.returncode == 0, r.stdout + r.stderr + calls = [c.split(" ", 1)[1] for c in log.read_text().splitlines()] + return [c for c in calls if ".cli monitor" in c][0], r.stdout + + call, out = monitor_call() + assert call.endswith("--no-email") and "Notification email: off" in out + call, out = monitor_call(DEVICEMON_EMAIL="1") + assert "--no-email" not in call and "Notification email: on" in out + + def test_never_runs_install_sh_or_full_extras(): text = SCRIPT.read_text() assert "bash install.sh" not in text and "[dev]" not in text and "[all]" not in text