Skip to content

Conversation

@twiggler
Copy link
Contributor

@twiggler twiggler commented Nov 5, 2025

Add an option --diagnostics <report.json> to acquire which collects troubleshooting information about the host

@codecov
Copy link

codecov bot commented Nov 5, 2025

Codecov Report

❌ Patch coverage is 1.70940% with 345 lines in your changes missing coverage. Please review.
✅ Project coverage is 41.01%. Comparing base (ca78bce) to head (5e22376).

Files with missing lines Patch % Lines
acquire/diagnostics/linux.py 0.00% 181 Missing ⚠️
acquire/diagnostics/windows.py 0.00% 136 Missing ⚠️
acquire/acquire.py 5.00% 19 Missing ⚠️
acquire/diagnostics/common.py 30.76% 9 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #273      +/-   ##
==========================================
- Coverage   44.90%   41.01%   -3.90%     
==========================================
  Files          26       29       +3     
  Lines        3543     3894     +351     
==========================================
+ Hits         1591     1597       +6     
- Misses       1952     2297     +345     
Flag Coverage Δ
unittests 41.01% <1.70%> (-3.90%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@twiggler twiggler requested a review from Schamper November 5, 2025 13:28
@twiggler twiggler marked this pull request as ready for review November 5, 2025 13:28
Copy link
Member

@Schamper Schamper left a comment

Choose a reason for hiding this comment

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

Is there some sanity unit test we can add? I.e. checking for errors, non empty values, that sort of thing. We run CI on Linux and Windows.


# Check for diagnostics argument here. Process and execute.
if args.diagnostics:
print("\nWARNING: Gathering diagnostics may destroy forensic evidence.")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
print("\nWARNING: Gathering diagnostics may destroy forensic evidence.")
print("\nWARNING: Gathering diagnostics may destroy forensic evidence!")

Gotta shout it.

diagnostics_info_json(diag_path)
log.info("Diagnostics written to file %s", diag_path.resolve())
except Exception:
acquire_gui.message("Failed to upload files")
Copy link
Member

Choose a reason for hiding this comment

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

?

confirm = input("Do you want to continue? [y/N]: ").strip().lower()
if confirm not in ("y", "yes"):
print("Aborted diagnostics.")
exit_success(args.config.get("arguments"))
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
exit_success(args.config.get("arguments"))
exit_success(args.config.get("arguments"))

if isinstance(args.diagnostics, str):
diag_path = Path(args.diagnostics)
elif log_file:
diag_path = Path(log_file).with_name(Path(log_file).stem + "_diag.json")
Copy link
Member

Choose a reason for hiding this comment

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

Isn't log_file already a Path?

Copy link
Member

Choose a reason for hiding this comment

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

Not necessarily a hard requirement, but in most other places in Dissect we'd call this file base.py. I'll leave it up to you to decide what to call it.

Comment on lines +184 to +187
def diagnostics_info_json(output: Path) -> None:
data = diagnostics_info()
with output.open("w") as f:
json.dump(data, f, default=str, indent=2)
Copy link
Member

Choose a reason for hiding this comment

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

Duplicate/unused?

Comment on lines +190 to +219
def parse_key_value_lines(lines: list[str]) -> dict[str, str]:
dev_tree = []
for root, _, files in os.walk("/dev"):
for name in files:
path_obj = Path(root) / name
dev_path = str(path_obj)
info = {"path": dev_path}
try:
st = path_obj.stat()
if stat.S_ISBLK(st.st_mode):
info["type"] = "block"
elif stat.S_ISCHR(st.st_mode):
info["type"] = "char"
else:
info["type"] = "other"
info["major"] = os.major(st.st_rdev)
info["minor"] = os.minor(st.st_rdev)
info["mode"] = oct(st.st_mode)
info["owner"] = st.st_uid
info["group"] = st.st_gid
if info["type"] == "block":
try:
blkid = subprocess.run(["blkid", dev_path], capture_output=True, text=True)
info["blkid"] = blkid.stdout.strip()
except Exception:
info["blkid"] = None
except Exception as e:
info["error"] = str(e)
dev_tree.append(info)
return dev_tree
Copy link
Member

Choose a reason for hiding this comment

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

This looks like the walk_dev code?

@@ -0,0 +1,198 @@
import ctypes
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
import ctypes
from __future__ import annotations.
import ctypes

ctypes.windll.kernel32.GetDiskFreeSpaceExW(
ctypes.c_wchar_p(drive), None, ctypes.byref(total), ctypes.byref(free)
)
info[drive] = {"total_GB": total.value // (1024**3), "free_GB": free.value // (1024**3)}
Copy link
Member

Choose a reason for hiding this comment

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

Why not just in bytes?

const=True,
default=False,
metavar="[PATH]",
help="gather diagnostics information and print as JSON (optional path, defaults to logfile stem)",
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
help="gather diagnostics information and print as JSON (optional path, defaults to logfile stem)",
help="gather diagnostics information and save as JSON (optional path, defaults to logfile stem or diag.json if no logfile provided)",

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.

3 participants