Skip to content

Commit 3665b69

Browse files
committed
Run systemd-detect-virt
Add run_command() function. Log also the "container" environment variable.
1 parent aa29571 commit 3665b69

1 file changed

Lines changed: 56 additions & 50 deletions

File tree

Lib/test/pythoninfo.py

Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010

1111
MS_WINDOWS = (sys.platform == "win32")
12+
COMMAND_TIMEOUT = 60.0
1213

1314

1415
def normalize_text(text):
@@ -356,6 +357,9 @@ def format_groups(groups):
356357
"_PYTHON_SYSCONFIGDATA_PATH",
357358
"__PYVENV_LAUNCHER__",
358359

360+
# Lower case variables
361+
"container",
362+
359363
# Sanitizer options
360364
"ASAN_OPTIONS",
361365
"LSAN_OPTIONS",
@@ -435,19 +439,40 @@ def format_attr(attr, value):
435439
info_add('readline.library', 'GNU readline')
436440

437441

438-
def collect_gdb(info_add):
442+
def run_command(cmd, **kwargs):
439443
import subprocess
444+
timeout = COMMAND_TIMEOUT
440445

441446
try:
442-
proc = subprocess.Popen(["gdb", "-nx", "--version"],
447+
proc = subprocess.Popen(cmd,
443448
stdout=subprocess.PIPE,
444-
stderr=subprocess.PIPE,
445-
universal_newlines=True)
446-
version = proc.communicate()[0]
449+
stderr=subprocess.DEVNULL,
450+
text=True,
451+
**kwargs)
452+
# ignore stderr
453+
with proc:
454+
try:
455+
stdout = proc.communicate(timeout=timeout)[0]
456+
except:
457+
proc.kill()
458+
proc.communicate()
459+
raise
460+
447461
if proc.returncode:
448-
# ignore gdb failure: test_gdb will log the error
449-
return
462+
return ''
463+
464+
# Strip trailing spaces and newlines
465+
return stdout.rstrip()
450466
except OSError:
467+
return ''
468+
except subprocess.TimeoutExpired:
469+
print(f"ERROR: Command {' '.join(cmd)}: timeout!")
470+
return ''
471+
472+
473+
def collect_gdb(info_add):
474+
version = run_command(["gdb", "-nx", "--version"])
475+
if not version:
451476
return
452477

453478
# Only keep the first line
@@ -848,7 +873,6 @@ def collect_support_threading_helper(info_add):
848873

849874

850875
def collect_cc(info_add):
851-
import subprocess
852876
import sysconfig
853877

854878
CC = sysconfig.get_config_var('CC')
@@ -861,19 +885,13 @@ def collect_cc(info_add):
861885
except ImportError:
862886
args = CC.split()
863887
args.append('--version')
864-
try:
865-
proc = subprocess.Popen(args,
866-
stdout=subprocess.PIPE,
867-
stderr=subprocess.STDOUT,
868-
universal_newlines=True)
869-
except OSError:
888+
889+
stdout = run_command(args)
890+
if not stdout:
870891
# Cannot run the compiler, for example when Python has been
871892
# cross-compiled and installed on the target platform where the
872893
# compiler is missing.
873-
return
874-
875-
stdout = proc.communicate()[0]
876-
if proc.returncode:
894+
#
877895
# CC --version failed: ignore error
878896
return
879897

@@ -979,21 +997,11 @@ def collect_windows(info_add):
979997
call_func(info_add, 'windows.oem_code_page', _winapi, 'GetOEMCP')
980998

981999
# windows.version_caption: "wmic os get Caption,Version /value" command
982-
import subprocess
983-
try:
984-
# When wmic.exe output is redirected to a pipe,
985-
# it uses the OEM code page
986-
proc = subprocess.Popen(["wmic", "os", "get", "Caption,Version", "/value"],
987-
stdout=subprocess.PIPE,
988-
stderr=subprocess.PIPE,
989-
encoding="oem",
990-
text=True)
991-
output, stderr = proc.communicate()
992-
if proc.returncode:
993-
output = ""
994-
except OSError:
995-
pass
996-
else:
1000+
output = run_command(["wmic", "os", "get", "Caption,Version", "/value"],
1001+
# When wmic.exe output is redirected to a pipe,
1002+
# it uses the OEM code page
1003+
encoding="oem")
1004+
if output:
9971005
for line in output.splitlines():
9981006
line = line.strip()
9991007
if line.startswith('Caption='):
@@ -1006,23 +1014,11 @@ def collect_windows(info_add):
10061014
info_add('windows.version', line)
10071015

10081016
# windows.ver: "ver" command
1009-
try:
1010-
proc = subprocess.Popen(["ver"], shell=True,
1011-
stdout=subprocess.PIPE,
1012-
stderr=subprocess.PIPE,
1013-
text=True)
1014-
output = proc.communicate()[0]
1015-
if proc.returncode == 0xc0000142:
1016-
return
1017-
if proc.returncode:
1018-
output = ""
1019-
except OSError:
1020-
return
1021-
else:
1022-
output = output.strip()
1023-
line = output.splitlines()[0]
1024-
if line:
1025-
info_add('windows.ver', line)
1017+
output = run_command(["ver"], shell=True)
1018+
if output:
1019+
first_line = output.splitlines()[0]
1020+
if first_line:
1021+
info_add('windows.ver', first_line)
10261022

10271023
# windows.developer_mode: get AllowDevelopmentWithoutDevLicense registry
10281024
value = winreg_query(r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows"
@@ -1136,11 +1132,21 @@ def get_machine_id():
11361132
def is_running_in_container():
11371133
# Check if the process in running in a container
11381134
import os.path
1135+
11391136
if os.path.exists('/.dockerenv'):
11401137
return 'docker'
11411138
if os.path.exists('/run/.containerenv'):
11421139
return 'podman'
11431140

1141+
container = read_first_line('/run/systemd/container')
1142+
if container:
1143+
return container
1144+
1145+
# Run systemd-detect-virt command
1146+
container = run_command(["systemd-detect-virt"])
1147+
if container and container != "none":
1148+
return container
1149+
11441150
# Other ways to check if running in a container:
11451151
# * Parse /proc/1/mounts or /proc/1/mountinfo (check "/" filesystem).
11461152
# * Parse /proc/1/cgroup.

0 commit comments

Comments
 (0)