Utilities¶
Helper modules used across sts-libs.
Command Line¶
sts.utils.cmdline
¶
Command execution: run(), run_argv(), and BackgroundCommand.
BackgroundCommand
¶
A background subprocess with managed lifecycle.
Created via run_background() or run_background_argv().
Always reap with stop() or wait() to avoid zombie processes.
Output is captured to temporary files so the child never blocks on a full pipe buffer.
Source code in sts_libs/src/sts/utils/cmdline.py
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | |
pid
property
¶
OS process ID.
running
property
¶
True if the process has not yet exited.
stop(timeout=30)
¶
Terminate the process and return its result.
Source code in sts_libs/src/sts/utils/cmdline.py
205 206 207 208 | |
wait(timeout=None)
¶
Wait for the process to exit on its own, then return its result.
Source code in sts_libs/src/sts/utils/cmdline.py
210 211 212 213 214 215 216 217 218 | |
CommandResult
pydantic-model
¶
Bases: ReportModel
Result of a command execution.
Show JSON schema:
{
"additionalProperties": false,
"description": "Result of a command execution.",
"properties": {
"command": {
"title": "Command",
"type": "string"
},
"rc": {
"title": "Rc",
"type": "integer"
},
"stdout": {
"default": "",
"title": "Stdout",
"type": "string"
},
"stderr": {
"default": "",
"title": "Stderr",
"type": "string"
},
"timed_out": {
"default": false,
"title": "Timed Out",
"type": "boolean"
}
},
"required": [
"command",
"rc"
],
"title": "CommandResult",
"type": "object"
}
Config:
extra:forbid
Fields:
-
command(str) -
rc(int) -
stdout(str) -
stderr(str) -
timed_out(bool)
Source code in sts_libs/src/sts/utils/cmdline.py
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | |
assert_ok(msg=None)
¶
Raise if the command failed; return self for chaining.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
msg
|
str | None
|
Optional context message prepended to the error. |
None
|
Raises:
| Type | Description |
|---|---|
STSError
|
If the command failed, with command, rc, and stderr. |
Source code in sts_libs/src/sts/utils/cmdline.py
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | |
build_options(**options)
¶
Build CLI option list from keyword arguments.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**options
|
str | int | bool | None
|
Keyword arguments where underscores become hyphens.
True → |
{}
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of CLI option strings. |
Example
build_options(report_format='json', yes=True)
# ['--report-format=json', '--yes']
Source code in sts_libs/src/sts/utils/cmdline.py
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | |
exists(cmd)
¶
Check if command exists in PATH.
Source code in sts_libs/src/sts/utils/cmdline.py
161 162 163 | |
run(cmd, msg=None, timeout=600, log_level=logging.INFO)
¶
Run a shell command and return a CommandResult.
Source code in sts_libs/src/sts/utils/cmdline.py
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | |
run_argv(argv, msg=None, timeout=600, log_level=logging.INFO)
¶
Run a command from an argument vector (no shell) and return a CommandResult.
Source code in sts_libs/src/sts/utils/cmdline.py
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | |
run_background(cmd)
¶
Start a shell command in the background.
Source code in sts_libs/src/sts/utils/cmdline.py
260 261 262 263 264 265 266 267 268 269 270 271 | |
run_background_argv(argv)
¶
Start a command from an argument vector in the background.
Source code in sts_libs/src/sts/utils/cmdline.py
274 275 276 277 278 279 280 281 282 283 284 285 | |
wait_for_device_io(device, *, timeout=10.0, poll_interval=0.1)
¶
Block until at least one new I/O operation completes on a block device.
Returns True if I/O was observed, False on timeout.
Source code in sts_libs/src/sts/utils/cmdline.py
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 | |
System Management¶
sts.utils.system
¶
System information, service management, and time control.
LogFormat
¶
Bases: Enum
Log format options.
Source code in sts_libs/src/sts/utils/system.py
63 64 65 66 67 68 | |
LogOptions
pydantic-model
¶
Bases: StsBaseModel
Options for SystemManager.get_logs().
Show JSON schema:
{
"$defs": {
"LogFormat": {
"description": "Log format options.",
"enum": [
1,
2,
3
],
"title": "LogFormat",
"type": "integer"
}
},
"additionalProperties": false,
"description": "Options for ``SystemManager.get_logs()``.",
"properties": {
"format": {
"$ref": "#/$defs/LogFormat",
"default": 1
},
"length": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Length"
},
"since": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Since"
},
"grep": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Grep"
},
"options": {
"items": {
"type": "string"
},
"title": "Options",
"type": "array"
}
},
"title": "LogOptions",
"type": "object"
}
Fields:
-
format(LogFormat) -
length(int | None) -
since(str | None) -
grep(str | None) -
options(list[str])
Source code in sts_libs/src/sts/utils/system.py
71 72 73 74 75 76 77 78 | |
SystemInfo
pydantic-model
¶
Bases: StsBaseModel
Lazily-discovered system information (hostname, kernel, arch, distro).
Show JSON schema:
{
"additionalProperties": false,
"description": "Lazily-discovered system information (hostname, kernel, arch, distro).",
"properties": {},
"title": "SystemInfo",
"type": "object"
}
Source code in sts_libs/src/sts/utils/system.py
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | |
arch
property
¶
System architecture (cached).
codename
property
¶
Distribution codename from os-release (cached).
distribution
property
¶
Distribution ID from os-release (cached).
hostname
property
¶
System hostname (cached).
in_container
property
¶
True if running inside a container.
is_debug
property
¶
True if running a +debug kernel.
kernel
property
¶
Kernel version string (cached).
release
property
¶
Distribution VERSION_ID from os-release (cached).
version
property
¶
Distribution release parsed as VersionInfo.
get_current()
classmethod
¶
Create a SystemInfo (properties are discovered lazily).
Source code in sts_libs/src/sts/utils/system.py
146 147 148 149 | |
log_all()
¶
Log all system information at debug level.
Source code in sts_libs/src/sts/utils/system.py
170 171 172 173 174 175 176 177 | |
SystemManager
¶
System logs, sosreport generation, and systemd service management.
Source code in sts_libs/src/sts/utils/system.py
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | |
clear_logs()
staticmethod
¶
Clear dmesg.
Source code in sts_libs/src/sts/utils/system.py
249 250 251 252 | |
daemon_reload()
staticmethod
¶
Run systemctl daemon-reload (needed after fstab or generator changes).
Source code in sts_libs/src/sts/utils/system.py
300 301 302 303 304 | |
escape_path_to_unit(path, unit_type=None)
staticmethod
¶
Escape a path to a systemd unit name via systemd-escape.
Source code in sts_libs/src/sts/utils/system.py
315 316 317 318 319 320 321 322 323 324 325 326 | |
generate_sosreport(skip_plugins=None, plugin_timeout=300)
staticmethod
¶
Generate a sosreport, returning the archive path or None on failure.
Source code in sts_libs/src/sts/utils/system.py
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | |
get_logs(options=None)
staticmethod
¶
Get system logs via journalctl, formatted to match /var/log/messages.
Source code in sts_libs/src/sts/utils/system.py
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | |
get_timestamp(timezone_='local')
staticmethod
¶
Current timestamp as 'YYYYMMDDhhmmss'.
Source code in sts_libs/src/sts/utils/system.py
244 245 246 247 | |
get_unit_property(unit, prop)
staticmethod
¶
Get a systemd unit property via systemctl show.
Source code in sts_libs/src/sts/utils/system.py
306 307 308 309 310 311 312 313 | |
is_service_enabled(service)
staticmethod
¶
Check if a systemd service is enabled.
Source code in sts_libs/src/sts/utils/system.py
254 255 256 257 258 | |
is_service_running(service)
staticmethod
¶
Check if a systemd service is active.
Source code in sts_libs/src/sts/utils/system.py
260 261 262 263 264 | |
service_disable(service)
staticmethod
¶
Disable a systemd service.
Source code in sts_libs/src/sts/utils/system.py
276 277 278 279 280 | |
service_enable(service)
¶
Enable a systemd service.
Source code in sts_libs/src/sts/utils/system.py
271 272 273 274 | |
service_exists(service)
¶
Check if a systemd unit file exists.
Source code in sts_libs/src/sts/utils/system.py
266 267 268 269 | |
service_restart(service)
staticmethod
¶
Restart a systemd service.
Source code in sts_libs/src/sts/utils/system.py
294 295 296 297 298 | |
service_start(service)
staticmethod
¶
Start a systemd service.
Source code in sts_libs/src/sts/utils/system.py
282 283 284 285 286 | |
service_stop(service)
staticmethod
¶
Stop a systemd service.
Source code in sts_libs/src/sts/utils/system.py
288 289 290 291 292 | |
test_service(service)
¶
Run enable/disable, start/stop, and restart cycles on a service.
Source code in sts_libs/src/sts/utils/system.py
364 365 366 367 368 369 370 371 372 373 374 375 | |
TimeController
¶
Temporarily shift system time for testing (requires root).
Example
tc = TimeController()
tc.disable_ntp()
try:
with tc.time_offset(hours=-5):
create_something_timestamped()
finally:
tc.enable_ntp()
Source code in sts_libs/src/sts/utils/system.py
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 | |
disable_ntp()
¶
Disable NTP (saves prior state for restore_ntp()).
Source code in sts_libs/src/sts/utils/system.py
401 402 403 404 405 406 407 408 | |
enable_ntp()
¶
Enable NTP synchronization (triggers time sync).
Source code in sts_libs/src/sts/utils/system.py
410 411 412 413 414 415 416 | |
is_ntp_enabled()
¶
Check if NTP synchronization is enabled.
Source code in sts_libs/src/sts/utils/system.py
396 397 398 399 | |
restore_ntp()
¶
Restore NTP to its state before disable_ntp() was called.
Source code in sts_libs/src/sts/utils/system.py
418 419 420 421 422 423 424 425 | |
set_time(time_str)
¶
Set system time (format: 'YYYY-MM-DD HH:MM:SS').
Source code in sts_libs/src/sts/utils/system.py
427 428 429 430 431 432 433 434 | |
set_time_offset(hours=0, days=0)
¶
Set system time to an offset from now (negative = past).
Source code in sts_libs/src/sts/utils/system.py
436 437 438 439 440 441 | |
time_offset(hours=0, days=0)
¶
Context manager that shifts system time for the duration of the block.
NTP must be disabled before entering. Time is NOT auto-restored on exit --
call enable_ntp() in a finally block to re-sync.
Source code in sts_libs/src/sts/utils/system.py
443 444 445 446 447 448 449 450 451 452 453 | |
Package Management¶
sts.utils.packages
¶
RPM package management (dnf, rpm-ostree) and repository configuration.
Dnf
¶
DNF package manager operations.
Source code in sts_libs/src/sts/utils/packages.py
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | |
add_repo(config)
¶
Write a .repo file for the given configuration (no-op if it already exists).
Source code in sts_libs/src/sts/utils/packages.py
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | |
download_repo(url, name=None, *, overwrite=True)
¶
Download a .repo file from url into /etc/yum.repos.d/.
Source code in sts_libs/src/sts/utils/packages.py
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | |
install(package)
staticmethod
¶
Install package (no-op if already installed).
Source code in sts_libs/src/sts/utils/packages.py
72 73 74 75 76 77 78 79 80 81 82 83 84 | |
remove(package)
staticmethod
¶
Remove package (no-op if not installed).
Source code in sts_libs/src/sts/utils/packages.py
86 87 88 89 90 91 92 93 94 95 96 97 98 | |
remove_repo(name)
¶
Delete the .repo file for a repository.
Source code in sts_libs/src/sts/utils/packages.py
122 123 124 125 126 127 128 129 130 131 | |
repo_enabled(name)
¶
Check if repository exists and is enabled.
Source code in sts_libs/src/sts/utils/packages.py
142 143 144 145 146 147 148 149 150 151 152 | |
repo_exists(name)
staticmethod
¶
Check if repository exists via dnf repoinfo.
Source code in sts_libs/src/sts/utils/packages.py
133 134 135 136 137 138 139 140 | |
PackageInfo
pydantic-model
¶
Bases: ReportModel
RPM package information.
Show JSON schema:
{
"description": "RPM package information.",
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"is_installed": {
"title": "Is Installed",
"type": "boolean"
},
"version": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Version"
},
"release": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Release"
}
},
"required": [
"name",
"is_installed"
],
"title": "PackageInfo",
"type": "object"
}
Fields:
-
name(str) -
is_installed(bool) -
version(str | None) -
release(str | None)
Source code in sts_libs/src/sts/utils/packages.py
18 19 20 21 22 23 24 | |
RepoConfig
pydantic-model
¶
Bases: StsBaseModel
DNF repository configuration (baseurl or metalink).
Show JSON schema:
{
"additionalProperties": false,
"description": "DNF repository configuration (baseurl or metalink).",
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"baseurl": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Baseurl"
},
"metalink": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Metalink"
},
"enabled": {
"default": true,
"title": "Enabled",
"type": "boolean"
},
"gpgcheck": {
"default": false,
"title": "Gpgcheck",
"type": "boolean"
},
"skip_if_unavailable": {
"default": true,
"title": "Skip If Unavailable",
"type": "boolean"
}
},
"required": [
"name"
],
"title": "RepoConfig",
"type": "object"
}
Fields:
-
name(str) -
baseurl(str | None) -
metalink(str | None) -
enabled(bool) -
gpgcheck(bool) -
skip_if_unavailable(bool)
Source code in sts_libs/src/sts/utils/packages.py
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | |
to_config()
¶
Convert to .repo file key-value pairs.
Source code in sts_libs/src/sts/utils/packages.py
51 52 53 54 55 56 57 58 59 60 61 62 63 | |
RpmOstree
¶
RPM-OSTree package manager operations.
Source code in sts_libs/src/sts/utils/packages.py
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | |
install(package)
staticmethod
¶
Install package via rpm-ostree (no-op if already installed).
Source code in sts_libs/src/sts/utils/packages.py
180 181 182 183 184 185 186 187 188 189 190 191 192 | |
remove(package)
staticmethod
¶
Remove package via rpm-ostree (no-op if not installed).
Source code in sts_libs/src/sts/utils/packages.py
194 195 196 197 198 199 200 201 202 203 204 205 206 | |
check_rpm_ostree_status()
¶
Check if the system is managed by rpm-ostree (cached).
Source code in sts_libs/src/sts/utils/packages.py
212 213 214 215 216 217 | |
ensure_installed(*packages)
¶
Install any missing packages, auto-detecting dnf vs rpm-ostree.
Source code in sts_libs/src/sts/utils/packages.py
220 221 222 223 224 | |
get_package(name)
¶
Query RPM for package installation status and version.
Source code in sts_libs/src/sts/utils/packages.py
27 28 29 30 31 32 33 34 35 36 37 38 | |
get_package_version(package_name)
¶
Get installed package version as VersionInfo, or None if not installed.
Source code in sts_libs/src/sts/utils/packages.py
227 228 229 230 231 232 | |
log_package_versions(*package_names)
¶
Log installed version (or 'not installed') for each package.
Source code in sts_libs/src/sts/utils/packages.py
235 236 237 238 239 240 241 242 243 | |
Module Management¶
sts.utils.modules
¶
Kernel module loading, unloading, and introspection.
ManagedModule
¶
Acquire a kernel module and release only a load owned by this object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Kernel module name. |
required |
parameters
|
Mapping[str, str | int | bool] | None
|
Parameters verified after loading and passed to modprobe. |
None
|
load_only_parameters
|
Mapping[str, str | int | bool] | None
|
Extra parameters passed to modprobe but not
verified via sysfs (e.g. trigger parameters like |
None
|
exclusive
|
bool
|
Refuse acquisition when the module was already loaded. |
False
|
unreadable_parameters_postcondition
|
Callable[[], bool] | None
|
Explicit fallback used only after this object loads a module and none of the requested parameters can be read back. |
None
|
Source code in sts_libs/src/sts/utils/modules.py
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 | |
owns_load
property
¶
Whether this lifecycle currently owns the module load.
__enter__()
¶
Acquire the module for a with block.
Source code in sts_libs/src/sts/utils/modules.py
434 435 436 | |
__exit__(_exc_type, exc_value, _traceback)
¶
Release the module acquired for a with block or surface cleanup failure.
Source code in sts_libs/src/sts/utils/modules.py
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 | |
acquire()
¶
Make the module available or raise an explicit acquisition outcome.
Missing modules and exclusive conflicts are typed pre-mutation outcomes.
Load and post-load verification failures are typed setup errors. Any
failed rollback retains ownership for a later :meth:release retry.
Source code in sts_libs/src/sts/utils/modules.py
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 | |
release(timeout=DEFAULT_TIMEOUT)
¶
Unload an owned module within a bounded retry window.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
timeout
|
float
|
Maximum number of seconds to retry unload or confirm absence. |
DEFAULT_TIMEOUT
|
Source code in sts_libs/src/sts/utils/modules.py
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 | |
ModuleInfo
pydantic-model
¶
Bases: StsBaseModel
Kernel module state from /proc/modules and sysfs.
Call discover() after construction to populate from the system.
Show JSON schema:
{
"additionalProperties": false,
"description": "Kernel module state from /proc/modules and sysfs.\n\nCall ``discover()`` after construction to populate from the system.",
"properties": {
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Name"
},
"size": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Size"
},
"refcount": {
"default": 0,
"title": "Refcount",
"type": "integer"
},
"used_by": {
"items": {
"type": "string"
},
"title": "Used By",
"type": "array"
},
"state": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "State"
},
"address": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Address"
},
"parameters": {
"additionalProperties": true,
"title": "Parameters",
"type": "object"
}
},
"title": "ModuleInfo",
"type": "object"
}
Fields:
-
name(str | None) -
size(int | None) -
refcount(int) -
used_by(list[str]) -
state(str | None) -
address(str | None) -
parameters(dict[str, Any])
Source code in sts_libs/src/sts/utils/modules.py
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | |
exists
property
¶
True if modinfo can find this module.
loaded
property
¶
True if the module is currently loaded.
state_observed
property
¶
Whether the last discovery read a valid /proc/modules snapshot.
discover()
¶
Load module state from /proc/modules and sysfs; returns self for chaining.
Source code in sts_libs/src/sts/utils/modules.py
70 71 72 73 | |
from_name(name)
classmethod
¶
Get module info by name, or None if the module doesn't exist.
Source code in sts_libs/src/sts/utils/modules.py
240 241 242 243 244 | |
get_parameter_names()
¶
Return module parameter names advertised by modinfo.
Source code in sts_libs/src/sts/utils/modules.py
159 160 161 162 163 164 165 166 167 | |
load(parameters=None, *, raise_on_error=False)
¶
Load module via modprobe.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parameters
|
str | Mapping[str, str | int | bool] | None
|
Module parameters as a shell-like string or mapping. They
are always passed to |
None
|
raise_on_error
|
bool
|
Raise :class: |
False
|
Source code in sts_libs/src/sts/utils/modules.py
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | |
unload()
¶
Unload module via modprobe -r.
Source code in sts_libs/src/sts/utils/modules.py
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | |
unload_with_dependencies()
¶
Recursively unload this module and all modules that depend on it.
Source code in sts_libs/src/sts/utils/modules.py
225 226 227 228 229 230 231 232 233 234 235 236 237 238 | |
ModuleManager
¶
Higher-level kernel module operations with timeout-based state waiting.
Source code in sts_libs/src/sts/utils/modules.py
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | |
get_all()
¶
Get all currently loaded modules.
Source code in sts_libs/src/sts/utils/modules.py
254 255 256 257 258 259 260 261 262 263 264 265 266 267 | |
get_parameters(name)
staticmethod
¶
Get module parameters from sysfs.
Source code in sts_libs/src/sts/utils/modules.py
269 270 271 272 273 274 | |
load(name, parameters=None, timeout=DEFAULT_TIMEOUT)
¶
Load module and wait for it to appear (no-op if already loaded).
Source code in sts_libs/src/sts/utils/modules.py
276 277 278 279 280 281 282 283 284 285 286 287 288 289 | |
unload(name, timeout=DEFAULT_TIMEOUT)
¶
Unload module and wait for it to disappear (no-op if not loaded).
Source code in sts_libs/src/sts/utils/modules.py
291 292 293 294 295 296 297 298 299 | |
unload_with_dependencies(name, timeout=DEFAULT_TIMEOUT)
¶
Recursively unload module and its dependents.
Source code in sts_libs/src/sts/utils/modules.py
301 302 303 304 305 306 307 308 309 | |
parameters_match(actual, expected)
¶
Return whether sysfs parameter readback matches the requested configuration.
Kernel boolean parameters may read back as Y/N while the caller
passes True/False or 1/0. Both forms are accepted.
Source code in sts_libs/src/sts/utils/modules.py
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | |
File Operations¶
sts.utils.files
¶
File/directory operations, mount/umount, mkfs, checksum helpers.
DirAccessError
¶
Bases: DirectoryError
Directory cannot be accessed.
Source code in sts_libs/src/sts/utils/files.py
42 43 | |
DirNotFoundError
¶
Bases: DirectoryError
Directory does not exist.
Source code in sts_libs/src/sts/utils/files.py
34 35 | |
DirTypeError
¶
Bases: DirectoryError
Path exists but is not a directory.
Source code in sts_libs/src/sts/utils/files.py
38 39 | |
Directory
pydantic-model
¶
Bases: StsBaseModel
Directory wrapper with optional auto-creation.
Attributes:
| Name | Type | Description |
|---|---|---|
create |
bool
|
If True, create the directory (with parents) on construction. |
Show JSON schema:
{
"additionalProperties": false,
"description": "Directory wrapper with optional auto-creation.\n\nAttributes:\n create: If True, create the directory (with parents) on construction.",
"properties": {
"path": {
"format": "path",
"title": "Path",
"type": "string"
},
"create": {
"default": false,
"title": "Create",
"type": "boolean"
},
"mode": {
"default": 493,
"title": "Mode",
"type": "integer"
}
},
"title": "Directory",
"type": "object"
}
Fields:
-
path(Path) -
create(bool) -
mode(int)
Validators:
-
_create_if_requested
Source code in sts_libs/src/sts/utils/files.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | |
exists
property
¶
True if path exists and is a directory.
count_files()
¶
Count files in directory (excluding subdirectories).
Source code in sts_libs/src/sts/utils/files.py
125 126 127 128 | |
iter_files(*, recursive=False)
¶
Yield Path objects for each file in the directory.
Source code in sts_libs/src/sts/utils/files.py
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | |
remove_dir()
¶
Remove directory and all its contents.
Source code in sts_libs/src/sts/utils/files.py
143 144 145 146 147 148 149 | |
remove_file(file)
staticmethod
¶
Remove file, logging errors on failure.
Source code in sts_libs/src/sts/utils/files.py
117 118 119 120 121 122 123 | |
rm_files_containing(pattern, *, invert=False)
¶
Delete files whose contents match (or don't match) pattern.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pattern
|
str
|
Substring to search for in file contents. |
required |
invert
|
bool
|
If True, delete files that do NOT contain the pattern. |
False
|
Source code in sts_libs/src/sts/utils/files.py
130 131 132 133 134 135 136 137 138 139 140 141 | |
should_remove_file_with_pattern(file, pattern)
staticmethod
¶
True if file contents contain pattern.
Source code in sts_libs/src/sts/utils/files.py
97 98 99 100 101 102 103 104 105 | |
should_remove_file_without_pattern(file, pattern)
staticmethod
¶
True if file contents do NOT contain pattern.
Source code in sts_libs/src/sts/utils/files.py
107 108 109 110 111 112 113 114 115 | |
validate_exists()
¶
Raise DirNotFoundError / DirTypeError if path is not a valid directory.
Source code in sts_libs/src/sts/utils/files.py
72 73 74 75 76 77 | |
DirectoryError
¶
Bases: STSError
Base class for directory-related errors.
Source code in sts_libs/src/sts/utils/files.py
30 31 | |
change_directory(path)
¶
Temporarily change working directory, restoring on exit.
Source code in sts_libs/src/sts/utils/files.py
152 153 154 155 156 157 158 159 160 | |
checksum(path)
¶
Compute the SHA-256 hex digest of a file, or None on failure.
Source code in sts_libs/src/sts/utils/files.py
399 400 401 402 403 404 405 406 407 408 409 | |
count_files(directory=None)
¶
Count files in directory (defaults to cwd).
Source code in sts_libs/src/sts/utils/files.py
163 164 165 166 | |
fallocate(path, *args, **kwargs)
¶
Preallocate or deallocate space for a file.
Source code in sts_libs/src/sts/utils/files.py
311 312 313 314 315 316 317 318 319 320 | |
get_free_space(path=None)
¶
Get free space in bytes for the filesystem containing path.
Source code in sts_libs/src/sts/utils/files.py
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | |
is_mounted(device=None, mountpoint=None)
¶
Check whether a device is mounted or a path is an exact mountpoint.
Source code in sts_libs/src/sts/utils/files.py
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | |
mkfs(device=None, fs_type=None, *args, force=False)
¶
Create filesystem on device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device
|
str | Path | None
|
Block device path. |
None
|
fs_type
|
str | None
|
Filesystem type (e.g. 'ext4', 'xfs'). |
None
|
force
|
bool
|
Add the filesystem-specific force flag ( |
False
|
Source code in sts_libs/src/sts/utils/files.py
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | |
mount(device=None, mountpoint=None, fs_type=None, options=None)
¶
Mount device at mountpoint (creates mountpoint directory if needed).
Source code in sts_libs/src/sts/utils/files.py
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | |
mounted(device, mountpoint, *, fs_type=None, options=None)
¶
Mount a device for a block and always attempt to unmount it afterwards.
Source code in sts_libs/src/sts/utils/files.py
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | |
rm_files_containing(directory=None, pattern='', *, invert=False)
¶
Delete files whose contents match (or don't match) pattern.
Source code in sts_libs/src/sts/utils/files.py
169 170 171 172 | |
unmount(mountpoint, /, *, force=False, missing_ok=True)
¶
Unmount an exact mountpoint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mountpoint
|
str | Path
|
Mounted path to unmount. |
required |
force
|
bool
|
Pass |
False
|
missing_ok
|
bool
|
Treat an already-unmounted mountpoint as success. |
True
|
Returns:
| Type | Description |
|---|---|
CommandResult
|
The real command result, or a successful no-op result when allowed. |
Source code in sts_libs/src/sts/utils/files.py
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | |
verify_checksum(path, expected)
¶
Verify a file's SHA-256 checksum matches expected.
Source code in sts_libs/src/sts/utils/files.py
412 413 414 415 416 417 418 419 420 421 | |
write_data(target, source, *, sync=True, **kwargs)
¶
Write data using dd.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str | Path
|
Target file/device path. |
required |
source
|
str | Path
|
Source path (e.g. '/dev/urandom', '/dev/zero'). |
required |
sync
|
bool
|
Run |
True
|
**kwargs
|
str | int
|
Passed as |
{}
|
Source code in sts_libs/src/sts/utils/files.py
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 | |
write_zeroes(target, *, sync=True, **kwargs)
¶
Write zeroes using dd (convenience wrapper around write_data).
Source code in sts_libs/src/sts/utils/files.py
364 365 366 367 368 369 370 371 | |
Configuration Files¶
sts.utils.config
¶
Key=value configuration file management with comment preservation.
Config
¶
Base configuration class for managing configuration files.
Source code in sts_libs/src/sts/utils/config.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | |
__init__(config_path)
¶
Load configuration from config_path (if it exists).
Source code in sts_libs/src/sts/utils/config.py
21 22 23 24 25 26 27 | |
get_parameter(name)
¶
Get parameter value, or None if not set.
Source code in sts_libs/src/sts/utils/config.py
58 59 60 | |
remove_parameters(keys)
¶
Mark configuration parameters for removal.
Removed keys are dropped from parameters immediately and their
lines are omitted from the file the next time save() runs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
keys
|
Iterable[str]
|
Parameter names to remove |
required |
Source code in sts_libs/src/sts/utils/config.py
45 46 47 48 49 50 51 52 53 54 55 56 | |
save()
¶
Write parameters back to the file, preserving comments and ordering.
Source code in sts_libs/src/sts/utils/config.py
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | |
set_parameters(parameters)
¶
Update multiple parameters at once.
Source code in sts_libs/src/sts/utils/config.py
41 42 43 | |
Fstab Management¶
sts.utils.fstab
¶
/etc/fstab entry management with backup/restore and a temporary_entry context manager.
The temporary_entry context manager is useful for tests that need a
mount point registered in fstab (e.g., snapm mount manager tests).
Fstab
¶
Manage /etc/fstab entries.
Provides static methods for querying mount information and managing fstab entries with backup/restore support.
Source code in sts_libs/src/sts/utils/fstab.py
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | |
add_entry(device, mount_point, fs_type, options='defaults', dump=0, fsck_pass=0)
staticmethod
¶
Append an entry to /etc/fstab.
Source code in sts_libs/src/sts/utils/fstab.py
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | |
backup()
staticmethod
¶
Create a backup of /etc/fstab and return its path.
Source code in sts_libs/src/sts/utils/fstab.py
123 124 125 126 127 128 129 | |
get_device(mount_point)
staticmethod
¶
Get the source device for a mounted filesystem via findmnt.
Source code in sts_libs/src/sts/utils/fstab.py
50 51 52 53 54 55 56 | |
get_fstype(mount_point)
staticmethod
¶
Get the filesystem type for a mounted filesystem via findmnt.
Source code in sts_libs/src/sts/utils/fstab.py
58 59 60 61 62 63 64 | |
has_entry(mount_point)
staticmethod
¶
Check whether a mount point already has an fstab entry.
Source code in sts_libs/src/sts/utils/fstab.py
66 67 68 69 70 71 72 73 74 75 76 77 78 79 | |
remove_entry(mount_point)
staticmethod
¶
Remove all fstab entries for a given mount point.
Source code in sts_libs/src/sts/utils/fstab.py
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | |
restore(backup_path=None)
staticmethod
¶
Restore /etc/fstab from a backup (defaults to the standard backup location).
Source code in sts_libs/src/sts/utils/fstab.py
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | |
temporary_entry(mount_point, options='defaults')
staticmethod
¶
Temporarily add a mount point to /etc/fstab with automatic rollback.
Discovers the device and filesystem type from the live mount via findmnt, backs up fstab, adds the entry, and restores the original fstab on exit (even if an exception occurs).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mount_point
|
Path
|
Path of the currently mounted filesystem to add |
required |
options
|
str
|
Mount options for the fstab entry (default: 'defaults') |
'defaults'
|
Example
with Fstab.temporary_entry(Path('/mnt/test')):
# /mnt/test is now in /etc/fstab
snapset.mount() # snapm can now find the entry
# Original fstab is restored
Source code in sts_libs/src/sts/utils/fstab.py
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | |
without_remote_entries()
staticmethod
¶
Temporarily remove remote filesystem entries from /etc/fstab.
Backs up fstab, removes entries with network filesystem types (NFS, CIFS, etc.), and restores the original on exit.
Uses a separate backup file from backup() so this context
manager can nest safely with temporary_entry().
Source code in sts_libs/src/sts/utils/fstab.py
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | |
NFS Exports¶
sts.utils.nfs
¶
/etc/exports management -- add/remove NFS exports and refresh exportfs.
NfsExports
¶
Manage /etc/exports entries.
Provides static methods for adding/removing NFS export entries and refreshing the kernel's export table to match.
Source code in sts_libs/src/sts/utils/nfs.py
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | |
add(path, options=DEFAULT_EXPORT_OPTIONS, clients='*')
staticmethod
¶
Add an export entry to /etc/exports and refresh exportfs.
Source code in sts_libs/src/sts/utils/nfs.py
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | |
refresh()
staticmethod
¶
Run exportfs -ra to re-export all directories.
Source code in sts_libs/src/sts/utils/nfs.py
72 73 74 75 76 77 78 79 | |
remove(path)
staticmethod
¶
Remove all export entries for path from /etc/exports and refresh exportfs.
Source code in sts_libs/src/sts/utils/nfs.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | |
Process Management¶
sts.utils.processes
¶
Process discovery and control via /proc.
ProcessInfo
pydantic-model
¶
Bases: StsBaseModel
Process state from /proc. Call discover() after construction.
Show JSON schema:
{
"additionalProperties": false,
"description": "Process state from /proc. Call ``discover()`` after construction.",
"properties": {
"pid": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Pid"
},
"name": {
"default": "",
"title": "Name",
"type": "string"
},
"status": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Status"
},
"cmdline": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Cmdline"
}
},
"title": "ProcessInfo",
"type": "object"
}
Fields:
-
pid(int | None) -
name(str) -
status(str | None) -
cmdline(str | None)
Source code in sts_libs/src/sts/utils/processes.py
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | |
exists
property
¶
True if the /proc/
running
property
¶
True if the process is alive (via kill(0)).
discover()
¶
Populate from /proc; returns self for chaining.
Source code in sts_libs/src/sts/utils/processes.py
96 97 98 99 100 101 102 103 104 105 106 107 | |
from_name(name)
classmethod
¶
Create and discover by name. Check .exists to confirm it was found.
Source code in sts_libs/src/sts/utils/processes.py
166 167 168 169 | |
from_pid(pid)
classmethod
¶
Create and discover by PID. Check .exists to confirm it was found.
Source code in sts_libs/src/sts/utils/processes.py
161 162 163 164 | |
kill(timeout=1.0)
¶
Send SIGTERM, then SIGKILL after timeout seconds if still alive.
Source code in sts_libs/src/sts/utils/processes.py
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | |
ProcessManager
¶
Bulk process operations (list, find by name, kill all).
Source code in sts_libs/src/sts/utils/processes.py
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | |
get_all()
¶
Get all running processes.
Source code in sts_libs/src/sts/utils/processes.py
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | |
get_by_name(name)
¶
Get all processes matching name.
Source code in sts_libs/src/sts/utils/processes.py
200 201 202 | |
kill_all(name, timeout=1.0)
¶
Kill all processes matching name via killall.
Source code in sts_libs/src/sts/utils/processes.py
204 205 206 207 208 209 210 211 212 213 214 | |
Size Handling¶
sts.utils.size
¶
Size parsing and conversion between human-readable strings and bytes.
Size
pydantic-model
¶
Bases: ReportModel
Immutable size value with unit, supporting parsing and conversion.
Large byte values are auto-scaled to the most readable unit on construction.
Show JSON schema:
{
"$defs": {
"Unit": {
"description": "Size units.",
"enum": [
"B",
"KiB",
"MiB",
"GiB",
"TiB",
"PiB",
"EiB",
"ZiB",
"YiB"
],
"title": "Unit",
"type": "string"
}
},
"description": "Immutable size value with unit, supporting parsing and conversion.\n\nLarge byte values are auto-scaled to the most readable unit on construction.",
"properties": {
"value": {
"default": 0.0,
"title": "Value",
"type": "number"
},
"unit": {
"$ref": "#/$defs/Unit",
"default": "B"
}
},
"title": "Size",
"type": "object"
}
Fields:
-
value(float) -
unit(Unit)
Validators:
-
_normalize_unit
Source code in sts_libs/src/sts/utils/size.py
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | |
from_bytes(bytes_)
classmethod
¶
Create a Size from a byte count, auto-scaling to the best unit.
Source code in sts_libs/src/sts/utils/size.py
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | |
from_string(size)
classmethod
¶
Parse a human-readable size string (e.g. '1KiB'), or None if invalid.
Source code in sts_libs/src/sts/utils/size.py
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | |
to_bytes()
¶
Convert to bytes.
Source code in sts_libs/src/sts/utils/size.py
124 125 126 | |
Unit
¶
Bases: StrEnum
Size units.
Source code in sts_libs/src/sts/utils/size.py
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | |
size_bytes_2_size_human(bytes_)
¶
Convert bytes to human-readable size string, or None if invalid.
Source code in sts_libs/src/sts/utils/size.py
163 164 165 166 167 168 169 170 171 172 173 | |
size_human_2_size_bytes(size)
¶
Convert human-readable size string to bytes, or None if invalid.
Source code in sts_libs/src/sts/utils/size.py
156 157 158 159 160 | |
size_human_check(size)
¶
Check if a human-readable size string is valid.
Source code in sts_libs/src/sts/utils/size.py
151 152 153 | |
String Utilities¶
sts.utils.string_extras
¶
String manipulation utilities.
none_to_empty(value)
¶
Convert None to empty string, otherwise pass through.
Source code in sts_libs/src/sts/utils/string_extras.py
18 19 20 | |
rand_string(length=8, chars=None)
¶
Generate a random string (default: 8 chars from lowercase + digits).
Source code in sts_libs/src/sts/utils/string_extras.py
12 13 14 15 | |
Test Marks¶
sts.marks
¶
Pytest skip/xfail helpers for distribution, version, and package gating.
Three tiers:
- Imperative helpers (
requires_*) — call inside fixtures topytest.skip(). - Marker factory (
requires_package) — returnspytest.MarkDecoratorfor decorators andpytestmark. - Boolean predicates (
is_*) — forpytest.mark.skipif/xfailconditions andpytestmark.
is_distro(name)
¶
True if running on the given distribution.
Source code in sts_libs/src/sts/marks.py
87 88 89 | |
is_rhel_below(version)
¶
True if running on RHEL below the given version.
Source code in sts_libs/src/sts/marks.py
81 82 83 84 | |
requires_package(name, min_version, reason='')
¶
Skipif marker: skip if installed package is below minimum version.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Package name (as known to rpm). |
required |
min_version
|
VersionInfo
|
Minimum required version. |
required |
reason
|
str
|
Custom skip reason. |
''
|
Source code in sts_libs/src/sts/marks.py
63 64 65 66 67 68 69 70 71 72 73 74 75 | |
requires_rhel(min_version, reason='')
¶
Skip the current test if on RHEL below the given version.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_version
|
int | VersionInfo
|
Minimum RHEL version. |
required |
reason
|
str
|
Custom skip reason. |
''
|
Source code in sts_libs/src/sts/marks.py
31 32 33 34 35 36 37 38 39 40 41 | |
requires_tool(tool, min_version, reason='')
¶
Skip the current test if a tool's version is below minimum.
Expects tool to have a version attribute comparable to VersionInfo.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool
|
object
|
Object with a |
required |
min_version
|
VersionInfo
|
Minimum required version. |
required |
reason
|
str
|
Custom skip reason. |
''
|
Source code in sts_libs/src/sts/marks.py
44 45 46 47 48 49 50 51 52 53 54 55 56 57 | |
Version Handling¶
sts.utils.version
¶
Semantic version parsing and comparison.
VersionInfo
¶
Bases: NamedTuple
Parsed version with major.minor.micro.patch-build components.
Supports comparison via tuple ordering and parsing via from_string().
Source code in sts_libs/src/sts/utils/version.py
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | |
__str__()
¶
Format as dotted version string, trimming trailing zeros.
Examples:
>>> str(VersionInfo(9))
'9'
>>> str(VersionInfo(9, 4))
'9.4'
>>> str(VersionInfo(0, 5, 1))
'0.5.1'
Source code in sts_libs/src/sts/utils/version.py
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | |
from_string(version_string)
classmethod
¶
Parse major[.minor[.micro[.patch]]][-build] into a VersionInfo.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the string is empty, malformed, or contains negative components. |
Source code in sts_libs/src/sts/utils/version.py
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | |
Multihost Synchronization¶
sts.utils.sync
¶
Multihost test synchronization via rstrnt-sync and TMT topology.
Three barrier helpers cover the typical multihost lifecycle:
barrier_start: setter announces readiness, no lingerbarrier: mid-test sync point, no lingerbarrier_finish: setter lingers to keep daemon alive for the peer
barrier(label, *, setter_role, timeout=3600)
¶
Mid-test barrier -- both hosts continue, no linger.
Use between test phases when both hosts need to synchronize but neither is about to exit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
Barrier / state name (e.g. |
required |
setter_role
|
str
|
Role of the host that announces the state |
required |
timeout
|
int
|
Seconds the blocker waits before giving up |
3600
|
Example
barrier('DATAWRITTEN', setter_role='server')
Source code in sts_libs/src/sts/utils/sync.py
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | |
barrier_finish(label, *, setter_role, linger=DEFAULT_LINGER, timeout=3600)
¶
Final barrier -- setter lingers so the peer can detect the state.
Use when the setter is about to exit (e.g. the client signalling completion). After announcing the state the setter sleeps for linger seconds (default 120) to keep the rstrnt-sync daemon alive for the peer to poll.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
Barrier / state name (e.g. |
required |
setter_role
|
str
|
Role of the host that announces the state |
required |
linger
|
int
|
Seconds to sleep after announcing |
DEFAULT_LINGER
|
timeout
|
int
|
Seconds the blocker waits before giving up |
3600
|
Example
barrier_finish('CLIENTDONE', setter_role='client')
Source code in sts_libs/src/sts/utils/sync.py
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | |
barrier_start(label, *, setter_role, timeout=3600)
¶
Initial barrier -- setter keeps running, no linger.
Use at the beginning of the test when the setter (typically the server) announces readiness and continues with its own work.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
Barrier / state name (e.g. |
required |
setter_role
|
str
|
Role of the host that announces the state |
required |
timeout
|
int
|
Seconds the blocker waits before giving up |
3600
|
Example
barrier_start('SERVERREADY', setter_role='server')
Source code in sts_libs/src/sts/utils/sync.py
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 | |
check_sync_daemon()
¶
Log rstrnt-sync process status and port 6776 listener (diagnostic only).
Source code in sts_libs/src/sts/utils/sync.py
225 226 227 228 229 230 231 232 233 234 235 236 237 | |
get_my_fqdn()
¶
Get this host's FQDN (from topology or socket.getfqdn()).
Source code in sts_libs/src/sts/utils/sync.py
118 119 120 121 122 123 124 125 126 | |
get_peer_fqdn(role)
¶
Get a peer's FQDN by role from the topology (falls back to <ROLE>_IP env).
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If no hostname can be determined for the role. |
Source code in sts_libs/src/sts/utils/sync.py
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | |
get_role()
¶
Get this host's role (from topology, TMT_ROLE env, or default 'server').
Source code in sts_libs/src/sts/utils/sync.py
93 94 95 96 97 98 99 100 101 102 103 104 105 | |
init_sync()
¶
Parse topology and set Beaker-compatible env vars. Call once before using barriers.
Source code in sts_libs/src/sts/utils/sync.py
214 215 216 217 | |
is_client()
¶
True if this host's role is 'client'.
Source code in sts_libs/src/sts/utils/sync.py
113 114 115 | |
is_server()
¶
True if this host's role is 'server'.
Source code in sts_libs/src/sts/utils/sync.py
108 109 110 | |
load_topology()
¶
Parse the TMT_TOPOLOGY_BASH file into a dict (empty if unavailable).
Source code in sts_libs/src/sts/utils/sync.py
39 40 41 42 43 44 45 46 47 48 49 50 51 | |
resolve_ipv4(hostname)
¶
Resolve hostname to IPv4 (returns hostname as-is on failure).
Useful for protocols that do not support IPv6 (e.g. iSCSI).
Source code in sts_libs/src/sts/utils/sync.py
158 159 160 161 162 163 164 165 166 167 168 169 170 171 | |
sync_block(state, host, *, timeout=3600, retry=60)
¶
Block until a remote host has announced a state.
Calls rstrnt-sync-block -s <state> <host> and polls every
retry seconds until the state is found or timeout is exceeded.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
str
|
State label to wait for |
required |
host
|
str
|
FQDN of the host that will announce the state |
required |
timeout
|
int
|
Seconds before giving up |
3600
|
retry
|
int
|
Seconds between polls |
60
|
Example
sync_block('SERVERREADY', 'server.example.com')
Source code in sts_libs/src/sts/utils/sync.py
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 | |
sync_set(state, *, linger=0)
¶
Announce that this host has reached a state.
Calls rstrnt-sync-set -s <state>. When the process is about
to exit, set linger to a non-zero value so the daemon stays
alive long enough for the peer to poll it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
str
|
State label to announce (e.g. |
required |
linger
|
int
|
Seconds to sleep after setting the state |
0
|
Example
sync_set('SERVERREADY')
sync_set('CLIENTDONE', linger=120)
Source code in sts_libs/src/sts/utils/sync.py
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | |
System Checks¶
sts.utils.syscheck
¶
Post-test system health checks: kernel taint, dmesg, abrt, kdump.
abrt_check()
¶
Check abrt for issues (True if clean, not installed, or daemon not running).
Source code in sts_libs/src/sts/utils/syscheck.py
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | |
check_all()
¶
Run all system health checks; save logs and sosreport on failure.
Under tmt, only kernel taint and abrt are checked (tmt covers the rest).
Source code in sts_libs/src/sts/utils/syscheck.py
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | |
dmesg_check()
¶
Check dmesg for segfaults and call traces.
Source code in sts_libs/src/sts/utils/syscheck.py
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | |
kdump_check()
¶
Check /var/crash for recent kdump crashes (last 24 hours).
Source code in sts_libs/src/sts/utils/syscheck.py
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | |
kernel_check()
¶
Check kernel taint status (True if clean or unreadable).
Source code in sts_libs/src/sts/utils/syscheck.py
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | |
messages_dump_check()
¶
Check /var/log/messages for kernel dump traces.
Source code in sts_libs/src/sts/utils/syscheck.py
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | |
Error Handling¶
sts.utils.errors
¶
Storage Test Suite error hierarchy.
Convention for subsystem errors:
-
Every subsystem defines
<Module>Error(STSError)as its base. Exception:DmErrorinheritsDeviceErrorbecause Device Mapper is the Linux device layer. -
Domain subclasses are optional — add them only when callers need to catch distinct failure modes (e.g.
FIOConfigErrorvsFIOExecutionError, or Stratis pool/fs/blockdev errors). -
Command failures go through
CommandResult.assert_ok()which raisesSTSError. There are no per-module*CommandErrorclasses.
DeviceError
¶
Bases: STSError
Base class for device-related errors.
Source code in sts_libs/src/sts/utils/errors.py
27 28 | |
DeviceNotFoundError
¶
Bases: DeviceError
Device does not exist.
Source code in sts_libs/src/sts/utils/errors.py
31 32 | |
DeviceTypeError
¶
Bases: DeviceError
Device is not of expected type.
Source code in sts_libs/src/sts/utils/errors.py
35 36 | |
ModuleAlreadyLoadedError
¶
Bases: ModuleError
Exclusive acquisition conflicts with a pre-existing module load.
Source code in sts_libs/src/sts/utils/errors.py
51 52 | |
ModuleError
¶
Bases: STSError
Base class for kernel module errors.
Source code in sts_libs/src/sts/utils/errors.py
39 40 | |
ModuleInUseError
¶
Bases: ModuleError
Module cannot be unloaded because it is in use.
Source code in sts_libs/src/sts/utils/errors.py
63 64 | |
ModuleLoadError
¶
Bases: ModuleError
Failed to load kernel module.
Source code in sts_libs/src/sts/utils/errors.py
43 44 | |
ModuleUnavailableError
¶
Bases: ModuleError
Kernel module is absent before setup mutates module state.
Source code in sts_libs/src/sts/utils/errors.py
47 48 | |
ModuleUnloadError
¶
Bases: ModuleError
Failed to unload kernel module.
Source code in sts_libs/src/sts/utils/errors.py
59 60 | |
ModuleVerificationError
¶
Bases: ModuleError
Loaded module state does not satisfy its requested postconditions.
Source code in sts_libs/src/sts/utils/errors.py
55 56 | |
PackageError
¶
Bases: STSError
Base class for package-related errors.
Source code in sts_libs/src/sts/utils/errors.py
67 68 | |
PackageInstallError
¶
Bases: PackageError
Failed to install package.
Source code in sts_libs/src/sts/utils/errors.py
75 76 | |
PackageNotFoundError
¶
Bases: PackageError
Package does not exist.
Source code in sts_libs/src/sts/utils/errors.py
71 72 | |
STSError
¶
Bases: Exception
Base class for all STS exceptions.
Source code in sts_libs/src/sts/utils/errors.py
23 24 | |
FMF Markers Plugin¶
sts.utils.fmf_markers
¶
Pytest plugin: apply fmf metadata (tags, tier) as pytest markers.
Reads main.fmf files via the fmf library, resolves tag and tier
inheritance, and applies them as pytest markers during collection. This
enables pytest-native test selection that mirrors tmt plan filters.
Usage::
pytest tests/ -m ci # same tests as the sts-ci plan
pytest tests/ -m tier1 # all tier-1 tests
pytest tests/ -m "dm and tier1" # tier-1 device-mapper tests
pytest tests/ -m "not hw_fc" # exclude FC-hardware tests
Requires the fmf library (available wherever tmt is installed).
When fmf is not importable the plugin silently does nothing.
FmfMarkerPlugin
¶
Apply fmf tags and tier as pytest markers during collection.
Source code in sts_libs/src/sts/utils/fmf_markers.py
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | |
pytest_configure(config)
¶
Register fmf-derived markers if the fmf library is available.
Source code in sts_libs/src/sts/utils/fmf_markers.py
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | |
tmt Pytest Integration¶
sts.utils.tmt_pytest
¶
Pytest plugin: report individual test outcomes as tmt subresults.
When running under tmt (TMT_TEST_PIDFILE is set), writes
$TMT_TEST_DATA/tmt-report-results.yaml at session end so that
tmt's shell framework reduces outcomes into a single parent result
and keeps each pytest item as a subresult.
This deliberately writes tmt-report-results.yaml (the file
normally created by the tmt-report-result command) rather than
results.yaml (which requires result: custom in fmf metadata
and produces separate top-level results, not subresults).
TmtReportPlugin
¶
Collect pytest outcomes and write them for tmt at session end.
Source code in sts_libs/src/sts/utils/tmt_pytest.py
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | |
pytest_runtest_logreport(report)
¶
Record one setup/call/teardown report.
Source code in sts_libs/src/sts/utils/tmt_pytest.py
126 127 128 | |
pytest_sessionfinish(session, exitstatus)
¶
Write results at session end.
Source code in sts_libs/src/sts/utils/tmt_pytest.py
130 131 132 133 | |
TmtSubresult
¶
One pytest item mapped to a tmt subresult entry.
Source code in sts_libs/src/sts/utils/tmt_pytest.py
38 39 40 41 42 43 44 45 46 47 48 49 50 | |
apply_report(results, report)
¶
Fold a pytest setup/call/teardown report into one subresult per item.
Source code in sts_libs/src/sts/utils/tmt_pytest.py
93 94 95 96 97 98 99 100 101 102 103 | |
pytest_configure(config)
¶
Register the tmt reporter only inside a tmt test invocation.
Source code in sts_libs/src/sts/utils/tmt_pytest.py
145 146 147 148 | |
write_results(path, items)
¶
Write tmt-report-results.yaml (name + result required, note optional).
Source code in sts_libs/src/sts/utils/tmt_pytest.py
106 107 108 109 110 111 112 113 114 115 116 117 | |
Test State Persistence¶
sts.utils.teststate
¶
Cross-phase test state persistence.
Provides JSON state storage for tests that span multiple phases (e.g. reboot tests). The storage directory is resolved in order:
TMT_TEST_DATAenvironment variable (always preferred under tmt)- Explicit data_dir passed by the caller
/var/tmp/sts/fallback
Snapshot-boot tests must pass a data_dir that lives outside the
snapshotted root filesystem (e.g. /boot/sts), otherwise the state
file will not be visible after booting the snapshot. Use
:func:on_different_device to verify the path is on a separate
filesystem from /.
TestState
¶
JSON state file for persisting data across test phases.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Base name for the state file (without |
required |
data_dir
|
Path | None
|
Explicit storage directory used when |
None
|
Source code in sts_libs/src/sts/utils/teststate.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | |
load()
¶
Read state from the file, or return None if absent.
Source code in sts_libs/src/sts/utils/teststate.py
74 75 76 77 78 | |
remove()
¶
Delete the state file if it exists.
Source code in sts_libs/src/sts/utils/teststate.py
80 81 82 | |
save(data)
¶
Write data as JSON to the state file.
Source code in sts_libs/src/sts/utils/teststate.py
68 69 70 71 72 | |
on_different_device(path, reference=Path('/'))
¶
Check whether path resides on a different filesystem than reference.
Useful for snapshot-boot tests that need state stored outside the
snapshotted root. Compares st_dev of the two paths.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
Path to check (must exist). |
required |
reference
|
Path
|
Path to compare against (default: |
Path('/')
|
Source code in sts_libs/src/sts/utils/teststate.py
33 34 35 36 37 38 39 40 41 42 43 | |
CLI Tool Base¶
sts.utils.cli
¶
Shared base for CLI tool wrappers.
Provides argv-based command construction using run_argv (no shell).
CliTool
pydantic-model
¶
Bases: StsBaseModel
Base for CLI tool wrappers.
Subclasses set CLI_NAME and optionally override _global_args().
Show JSON schema:
{
"additionalProperties": false,
"description": "Base for CLI tool wrappers.\n\nSubclasses set CLI_NAME and optionally override _global_args().",
"properties": {},
"title": "CliTool",
"type": "object"
}
Source code in sts_libs/src/sts/utils/cli.py
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | |
run_command(subcommand=None, action=None, options=None, positional_args=None)
¶
Build and run a CLI command via run_argv (no shell).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
subcommand
|
str | Sequence[str] | None
|
Primary subcommand -- string or list for multi-word
(e.g. |
None
|
action
|
str | Sequence[str] | None
|
Action verb -- string or list for multi-word
(e.g. |
None
|
options
|
CliOptions | None
|
CLI options dict. None value = bare flag, str = |
None
|
positional_args
|
list[str] | None
|
Trailing positional arguments. |
None
|
Source code in sts_libs/src/sts/utils/cli.py
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | |