Skip to content

Commit 0887038

Browse files
author
xianglongfei
committed
Fixed the issue in sysinfo where the dmidecode and fdisk - l commands were executed.
1 parent 74b7379 commit 0887038

File tree

4 files changed

+146
-4
lines changed

4 files changed

+146
-4
lines changed

avocado/core/sysinfo.py

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import logging
1616
import os
1717
import time
18+
import configparser
1819

1920
from avocado.core import output
2021
from avocado.core.settings import settings
@@ -68,6 +69,41 @@ def __init__(self, basedir=None, log_packages=None, profiler=None):
6869
"""
6970
self.config = settings.as_dict()
7071

72+
# Retrieve the configured paths for sudo commands and distros from the settings dictionary
73+
sudo_commands_conf = self.config.get("sysinfo.sudo_commands", "")
74+
sudo_distros_conf = self.config.get("sysinfo.sudo_distros", "")
75+
76+
if sudo_commands_conf:
77+
log.info("sudo_commands loaded from config: %s", sudo_commands_conf)
78+
else:
79+
log.debug("sudo_commands config is empty or missing")
80+
81+
if sudo_distros_conf:
82+
log.info("sudo_distros loaded from config: %s", sudo_distros_conf)
83+
else:
84+
log.debug("sudo_distros config is empty or missing")
85+
86+
config = configparser.ConfigParser()
87+
candidates = [sudo_commands_conf, sudo_distros_conf]
88+
config.read([p for p in candidates if p])
89+
90+
# Retrieve the actual sudo commands and distros values from the config files,
91+
# falling back to empty string if the keys are missing
92+
sudo_commands_value = config.get("sysinfo", "sudo_commands", fallback="")
93+
sudo_distros_value = config.get("sysinfo", "sudo_distros", fallback="")
94+
95+
self.sudo_commands = {
96+
cmd.strip().lower()
97+
for cmd in sudo_commands_value.split(",")
98+
if cmd.strip()
99+
}
100+
101+
self.sudo_distros = {
102+
distro.strip().lower()
103+
for distro in sudo_distros_value.split(",")
104+
if distro.strip()
105+
}
106+
71107
if basedir is None:
72108
basedir = utils_path.init_dir("sysinfo")
73109
self.basedir = basedir
@@ -136,15 +172,33 @@ def _set_collectibles(self):
136172

137173
for cmd in self.sysinfo_files["commands"]:
138174
self.start_collectibles.add(
139-
sysinfo.Command(cmd, timeout=timeout, locale=locale)
175+
sysinfo.Command(
176+
cmd,
177+
timeout=timeout,
178+
locale=locale,
179+
sudo_commands=self.sudo_commands,
180+
sudo_distros=self.sudo_distros
181+
)
140182
)
141183
self.end_collectibles.add(
142-
sysinfo.Command(cmd, timeout=timeout, locale=locale)
184+
sysinfo.Command(
185+
cmd,
186+
timeout=timeout,
187+
locale=locale,
188+
sudo_commands=self.sudo_commands,
189+
sudo_distros=self.sudo_distros
190+
)
143191
)
144192

145193
for fail_cmd in self.sysinfo_files["fail_commands"]:
146194
self.end_fail_collectibles.add(
147-
sysinfo.Command(fail_cmd, timeout=timeout, locale=locale)
195+
sysinfo.Command(
196+
fail_cmd,
197+
timeout=timeout,
198+
locale=locale,
199+
sudo_commands=self.sudo_commands,
200+
sudo_distros=self.sudo_distros
201+
)
148202
)
149203

150204
for filename in self.sysinfo_files["files"]:

avocado/etc/avocado/sysinfo.conf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[sysinfo]
2+
sudo_commands = dmidecode,fdisk
3+
# Add any other commands that require sudo here, separated by commas.
4+
sudo_distros = uos,deepin
5+
# Add any other operating system that require sudo here, separated by commas.

avocado/plugins/sysinfo.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,25 @@ def initialize(self):
169169
help_msg=help_msg,
170170
)
171171

172+
help_msg = "File with list of commands that require sudo"
173+
default = system_wide_or_base_path("etc/avocado/sysinfo.conf")
174+
settings.register_option(
175+
section="sysinfo",
176+
key="sudo_commands",
177+
key_type=prepend_base_path,
178+
default=default,
179+
help_msg=help_msg,
180+
)
181+
182+
help_msg = "File with list of distributions that require sudo"
183+
settings.register_option(
184+
section="sysinfo",
185+
key="sudo_distros",
186+
key_type=prepend_base_path,
187+
default=default,
188+
help_msg=help_msg,
189+
)
190+
172191

173192
class SysInfoJob(JobPreTests, JobPostTests):
174193

avocado/utils/sysinfo.py

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818
import shlex
1919
import subprocess
2020
import tempfile
21+
import platform
22+
import logging
2123
from abc import ABC, abstractmethod
2224

2325
from avocado.utils import astring, process
2426

2527
DATA_SIZE = 200000
28+
log = logging.getLogger("avocado.sysinfo")
2629

2730

2831
class CollectibleException(Exception):
@@ -132,12 +135,16 @@ class Command(Collectible):
132135
:param locale: Force LANG for sysinfo collection
133136
"""
134137

