Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions sos/collector/clusters/ocp.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,16 @@ def _label_sos_project(self):
)

def cleanup(self):
"""Remove the project we created to execute within
"""Remove the project we created to execute within.

Only attempt deletion when using 'oc' transport, as the temporary
namespace is only created in that case.
"""
if self.project:
# Check actual transport being used
actual_transport = self.set_transport_type()

if self.project and actual_transport == 'oc':
# Only delete namespace if using oc transport
try:
ret = self.exec_primary_cmd(
self.fmt_oc_cmd(f"delete project {self.project}"),
Expand All @@ -192,8 +199,8 @@ def cleanup(self):
)
if not ret['status'] == 0:
self.log_error(
f"Error waiting for temporary project to be deleted: "
f"{ret['output']}"
f"Error waiting for temporary project to be "
f"deleted: {ret['output']}"
)
except Exception as err:
self.log_error(
Expand All @@ -203,7 +210,15 @@ def cleanup(self):
)
# don't leave the config on a non-existing project
self.exec_primary_cmd(self.fmt_oc_cmd("project default"))
elif self.project:
# SSH transport - namespace was never created, just clear reference
self.log_debug(
f"Skipping project deletion for {actual_transport} transport"
)

if self.project:
self.project = None
Comment thread
pmoravec marked this conversation as resolved.

return True

def _build_dict(self, nodelist):
Expand Down
116 changes: 109 additions & 7 deletions sos/policies/distros/redhat.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,58 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True,
super().__init__(sysroot=sysroot, init=init,
probe_runtime=probe_runtime,
remote_exec=remote_exec)
self._rhel_version = self._get_rhel_version()

def _get_rhel_version(self):
"""Detect RHEL major version from RHEL_VERSION in /etc/os-release.

Parses RHEL_VERSION first (available on RHCOS 4.6+), falls back
to PLATFORM_ID (e.g. 'platform:el9').

:returns: RHEL major version as string ('8', '9', '10')
:rtype: ``str``
"""
os_release_content = None
if self.remote_exec:
ret = self.remote_exec('cat /etc/os-release')
if ret['status'] == 0:
os_release_content = ret['output']
else:
try:
os_release_path = self.join_sysroot('/etc/os-release')
with open(os_release_path, 'r', encoding='utf-8') as f:
os_release_content = f.read()
except (IOError, OSError) as err:
self.soslog.debug(
f"Unable to read /etc/os-release: {err}"
)

if os_release_content:
rhel_version = None
platform_id = None
for line in os_release_content.splitlines():
if line.startswith('RHEL_VERSION='):
rhel_version = line.split('=', 1)[1].strip().strip('"')
elif line.startswith('PLATFORM_ID='):
platform_id = line.split('=', 1)[1].strip().strip('"')
if rhel_version:
major = rhel_version.split('.')[0]
self.soslog.debug(
f"Detected RHEL major version: {major}"
)
return major
if platform_id and ':el' in platform_id:
major = platform_id.split(':el')[1]
self.soslog.debug(
f"Detected RHEL major version from "
f"PLATFORM_ID: {major}"
)
return major

self.soslog.debug(
"Unable to detect RHEL version, defaulting to '8'"
)
return '8'

@classmethod
def check(cls, remote=''):
Expand Down Expand Up @@ -459,20 +511,70 @@ def get_archive_name(self):

return archive_name

def _get_container_image(self):
"""Determine the container image to use for sos collection.

Checks /root/.toolboxrc for a custom REGISTRY/IMAGE override,
then falls back to the version-appropriate support-tools image.

:returns: The container image reference
:rtype: ``str``
"""
toolboxrc = self.join_sysroot('/root/.toolboxrc')
content = None
if self.remote_exec:
ret = self.remote_exec('cat /root/.toolboxrc')
if ret['status'] == 0:
content = ret['output']
else:
try:
with open(toolboxrc, 'r', encoding='utf-8') as f:
content = f.read()
except IOError:
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
# .toolboxrc is optional; fall back to default image
pass

if content:
registry = None
img = None
for line in content.splitlines():
line = line.strip()
if line.startswith('REGISTRY='):
registry = line.split('=', 1)[1].strip().strip('"')
elif line.startswith('IMAGE='):
img = line.split('=', 1)[1].strip().strip('"')
if registry and img:
self.soslog.info(
f"Using container image from .toolboxrc: "
f"{registry}/{img}"
)
return f"{registry}/{img}"

return (f"registry.redhat.io/rhel{self._rhel_version}/"
f"support-tools:latest")

def create_sos_container(self, image=None, auth=None, force_pull=False):
_image = image or self.container_image
_image = image or self._get_container_image()
_pull = '--pull=always' if force_pull else ''
self.soslog.info(
f"Using RHEL {self._rhel_version} support-tools image"
)
return (
f"{self.container_runtime} run -di "
f"{self.container_runtime} run -d "
f"--name {self.sos_container_name} --privileged --ipc=host "
f"--net=host --pid=host -e HOST=/host "
f"-e NAME={self.sos_container_name} -e "
f"IMAGE={_image} {_pull} "
f"-e NAME={self.sos_container_name} -e IMAGE={_image} "
f"{_pull} "
f"-v /run:/run -v /var/log:/var/log "
f"-v /etc/machine-id:/etc/machine-id "
f"-v /etc/localtime:/etc/localtime "
f"-v /:/host "
f"{auth or ''} {_image}"
f"-v /etc/localtime:/etc/localtime -v /:/host "
f"{auth or ''} {_image} sleep infinity"
Comment thread
pmoravec marked this conversation as resolved.
)

def restart_sos_container(self):
return (
f"{self.container_runtime} start "
Comment thread
pmoravec marked this conversation as resolved.
f"{self.sos_container_name}"
)

def set_cleanup_cmd(self):
Expand Down
Loading