NAS-133293 / 25.04 / remove psutil from truenas_install (#796)

This commit is contained in:
Caleb St. John
2024-12-28 16:18:59 -05:00
committed by GitHub
parent af1435d993
commit a506fbac05
5 changed files with 95 additions and 21 deletions

View File

@@ -6,7 +6,6 @@ idna==3.7
jsonschema==3.2.0
packaging==21.3
pexpect==4.8.0
psutil==5.8.0
ptyprocess==0.7.0
pyparsing==3.0.9
PyYAML==6.0.1

View File

@@ -1,8 +1,12 @@
import psutil
REQUIRED_RAM = 16 # GB
from functools import cache
REQUIRED_RAM_GB = 16 * (1024 ** 3)
__all__ = ("has_low_ram",)
@cache
def has_low_ram():
return psutil.virtual_memory().total < REQUIRED_RAM * 1024 * 1024 * 1024
with open('/proc/meminfo') as f:
for line in filter(lambda x: 'MemTotal' in x, f):
return int(line.split()[1]) * 1024 < REQUIRED_RAM_GB

View File

@@ -10,7 +10,6 @@ setup(
install_requires=[
'coloredlogs',
'toposort',
'psutil',
'requests',
'pyyaml'
],

View File

@@ -14,12 +14,11 @@ import subprocess
import sys
import tempfile
import psutil
from licenselib.license import ContractType, License
from .dhs import TRUENAS_DATA_HIERARCHY
from .fhs import TRUENAS_DATASETS
from .utils import getmntinfo, get_pids
logger = logging.getLogger(__name__)
@@ -185,23 +184,20 @@ def precheck(old_root):
pass
processes = defaultdict(list)
for p in psutil.process_iter():
processes[p.name()].append(p.pid)
for p in get_pids():
processes[p.name].append(p)
running_services = []
for service, title, process_name, cmdline in services:
if process_name in processes:
# If we report an enabled service, we don't want to report the same service running.
if title not in enabled_services:
for pid in processes[process_name]:
for proc in processes[process_name]:
if cmdline is not None:
try:
if cmdline not in psutil.Process(pid).cmdline():
continue
except psutil.NoSuchProcess:
if cmdline not in proc.cmdline.decode(errors="ignore"):
continue
try:
with open(f"/proc/{pid}/cgroup") as f:
with open(f"/proc/{proc.pid}/cgroup") as f:
cgroups = f.read().strip()
except FileNotFoundError:
cgroups = ""
@@ -276,10 +272,10 @@ def main():
old_root_dataset = None
if old_root is not None:
try:
old_root_dataset = next(p for p in psutil.disk_partitions() if p.mountpoint == old_root).device
except StopIteration:
pass
for i in getmntinfo():
if i.mountpoint == old_root:
old_root_dataset == i.mount_source
break
write_progress(0, "Creating dataset")
if input.get("dataset_name"):

76
truenas_install/utils.py Normal file
View File

@@ -0,0 +1,76 @@
from collections.abc import Generator
from dataclasses import dataclass
from functools import cached_property
from os import makedev, scandir
__all__ = ("get_pids", "getmntinfo",)
@dataclass(frozen=True, kw_only=True)
class PidEntry:
cmdline: bytes
pid: int
@cached_property
def name(self) -> bytes:
"""The name of process as described in man 2 PR_SET_NAME"""
with open(f"/proc/{self.pid}/status", "rb") as f:
# first line in this file is name of process
# and this is in procfs, which is considered
# part of linux's ABI and is stable
return f.readline().split(b"\t", 1)[-1].strip()
@dataclass(slots=True, frozen=True, kw_only=True)
class DevIdEntry:
major: int
minor: int
dev_t: int
@dataclass(slots=True, frozen=True, kw_only=True)
class MntEntry:
mount_id: int
parent_id: int
device_id: DevIdEntry
root: str
mountpoint: str
mount_opts: list[str]
fs_type: str
mount_source: str
super_opts: list[str]
def get_pids() -> Generator[PidEntry] | None:
"""Get the currently running processes on the OS"""
with scandir("/proc/") as sdir:
for i in filter(lambda x: x.name.isdigit(), sdir):
try:
with open(f"{i.path}/cmdline", "rb") as f:
cmdline = f.read().replace(b"\x00", b" ")
yield PidEntry(cmdline=cmdline, pid=int(i.name))
except FileNotFoundError:
# process could have gone away
pass
def getmntinfo() -> Generator[MntEntry]:
with open('/proc/self/mountinfo') as f:
for line in f:
mnt_id, parent_id, maj_min, root, mp, opts, extra = line.split(" ", 6)
fstype, mnt_src, super_opts = extra.split(' - ')[1].split()
major, minor = maj_min.split(':')
major, minor = int(major), int(minor)
devid = makedev(major, minor)
deventry = DevIdEntry(major=major, minor=minor, dev_t=devid)
yield MntEntry(**{
'mount_id': int(mnt_id),
'parent_id': int(parent_id),
'device_id': deventry,
'root': root.replace('\\040', ' '),
'mountpoint': mp.replace('\\040', ' '),
'mount_opts': opts.upper().split(','),
'fs_type': fstype,
'mount_source': mnt_src.replace('\\040', ' '),
'super_opts': super_opts.upper().split(','),
})