osmith has uploaded this change for review.
testenv: coredump: support core_pattern=core
Support getting core files from a typical core_pattern=core where the
coredump just gets stored in the current working dir, instead of always
retrieving it from coredumpctl. This is what we will use with jenkins in
the future, as it makes getting core files in other jobs easier. Remove
support for the custom testenv-coredump-helper code that isn't needed
anymore.
Change-Id: Ia765b01432e4cb4cd36c45de874b966e3ebf55bc
---
M _testenv/testenv/coredump.py
M _testenv/testenv/daemons.py
M _testenv/testenv/requirements.py
3 files changed, 46 insertions(+), 56 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/52/41152/1
diff --git a/_testenv/testenv/coredump.py b/_testenv/testenv/coredump.py
index 0343c67..d3fa35f 100644
--- a/_testenv/testenv/coredump.py
+++ b/_testenv/testenv/coredump.py
@@ -2,63 +2,20 @@
# SPDX-License-Identifier: GPL-3.0-or-later
import datetime
import fnmatch
+import glob
import json
import logging
-import os
+import re
import shlex
import shutil
import subprocess
import testenv
import testenv.daemons
import testenv.testdir
-import urllib
-import urllib.request
+core_path = None
executable_path = None
-lxc_netdev = "eth0"
-lxc_ip_pattern = "10.0.*"
-lxc_port = 8042
-
-
-def find_lxc_host_ip():
- cmd = ["ip", "-j", "-o", "-4", "addr", "show", "dev", lxc_netdev]
- p = testenv.cmd.run(cmd, check=False, no_podman=True, capture_output=True, text=True)
- ret = json.loads(p.stdout)[0]["addr_info"][0]["local"]
- if fnmatch.fnmatch(ret, lxc_ip_pattern):
- ret = ret.split(".")
- ret = f"{ret[0]}.{ret[1]}.{ret[2]}.1"
- return ret
- return None
-
-
-def get_from_coredumpctl_lxc_host():
- # Server implementation: osmo-ci, ansible/roles/testenv-coredump-helper
- global executable_path
-
- logging.info("Looking for a coredump on lxc host")
-
- ip = os.environ.get("TESTENV_COREDUMP_FROM_LXC_HOST_IP") or find_lxc_host_ip()
- if not ip:
- logging.warning("Failed to get lxc host ip, can't look for coredump")
- return
-
- try:
- with urllib.request.urlopen(f"http://{ip}:{lxc_port}/core") as response:
- executable_path = dict(response.getheaders())["X-Executable-Path"]
- with open(f"{testenv.testdir.testdir}/core", "wb") as h:
- shutil.copyfileobj(response, h)
- logging.debug("Coredump found and copied to log dir")
- except urllib.error.HTTPError as e:
- executable_path = None
- if e.code == 404:
- logging.debug("No coredump found")
- else:
- logging.error(f"Unexpected error while attempting to fetch the coredump: {e}")
- except urllib.error.URLError as e:
- executable_path = None
- logging.error(f"Unexpected error while attempting to fetch the coredump: {e}")
-
def executable_is_relevant(exe):
if testenv.args.binary_repo:
@@ -77,10 +34,11 @@
return False
-def get_from_coredumpctl_local():
+def get_from_coredumpctl():
+ global core_path
global executable_path
- logging.info("Looking for a coredump")
+ logging.info("Looking for a coredump with coredumpctl")
if not shutil.which("coredumpctl"):
logging.debug("coredumpctl is not available, won't try to get coredump")
@@ -113,18 +71,49 @@
executable_path = coredump["exe"]
-def get_from_coredumpctl():
- if os.environ.get("TESTENV_COREDUMP_FROM_LXC_HOST"):
- get_from_coredumpctl_lxc_host()
+def get_from_file():
+ global core_path
+ global executable_path
+
+ logging.info("Looking for a coredump file")
+
+ glob_matches = glob.glob(f"{testenv.testdir.testdir}/*/core*")
+ if not glob_matches:
+ return
+
+ core_path = glob_matches[0]
+ p = testenv.cmd.run(
+ ["file", core_path],
+ no_podman=True,
+ capture_output=True,
+ text=True,
+ )
+ print(p.stdout, end="")
+
+ execfn_match = re.search(r"execfn: '(.*?)'", p.stdout)
+ if execfn_match:
+ executable_path = execfn_match.group(1)
+ logging.debug("Coredump file and execfn found")
else:
- get_from_coredumpctl_local()
+ logging.debug("Failed to get execfn path from coredump file")
+
+
+def get_coredump():
+ with open("/proc/sys/kernel/core_pattern") as f:
+ pattern = f.readline().rstrip()
+
+ if "systemd-coredump" in pattern:
+ get_from_coredumpctl()
+ elif pattern.startswith("core"):
+ get_from_file()
+ else:
+ logging.debug(f"Unsupported core_pattern, won't try to get coredump: {pattern}")
def get_backtrace():
global executable_path
- core_path = f"{testenv.testdir.testdir}/core"
- if not executable_path or not os.path.exists(core_path):
+ if not executable_path or not core_path:
return
logging.info("Running gdb to get a backtrace")
diff --git a/_testenv/testenv/daemons.py b/_testenv/testenv/daemons.py
index 3a38850..f57b4b4 100644
--- a/_testenv/testenv/daemons.py
+++ b/_testenv/testenv/daemons.py
@@ -68,7 +68,7 @@
# Wait 200ms and check if it is still running
time.sleep(0.2)
if daemons[section].poll() is not None:
- testenv.coredump.get_from_coredumpctl()
+ testenv.coredump.get_coredump()
raise testenv.NoTraceException(f"program failed to start: {program}")
# Run setup script
@@ -118,7 +118,7 @@
return
current_test = testenv.testsuite.get_current_test()
- testenv.coredump.get_from_coredumpctl()
+ testenv.coredump.get_coredump()
if current_test:
logging.error(f"{daemon_name} unexpected exit during {current_test}! rc={returncode}")
diff --git a/_testenv/testenv/requirements.py b/_testenv/testenv/requirements.py
index 97fae0c..2e53081 100644
--- a/_testenv/testenv/requirements.py
+++ b/_testenv/testenv/requirements.py
@@ -11,6 +11,7 @@
def check_programs():
programs = [
+ "file",
"git",
]
To view, visit change 41152. To unsubscribe, or for help writing mail filters, visit settings.