Skip to content

Commit b504bef

Browse files
committed
chore: bump version number [skip ci]
1 parent ac64af7 commit b504bef

2 files changed

Lines changed: 31 additions & 29 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,38 +8,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
## [Unreleased]
1010

11-
### Changed
11+
tbd
1212

13-
* base.py: `get_worst()` now accepts any number of state arguments (`*states`). Existing two-argument callers keep working unchanged, but plugins that need to combine three or more states in one call no longer have to nest the call - e.g. `get_worst(state, used_state, committed_state)` instead of `get_worst(state, get_worst(used_state, committed_state))`
14-
* lftest.py: `test()` now accepts `args` with fewer than three elements. Plugins can be invoked as `--test=path/to/fixture` without the trailing `,,0`; stderr defaults to the empty string and the return code to `0`
1513

16-
### Fixed
17-
18-
* Fix `--require-hashes` pip installs in CI workflows by using pinned versions instead
19-
* cache.py: treat a cache entry as valid up to and including its `expire` timestamp instead of expiring it one second early (`<` instead of `<=`). A key set with `expire=now+5` is now still served at `now+5` and first becomes unavailable at `now+6`, matching HTTP Cache-Control max-age and Redis EXPIRE semantics. Callers that relied on the old one-second-early expiry see their cached value live one second longer ([#120](https://github.com/Linuxfabrik/lib/issues/120))
20-
* human.py: `bits2human()`, `bytes2human()` and `bps2human()` now scale negative values to a unit that matches their magnitude. Before, `bytes2human(-1048576)` returned `-1048576.0B`, now it returns `-1.0MiB`. This matters for counter deltas that can legitimately be negative (counter resets, reclaimed memory, bandwidth drops) ([#120](https://github.com/Linuxfabrik/lib/issues/120))
21-
* shell.py: close the upstream process's `stdout` after connecting it to the next pipeline stage. Without this, the upstream process never received EOF/SIGPIPE when the downstream stage exited early, and each pipeline stage leaked a file descriptor until garbage collection caught up ([#120](https://github.com/Linuxfabrik/lib/issues/120))
22-
* url.py: drop the dead `timeout=timeout if digest_auth_user else timeout` ternary in `fetch()`; both branches evaluated to `timeout`, so behavior is unchanged ([#120](https://github.com/Linuxfabrik/lib/issues/120))
23-
* db_sqlite.py: pass `usedforsecurity=False` to `hashlib.sha1()` so bandit no longer flags a non-security SHA1 use as a weak hash (the hash is only used to derive sanitized SQL identifiers)
24-
* db_sqlite.py: rename unused loop variable in `rm_db()` to silence ruff B007
25-
* grassfish.py: remove unused `match()` helper that referenced undefined names (`re` and `compiled_custom_id_regex`); the function was never called and would have raised `NameError` at runtime
26-
* net.py: fix `get_netinfo()` which called a non-existent `get_ip_public()` and swallowed the resulting `NameError` by returning `[]`; the function now leaves `public_address` as `None` and callers that need the public IP must use `get_public_ip()` directly
27-
* rocket.py: `get_groups_history()` no longer mutates a shared default `params={}` dict (B006) and properly defaults `params` to `None`
28-
* url.py: `fetch()` and `fetch_json()` no longer use mutable default arguments for `header` and `data` (B006); defaults are now `None` with initialization inside the function
29-
30-
### Security
31-
32-
* Annotate all remaining bandit low/medium findings with `# nosec BXXX` comments and a short justification (subprocess helpers with `shell=True` by design, admin-controlled URLs passed to `urlopen`, SQL built from sanitized identifiers in `db_sqlite`). Bandit now runs clean at `--severity-level=low --confidence-level=low` over the whole lib
14+
## [v3.0.0] - 2026-04-13
3315

3416
### Added
3517

36-
* Add CONTRIBUTING
3718
* Add GitHub Actions workflow to automatically build and deploy API documentation to GitHub Pages
3819
* Add bandit and vulture to `.pre-commit-config.yaml` for security and dead-code checks on every commit
39-
* Add ruff linter and formatter to pre-commit hooks ([#117](https://github.com/Linuxfabrik/lib/issues/117))
4020
* Add pre-commit hooks
41-
* disk.py: add `get_owner()`
21+
* Add ruff linter and formatter to pre-commit hooks ([#117](https://github.com/Linuxfabrik/lib/issues/117))
4222
* args.py: expand `HELP_TEXTS` with standard help texts for all common parameters (always-ok, critical, warning, insecure, no-proxy, timeout, url, ignore-regex, match, lengthy, count, test, etc.)
23+
* disk.py: add `get_owner()`
4324
* lftest.py: add `run()` function for declarative, data-driven unit tests using `subTest()`
4425
* nextcloud.py: new library
4526
* txt.py: add `exception2text()`
@@ -48,19 +29,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4829

4930
### Changed
5031

51-
* Bump minimum Python version from 3.6 to 3.9
5232
* base.py: `get_perfdata()` now sanitizes labels by stripping single quotes and replacing `=` with `_`
33+
* base.py: `get_perfdata()` output no longer has trailing semicolons
34+
* base.py: `get_table()`: document why pure ASCII delimiters are used instead of Unicode box-drawing characters
35+
* base.py: `get_worst()` now accepts any number of state arguments (`*states`). Existing two-argument callers keep working unchanged, but plugins that need to combine three or more states in one call no longer have to nest the call - e.g. `get_worst(state, used_state, committed_state)` instead of `get_worst(state, get_worst(used_state, committed_state))`
5336
* base.py: deduplicate `get_state()` operator logic using `operator` module
5437
* base.py: deduplicate `sum_dict()` by delegating to `sum_lod()`
55-
* base.py: `get_table()`: document why pure ASCII delimiters are used instead of Unicode box-drawing characters
5638
* base.py: improve `get_table()` performance for large tables
5739
* base.py: move `parse_range()` and state name mapping to module level
5840
* base.py: remove unused `collections` import
59-
* base.py: strip trailing semicolons in `get_perfdata()` output
6041
* db_sqlite.py: reduce unnecessary dictionary object creation
6142
* human.py: deduplicate `bits2human()`/`bps2human()`/`bytes2human()` via shared `_to_human()` helper
6243
* human.py: deduplicate `humanrange2bytes()`/`humanrange2seconds()` via shared `_convert_range()` helper
6344
* human.py: pre-compute mappings as module constants
45+
* lftest.py: `test()` now accepts `args` with fewer than three elements. Plugins can be invoked as `--test=path/to/fixture` without the trailing `,,0`; stderr defaults to the empty string and the return code to `0`
6446
* powershell.py: `run_ps()` now always returns a dict
6547
* Remove pre-built documentation from the repository (now auto-deployed via GitHub Actions)
6648
* txt.py: improve `filter_mltext()` performance (avoid O(n²) string concatenation)
@@ -70,23 +52,42 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7052
* winrm.py: make `run_cmd()` and `run_ps()` JEA-aware
7153
* winrm.py: make `run_cmd()` and `run_ps()` Kerberos-aware
7254

55+
### Removed
56+
57+
* Drop support for Python older than 3.9. The lib now requires Python 3.9 or newer; this matches the oldest still-supported enterprise Linux (RHEL 8) and lets the codebase use modern syntax and standard-library features
58+
7359
### Fixed
7460

7561
* base.py: `cu()` now also escapes HTML characters in the error message, not just in the traceback
7662
* base.py: `cu()` now detects active exceptions via `sys.exc_info()` instead of string-matching the traceback
7763
* base.py: `get_state()` no longer calls `sys.exit()` on malformed range specs, returns UNKNOWN instead
64+
* base.py: `get_table()` no longer uses the wrong separator for the second data row when called without a header
7865
* base.py: `oao()` now escapes HTML characters in the output message to prevent injection in web UIs
79-
* base.py: fix `get_table()` using wrong separator for the second data row when called without a header
8066
* base.py: fix invalid `-10` range example in `_parse_range()` docstring (correct syntax is `-10:0`)
67+
* cache.py: treat a cache entry as valid up to and including its `expire` timestamp instead of expiring it one second early (`<` instead of `<=`). A key set with `expire=now+5` is now still served at `now+5` and first becomes unavailable at `now+6`, matching HTTP Cache-Control max-age and Redis EXPIRE semantics. Callers that relied on the old one-second-early expiry see their cached value live one second longer ([#120](https://github.com/Linuxfabrik/lib/issues/120))
68+
* db_sqlite.py: pass `usedforsecurity=False` to `hashlib.sha1()` so bandit no longer flags a non-security SHA1 use as a weak hash (the hash is only used to derive sanitized SQL identifiers)
69+
* db_sqlite.py: rename unused loop variable in `rm_db()` to silence ruff B007
70+
* Fix `--require-hashes` pip installs in CI workflows by using pinned versions instead
71+
* grassfish.py: remove unused `match()` helper that referenced undefined names (`re` and `compiled_custom_id_regex`); the function was never called and would have raised `NameError` at runtime
72+
* human.py: `bits2human()`, `bytes2human()` and `bps2human()` now scale negative values to a unit that matches their magnitude. Before, `bytes2human(-1048576)` returned `-1048576.0B`, now it returns `-1.0MiB`. This matters for counter deltas that can legitimately be negative (counter resets, reclaimed memory, bandwidth drops) ([#120](https://github.com/Linuxfabrik/lib/issues/120))
8173
* human.py: fix incorrect `seconds2human()` docstring example for sub-second values
74+
* net.py: fix `get_netinfo()` which called a non-existent `get_ip_public()` and swallowed the resulting `NameError` by returning `[]`; the function now leaves `public_address` as `None` and callers that need the public IP must use `get_public_ip()` directly
8275
* powershell.py: fix outdated shebang line
76+
* rocket.py: `get_groups_history()` no longer mutates a shared default `params={}` dict (B006) and properly defaults `params` to `None`
8377
* shell.py: `shell_exec()` now applies timeout to the `shell=True` path (was previously ignored)
78+
* shell.py: close the upstream process's `stdout` after connecting it to the next pipeline stage. Without this, the upstream process never received EOF/SIGPIPE when the downstream stage exited early, and each pipeline stage leaked a file descriptor until garbage collection caught up ([#120](https://github.com/Linuxfabrik/lib/issues/120))
8479
* txt.py: `sanitize_sensitive_data()` now also redacts JSON-style fields and HTTP Authorization headers
8580
* txt.py: fix `exception2text()` missing `traceback` import (fallback path was dead code)
8681
* txt.py: fix `pluralize()` not stripping whitespace from comma-separated suffix parts
8782
* txt.py: fix `sanitize_sensitive_data()` replacing the key name instead of the secret value
83+
* url.py: `fetch()` and `fetch_json()` no longer use mutable default arguments for `header` and `data` (B006); defaults are now `None` with initialization inside the function
84+
* url.py: drop the dead `timeout=timeout if digest_auth_user else timeout` ternary in `fetch()`; both branches evaluated to `timeout`, so behavior is unchanged ([#120](https://github.com/Linuxfabrik/lib/issues/120))
8885
* winrm.py: pass parameters correctly in `run_cmd()` when using pypsrp
8986

87+
### Security
88+
89+
* Annotate all remaining bandit low/medium findings with `# nosec BXXX` comments and a short justification (subprocess helpers with `shell=True` by design, admin-controlled URLs passed to `urlopen`, SQL built from sanitized identifiers in `db_sqlite`). Bandit now runs clean at `--severity-level=low --confidence-level=low` over the whole lib
90+
9091

9192
## [v2.4.0] - 2025-09-17
9293

@@ -468,7 +469,8 @@ Minor improvements, barely any changes.
468469
Initial release.
469470

470471

471-
[Unreleased]: https://github.com/Linuxfabrik/lib/compare/v2.4.0...HEAD
472+
[Unreleased]: https://github.com/Linuxfabrik/lib/compare/v3.0.0...HEAD
473+
[v3.0.0]: https://github.com/Linuxfabrik/lib/compare/v2.4.0...v3.0.0
472474
[v2.4.0]: https://github.com/Linuxfabrik/lib/compare/v2.3.0...v2.4.0
473475
[v2.3.0]: https://github.com/Linuxfabrik/lib/compare/v2.2.1...v2.3.0
474476
[v2.2.1]: https://github.com/Linuxfabrik/lib/compare/v2.2.0...v2.2.1

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
66

77
[project]
88
name = "linuxfabrik-lib"
9-
version = "2.4.0"
9+
version = "3.0.0"
1010
description = "Python libraries used in various Linuxfabrik projects, including the 'Linuxfabrik Monitoring Plugins' project."
1111
readme = "README.md"
1212
authors = [

0 commit comments

Comments
 (0)