Skip to content

feat: Write roles fingerprints to /var/log/sysroles.jsonl - #178

Open
spetrosi wants to merge 10 commits into
linux-system-roles:mainfrom
spetrosi:fingerprint-write-to-file
Open

feat: Write roles fingerprints to /var/log/sysroles.jsonl#178
spetrosi wants to merge 10 commits into
linux-system-roles:mainfrom
spetrosi:fingerprint-write-to-file

Conversation

@spetrosi

@spetrosi spetrosi commented Aug 3, 2026

Copy link
Copy Markdown
Contributor
  • Extend the sr_fingerprint module to write syslog to /var/log/sysroles.jsonl in addition to writing them to syslog.

  • Add unit test for sr_fingerprint.py

Summary by CodeRabbit

  • New Features
    • Added structured role-fingerprint records with validated role, status, playbook, host, distribution, and host-count information.
    • Added syslog key-value output and optional JSONL logging with automatic directory creation, size limits, and trimming.
    • Added log preview support in check mode.
  • Bug Fixes
    • Improved handling of invalid data and file-write failures with clear error reporting.
  • Tests
    • Added comprehensive coverage for formatting, record generation, logging, validation, check mode, and timestamp behavior.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The module now collects structured role fingerprints, formats escaped syslog records, optionally persists bounded JSONL records, supports check mode, and includes unit coverage.

Changes

Structured fingerprint logging

Layer / File(s) Summary
Fingerprint contract and collection
playbooks/files/library/sr_fingerprint.py, playbooks/files/tests/unit/test_sr_fingerprint.py
The module defines structured inputs, canonical fields, derived values, and syslog and JSONL formatting. Tests cover collection and formatting.
Fingerprint execution and persistence
playbooks/files/library/sr_fingerprint.py, playbooks/files/tests/unit/test_sr_fingerprint.py
The module creates log directories, appends JSONL records, trims logs atomically, supports check-mode metadata, validates log sizes, and reports write failures. Tests cover persistence and error handling.
Fingerprint validation and wiring
playbooks/files/tests/unit/test_sr_fingerprint.py, playbooks/files/tests/unit/sr_fingerprint.py, inventory/group_vars/active_roles.yml
Tests cover setup and timestamp formatting. The symbolic link and inventory declarations expose the test module and update file classifications.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers: richm

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: writing role fingerprints to /var/log/sysroles.jsonl.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
playbooks/files/library/sr_fingerprint.py (2)

211-256: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider making run_module easier to unit test.

run_module builds AnsibleModule internally, so the write-failure path (fail_json on Lines 247-251) and the check-mode preview branch (Lines 230-239) are not exercised by test_sr_fingerprint.py, only the extracted helper functions are. Accepting an injected module instance (or splitting the check-mode/write logic into a testable helper) would let tests cover the fail_json path, which is the module's main failure mode.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playbooks/files/library/sr_fingerprint.py` around lines 211 - 256, Refactor
run_module so its AnsibleModule dependency can be injected, or extract the
check-mode and JSONL write handling into a separately callable helper. Preserve
the existing check-mode preview behavior and ensure tests can exercise the
_write_jsonl_log failure path through module.fail_json.

84-84: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the actual return values.

RETURN is an empty placeholder, but the module now returns fingerprint, and conditionally message, jsonl_row, and log_file (Lines 231-239, 256). Document these fields so ansible-doc and downstream consumers of register: output can see the real return contract.

♻️ Suggested RETURN documentation
-RETURN = r""" # """
+RETURN = r"""
+fingerprint:
+    description: The canonical fingerprint record that was logged.
+    type: dict
+    returned: always
+message:
+    description: Human-readable preview of the syslog line (check mode only).
+    type: str
+    returned: when check mode is enabled
+jsonl_row:
+    description: The JSON line that would be (or was) appended to the log file.
+    type: str
+    returned: when write_log_file is true
+log_file:
+    description: Path to the JSONL log file.
+    type: str
+    returned: when write_log_file is true
+"""
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playbooks/files/library/sr_fingerprint.py` at line 84, Replace the
placeholder RETURN documentation in the sr_fingerprint module with a complete
description of the actual return contract: always document fingerprint, and
document the conditional message, jsonl_row, and log_file fields, including when
each is produced, so ansible-doc and registered results expose these values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@inventory/group_vars/active_roles.yml`:
- Line 12: Update the entry in present_files to reference
tests/unit/test_sr_fingerprint.py instead of the .yml path, matching the actual
added test file and preserving the exact path expected by file-sync automation.

