From b51fd2c651d5289d6de4f11cda2a83bc71a0222b Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Fri, 21 Aug 2026 17:59:23 +0200 Subject: [PATCH] Record the node a container is running on, not the container id #320 stores socket.gethostname() as the machine that produced a library's results. That is right until the run is inside a container, where it is the container id: job_claim currently says the wasm-jit libraries were tested by "e9725d308091", which identifies no machine and is gone with the container. #295 wants every job in a Docker image, which would make that the answer everywhere and leave the new libversion.host column as useless as no column. Ask Jenkins instead. It names its agents and propagates NODE_NAME into a container it starts, so that is the machine name when there is a container in the way. LIBTEST_HOST overrides it, for the same reason LIBTEST_DB exists. NODE_NAME is only consulted inside a container - detected by /.dockerenv, or /run/.containerenv under podman. Outside one the kernel's answer is the right one and a NODE_NAME left in the environment must not override it, which is also what keeps this a no-op for the machines running the testing today. One helper in resultsdb, so the claim in job_claim and the host recorded with the results cannot disagree about which machine this is. Checked all four paths: plain host, NODE_NAME set but no container (unchanged, the real hostname wins), LIBTEST_HOST set, and inside a container with and without NODE_NAME. The container paths were exercised by faking the marker file rather than in a real container - Docker is not available where this was written. Follow-up to #320, part of #301, and needed before #295. --- resultsdb.py | 26 +++++++++++++++++++++++++- test.py | 3 +-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/resultsdb.py b/resultsdb.py index e709038..03d2299 100644 --- a/resultsdb.py +++ b/resultsdb.py @@ -78,6 +78,30 @@ # Jenkins sets LIBTEST_DB once for the whole pipeline rather than passing --db # to every script invocation. DEFAULT_DB = os.environ.get("LIBTEST_DB") or "sqlite3.db" + + +def hostname(): + """The machine the testing is running on, as something a human recognises. + + socket.gethostname() is that machine, right up until the run is inside a + container, where it is the container id instead: job_claim holds rows saying + the wasm-jit libraries were tested by "e9725d308091", which identifies nothing + and is gone with the container. Jenkins does know the machine - it names its + agents - and propagates NODE_NAME into a container it starts, so prefer that + when there is a container to see through. LIBTEST_HOST overrides both, for + the same reason LIBTEST_DB exists. + + Only consulted inside a container: outside one the kernel's answer is the + right one, and a NODE_NAME left over in the environment should not override + it. + """ + explicit = os.environ.get("LIBTEST_HOST") + if explicit: + return explicit + # Docker leaves /.dockerenv behind, podman /run/.containerenv. + if os.path.exists("/.dockerenv") or os.path.exists("/run/.containerenv"): + return os.environ.get("NODE_NAME") or socket.gethostname() + return socket.gethostname() DB_HELP = ("Result database: a local sqlite3 file, or a postgresql://user@host/database URL for " "the shared one, taken from the LIBTEST_DB environment variable when not given. " "Several machines can write to the shared database at the same time; a library " @@ -304,7 +328,7 @@ def __init__(self, url): self.lostConnection = (psycopg2.OperationalError, psycopg2.InterfaceError) self.pending = [] self.conn = self._connect() - self.host = socket.gethostname() + self.host = hostname() self.claims = [] self.heartbeatThread = None self.execute(JOB_CLAIM) diff --git a/test.py b/test.py index 8351f66..6cb7797 100755 --- a/test.py +++ b/test.py @@ -12,7 +12,6 @@ from joblib import Parallel, delayed import simplejson as json import psutil, subprocess, threading, hashlib -import socket from subprocess import call from monotonic import monotonic from omcommon import friendlyStr, multiple_replace @@ -1011,7 +1010,7 @@ def cpu_name(): except: lsb_release = "" -hostname = socket.gethostname() +hostname = resultsdb.hostname() sysInfo = "%s: %s, %d GB RAM, %s%s" % (hostname, cpu_name(), int(math.ceil(psutil.virtual_memory().total / (1024.0**3))), ("Docker " + docker + " ") if docker else "", lsb_release) for (resultBranch, simulator) in resultBranches: