-
Notifications
You must be signed in to change notification settings - Fork 38
Add diagnostics #273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add diagnostics #273
Conversation
Codecov Report❌ Patch coverage is
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
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Schamper
left a comment
There was a problem hiding this 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.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 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") |
There was a problem hiding this comment.
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")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 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") |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
| def diagnostics_info_json(output: Path) -> None: | ||
| data = diagnostics_info() | ||
| with output.open("w") as f: | ||
| json.dump(data, f, default=str, indent=2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate/unused?
| 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 |
There was a problem hiding this comment.
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 | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 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)} |
There was a problem hiding this comment.
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)", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 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)", |
Add an option
--diagnostics <report.json>to acquire which collects troubleshooting information about the host