In `@playbooks/files/library/sr_fingerprint.py`:
- Around line 175-188: Preserve the actual distribution values returned by
`_collect_fingerprint_record` and its `managed_node_distro` field. Do not mark
the entire `ansible_facts` input as `no_log=True`; instead, pass only the fields
consumed by `_get_managed_node_distro` as separate parameters while retaining
the existing record-building flow.

---

Nitpick comments:
In `@playbooks/files/library/sr_fingerprint.py`:
- Around line 211-256: Refactor run_module so its AnsibleModule dependency can
be injected, or extract the check-mode and JSONL write handling into a
separately callable helper. Preserve the existing check-mode preview behavior
and ensure tests can exercise the _write_jsonl_log failure path through
module.fail_json.
- Line 84: Replace the placeholder RETURN documentation in the sr_fingerprint
module with a complete description of the actual return contract: always
document fingerprint, and document the conditional message, jsonl_row, and
log_file fields, including when each is produced, so ansible-doc and registered
results expose these values.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2eb2986c-d66c-4fdc-9d50-f2c7b1cde1aa

📥 Commits

Reviewing files that changed from the base of the PR and between b978437 and fe587f8.

📒 Files selected for processing (3)
  • inventory/group_vars/active_roles.yml
  • playbooks/files/library/sr_fingerprint.py
  • playbooks/files/tests/unit/test_sr_fingerprint.py

Comment thread inventory/group_vars/active_roles.yml Outdated
Comment thread playbooks/files/library/sr_fingerprint.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
playbooks/files/tests/unit/test_sr_fingerprint.py (2)

251-271: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Avoid the hardcoded /tmp path to prevent a lint failure.

Lines 256 and 269 use the literal "/tmp/test.jsonl". Static analysis flags this as CWE-377 (Ruff S108, ast-grep hardcoded-tmp-file) at the error level. The test never opens this file, because check_mode=True makes _handle_fingerprint return before the write branch runs. Even so, the literal path still triggers the lint rule and can fail the pipeline.

Derive the path with tempfile.gettempdir() instead of a literal /tmp string.

🔧 Proposed fix
     def test_handle_fingerprint_check_mode_with_log_file(self):
+        log_file = os.path.join(tempfile.gettempdir(), "test.jsonl")
         module = _FakeModule(
             {
                 "status": "success",
                 "write_log_file": True,
-                "log_file": "/tmp/test.jsonl",
+                "log_file": log_file,
                 "role_name": "systemd",
                 "role_path": "/usr/share/ansible/roles/systemd",
                 "ansible_play_hosts_all": ["host1"],
                 "distribution": "RedHat",
                 "distribution_version": "9.4",
             },
             check_mode=True,
         )
         with self.assertRaises(_ExitJsonException) as ctx:
             sr_fingerprint._handle_fingerprint(module)
         result = ctx.exception.kwargs
         self.assertIn("jsonl_row", result)