135-
def __init__(self, cmd, timeout=-1, locale="C"):
138+
def __init__(
139+
self, cmd, timeout=-1, locale="C", sudo_commands=None, sudo_distros=None
140+
):
136141
super().__init__(cmd)
137142
self._name = self.log_path
138143
self.cmd = cmd
139144
self.timeout = timeout
140145
self.locale = locale
146+
self.sudo_commands = sudo_commands
147+
self.sudo_distros = sudo_distros
141148

142149
def __repr__(self):
143150
r = "Command(%r, %r)"
@@ -168,6 +175,12 @@ def collect(self):
168175
# but the avocado.utils.process APIs define no timeouts as "None"
169176
if int(self.timeout) <= 0:
170177
self.timeout = None
178+
179+
# Determine whether to run with sudo (do not mutate the command string)
180+
sysinfo_cmd = SysinfoCommand(self.sudo_commands, self.sudo_distros)
181+
sudo_flag = sysinfo_cmd.use_sudo() and sysinfo_cmd.is_sudo_cmd(self.cmd)
182+
log.info("Executing Command%s: %s", " (sudo)" if sudo_flag else "", self.cmd)
183+
171184
try:
172185
result = process.run(
173186
self.cmd,
@@ -176,6 +189,7 @@ def collect(self):
176189
ignore_status=True,
177190
shell=True,
178191
env=env,
192+
sudo=sudo_flag,
179193
)
180194
yield result.stdout
181195
except FileNotFoundError as exc_fnf:
@@ -394,3 +408,53 @@ def collect(self):
394408
raise CollectibleException(
395409
f"Not logging {self.path} " f"(lack of permissions)"
396410
) from exc
411+
412+
413+
class SysinfoCommand:
414+
def __init__(self, sudo_commands=None, sudo_distros=None):
415+
from avocado.utils.process import can_sudo
416+
self.sudo_available = can_sudo()
417+
self.sudo_cmds = sudo_commands if sudo_commands else set()
418+
self.sudo_distros = sudo_distros if sudo_distros else set()
419+
420+
def use_sudo(self):
421+
"""
422+
Determine if 'sudo' should be used based on the system type.
423+
424+
Returns:
425+
bool: True if 'sudo' should be used, False otherwise.
426+
"""
427+
if not self.sudo_available:
428+
return False
429+
system_name = platform.system().lower()
430+
if system_name == "linux":
431+
if hasattr(os, "geteuid") and os.geteuid() == 0:
432+
return False
433+
try:
434+
with open("/etc/os-release") as f:
435+
for line in f:
436+
if line.startswith("ID="):
437+
os_id = line.strip().split("=")[1].strip('"')
438+
return os_id.lower() in self.sudo_distros
439+
except FileNotFoundError:
440+
log.debug("/etc/os-release not found.")
441+
return False
442+
return False
443+
return False
444+
445+
def is_sudo_cmd(self, cmd):
446+
"""
447+
Determine if 'sudo' should be used for a specific command based on the configuration.
448+
449+
Args:
450+
cmd (str): The command to check.
451+
452+
Returns:
453+
bool: True if 'sudo' should be used, False otherwise.
454+
"""
455+
try:
456+
first = shlex.split(cmd or "")[0]
457+
except (ValueError, IndexError):
458+
return False
459+
base = os.path.basename(first).lower()
460+
return base in self.sudo_cmds

0 commit comments

Comments
 (0)