-        self.assertEqual(result["log_file"], "/tmp/test.jsonl")
+        self.assertEqual(result["log_file"], log_file)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playbooks/files/tests/unit/test_sr_fingerprint.py` around lines 251 - 271,
Replace the hardcoded “/tmp/test.jsonl” values in
test_handle_fingerprint_check_mode_with_log_file with a path derived from
tempfile.gettempdir(), and use the same derived path for both the fake module
input and the assertion. Preserve the existing test behavior and add or reuse
the tempfile import as needed.

Source: Linters/SAST tools


273-291: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Make the fingerprint write-failure test independent from non-root execution.

This test uses /nonexistent/deep/path and expects directory creation or file opening to fail. As root, the write can succeed, so the expected failure path is not covered. Mock the failure, such as builtins.open or _ensure_parent_dir, to make the assertion deterministic.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playbooks/files/tests/unit/test_sr_fingerprint.py` around lines 273 - 291,
Update test_handle_fingerprint_write_failure_calls_fail_json to mock the
file-writing failure deterministically, using builtins.open or
_ensure_parent_dir, instead of relying on the /nonexistent/deep/path filesystem
behavior. Preserve the existing _FailJsonException assertion and failure-message
validation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@playbooks/files/library/sr_fingerprint.py`:
- Around line 186-200: Update _write_jsonl_log and _trim_log_file to hold a
cross-process lock across the append and optional trim operations. Perform
trimming by writing retained lines to a temporary file in the log’s directory,
flushing and closing it, then atomically replacing the original log; ensure
concurrent writers cannot overwrite rows added after their snapshot.
- Line 299: Validate max_log_lines before fingerprint handling so negative
values are rejected, while preserving 0 as the documented value that disables
trimming and positive values as valid limits.

---

Nitpick comments:
In `@playbooks/files/tests/unit/test_sr_fingerprint.py`:
- Around line 251-271: Replace the hardcoded “/tmp/test.jsonl” values in
test_handle_fingerprint_check_mode_with_log_file with a path derived from
tempfile.gettempdir(), and use the same derived path for both the fake module
input and the assertion. Preserve the existing test behavior and add or reuse
the tempfile import as needed.
- Around line 273-291: Update
test_handle_fingerprint_write_failure_calls_fail_json to mock the file-writing
failure deterministically, using builtins.open or _ensure_parent_dir, instead of
relying on the /nonexistent/deep/path filesystem behavior. Preserve the existing
_FailJsonException assertion and failure-message validation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 44120bfa-fa79-4e4c-ab39-285f4c54179c

📥 Commits

Reviewing files that changed from the base of the PR and between fe587f8 and c372832.

📒 Files selected for processing (4)
  • inventory/group_vars/active_roles.yml
  • playbooks/files/library/sr_fingerprint.py
  • playbooks/files/tests/unit/sr_fingerprint.py
  • playbooks/files/tests/unit/test_sr_fingerprint.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • inventory/group_vars/active_roles.yml

Comment thread playbooks/files/library/sr_fingerprint.py Outdated
Comment thread playbooks/files/library/sr_fingerprint.py Outdated
@richm

richm commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

I think using a max size in bytes rather than a max number of records might be easier to implement:

lock log file
cur_size = get log file size in bytes (i.e. stat)
new_log_string = _format_fingerprint_record(record) + "\n"
if cur_size + len(new_log_string) > max_size:
  trim # trim records from log until new size is less than (max_size - len(new_log_string))
write new_log_string to log
unlock log file

Comment thread playbooks/files/tests/unit/test_sr_fingerprint.py Outdated
Comment thread playbooks/files/tests/unit/test_sr_fingerprint.py Outdated
Comment thread playbooks/files/tests/unit/test_sr_fingerprint.py Outdated
Comment thread playbooks/files/tests/unit/test_sr_fingerprint.py Outdated
Comment thread playbooks/files/tests/unit/test_sr_fingerprint.py Outdated
Comment thread playbooks/files/tests/unit/test_sr_fingerprint.py Outdated
Comment thread playbooks/files/tests/unit/test_sr_fingerprint.py Outdated
Comment thread playbooks/files/tests/unit/test_sr_fingerprint.py Outdated
Comment thread playbooks/files/tests/unit/test_sr_fingerprint.py Outdated
Comment thread playbooks/files/tests/unit/test_sr_fingerprint.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@playbooks/files/library/sr_fingerprint.py`:
- Around line 230-231: Define and enforce an explicit oversized-record policy in
the JSONL write flow around the max_size check and _trim_log_file: either raise
a clear module error when a serialized row exceeds max_log_size, or
intentionally allow that single row without trimming and document the exception.
Ensure missing log files do not trigger _trim_log_file with a negative or
invalid target, preserve consistent behavior for existing files, and add a
regression test covering a missing log file whose limit is smaller than one row.
- Line 195: Rename the ambiguous loop variable l to line in the while condition
and any related expressions within the surrounding logic, preserving the
existing behavior of the size calculation and line processing.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e93759fa-f9c4-4a1d-88e6-499762bed81c

📥 Commits

Reviewing files that changed from the base of the PR and between c372832 and 20117de.

📒 Files selected for processing (2)
  • playbooks/files/library/sr_fingerprint.py
  • playbooks/files/tests/unit/test_sr_fingerprint.py

Comment thread playbooks/files/library/sr_fingerprint.py Outdated
Comment thread playbooks/files/library/sr_fingerprint.py Outdated
Comment thread playbooks/files/library/sr_fingerprint.py Outdated
Comment thread playbooks/files/library/sr_fingerprint.py Outdated
Comment thread playbooks/files/library/sr_fingerprint.py Outdated
Comment thread playbooks/files/library/sr_fingerprint.py Outdated
Comment thread playbooks/files/library/sr_fingerprint.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@playbooks/files/library/sr_fingerprint.py`:
- Around line 231-232: Update the append-size handling around _trim_log_file to
reject any new_line larger than positive max_size, including empty logs, with a
clear error; otherwise calculate the removal amount as cur_size + len(new_line)
- max_size so only the oldest records needed for the append are removed. Catch
this error in _handle_fingerprint and add a regression test covering an empty
log with a limit smaller than one JSONL row.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 420ff308-86e8-48e9-bf61-1430ce494ea3

📥 Commits

Reviewing files that changed from the base of the PR and between 20117de and 7884dd1.

📒 Files selected for processing (2)
  • playbooks/files/library/sr_fingerprint.py
  • playbooks/files/tests/unit/test_sr_fingerprint.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • playbooks/files/tests/unit/test_sr_fingerprint.py

Comment thread playbooks/files/library/sr_fingerprint.py
spetrosi and others added 8 commits August 5, 2026 18:05
* Extend the sr_fingerprint module to write syslog to
/var/log/sysroles.jsonl in addition to writing them to syslog.

* Add unit test for sr_fingerprint.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add max_log_lines defaulting to 10000
* Apply CodeRabbit review
* Change the need for large ansible_facts to smaller distribution and
distribution_version
@spetrosi
spetrosi force-pushed the fingerprint-write-to-file branch from cfb3adb to ced463e Compare August 5, 2026 16:06
Add test_trim_multiple_lines
Use re.match for older Python compatibility
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
playbooks/files/tests/unit/test_sr_fingerprint.py (1)

202-203: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Verify max_log_size in bytes.

len() measures Python characters, not UTF-8 bytes. These tests use only ASCII values. They can pass when the implementation exceeds the byte limit for a multibyte value.

Add a record with multibyte text. Use len(serialized.encode("utf-8")) for capacity setup. Assert os.path.getsize(log_file) <= max_size after trimming.

Also applies to: 228-231, 253-255

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playbooks/files/tests/unit/test_sr_fingerprint.py` around lines 202 - 203,
Update the affected tests around _format_fingerprint_jsonl and log trimming to
include a record containing multibyte UTF-8 text, calculate max_size from the
serialized record using len(serialized.encode("utf-8")), and assert
os.path.getsize(log_file) <= max_size after trimming. Apply the same byte-based
setup and file-size assertion to the additional referenced test cases.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@playbooks/files/library/sr_fingerprint.py`:
- Around line 283-287: Update _format_fingerprint_key_value to escape newline,
carriage-return, and tab characters in value before determining quoting and
formatting, preserving the existing quote escaping behavior. Add tests covering
values containing newline and tab characters.

---

Nitpick comments:
In `@playbooks/files/tests/unit/test_sr_fingerprint.py`:
- Around line 202-203: Update the affected tests around
_format_fingerprint_jsonl and log trimming to include a record containing
multibyte UTF-8 text, calculate max_size from the serialized record using
len(serialized.encode("utf-8")), and assert os.path.getsize(log_file) <=
max_size after trimming. Apply the same byte-based setup and file-size assertion
to the additional referenced test cases.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a224b9bb-f745-4f4f-bc30-c191785c5c15

📥 Commits

Reviewing files that changed from the base of the PR and between e50be36 and d315308.

📒 Files selected for processing (4)
  • inventory/group_vars/active_roles.yml
  • playbooks/files/library/sr_fingerprint.py
  • playbooks/files/tests/unit/sr_fingerprint.py
  • playbooks/files/tests/unit/test_sr_fingerprint.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • playbooks/files/tests/unit/sr_fingerprint.py

Comment on lines +283 to +287
def _format_fingerprint_key_value(field, value):
text = "" if value is None else str(value)
if any(char in text for char in ' "='):
return '%s="%s"' % (field, text.replace('"', '""'))
return "%s=%s" % (field, text)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Escape control characters in syslog fields.

_format_fingerprint_key_value leaves newline, carriage-return, and tab characters unchanged. A parameter value with these characters can create malformed or multiple syslog records. Escape control characters before joining the key-value pairs. Add tests for newline and tab values.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playbooks/files/library/sr_fingerprint.py` around lines 283 - 287, Update
_format_fingerprint_key_value to escape newline, carriage-return, and tab
characters in value before determining quoting and formatting, preserving the
existing quote escaping behavior. Add tests covering values containing newline
and tab characters.

Comment thread playbooks/files/tests/unit/sr_fingerprint.py


def run_module():
from ansible.module_utils.basic import AnsibleModule

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this might cause problems with ansible-test or flake8 because they may expect imports to be done in a certain order and in a certain location

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reverted this

except - pass
@spetrosi
spetrosi force-pushed the fingerprint-write-to-file branch from 649b1a8 to 06b408e Compare August 6, 2026 15:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants