-
Notifications
You must be signed in to change notification settings - Fork 165
Running tmt clean will now show disk space freed
#4801
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?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3613,6 +3613,11 @@ def show(self) -> None: | |
| CleanCallback = Callable[[], bool] | ||
|
|
||
|
|
||
| def _dir_size(path: Path) -> int: | ||
| """Return the total size in bytes of all files under path.""" | ||
| return sum(f.stat().st_size for f in path.rglob('*') if f.is_file()) | ||
|
|
||
|
|
||
| class Clean(tmt.utils.Common): | ||
| """ | ||
| A class for cleaning up workdirs, guests or images | ||
|
|
@@ -3751,14 +3756,15 @@ def guests(self, run_ids: tuple[str, ...], keep: Optional[int]) -> bool: | |
| successful = False | ||
| return successful | ||
|
|
||
| def _clean_workdir(self, path: Path) -> bool: | ||
| def _clean_workdir(self, path: Path, size: int) -> bool: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Computing the size outside of
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Absolutely - that was my intuition too. The only reason was I was trying to avoid returning a tuple - and I thought dataclass would be an overkill. Will revert to returning a tuple instead.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done: c4b334a |
||
| """ | ||
| Remove a workdir (unless in dry mode) | ||
| """ | ||
| formatted_size = tmt.utils.format_size(size) | ||
| if self.is_dry_run: | ||
| self.verbose(f"Would remove workdir '{path}'.", shift=1) | ||
| self.verbose(f"Would remove workdir '{path}' ({formatted_size}).", shift=1) | ||
| else: | ||
| self.verbose(f"Removing workdir '{path}'.", shift=1) | ||
| self.verbose(f"Removing workdir '{path}' ({formatted_size}).", shift=1) | ||
| try: | ||
| shutil.rmtree(path) | ||
| except OSError as error: | ||
|
|
@@ -3777,18 +3783,33 @@ def runs(self, id_: tuple[str, ...], keep: Optional[int]) -> bool: | |
| # the correct one. | ||
| last_run = Run(logger=self._logger, cli_invocation=self.cli_invocation) | ||
| last_run.load_workdir(with_logfiles=False) | ||
| return self._clean_workdir(last_run.run_workdir) | ||
| size = _dir_size(last_run.run_workdir) | ||
| success = self._clean_workdir(last_run.run_workdir, size) | ||
| self.verbose( | ||
| f"Summary: {'Would free' if self.is_dry_run else 'Freed'} " | ||
| f"{tmt.utils.format_size(size)} of disk space.", | ||
| shift=1, | ||
| ) | ||
| return success | ||
| all_workdirs = list(tmt.utils.generate_runs(self.workdir_root, id_, all_=True)) | ||
| if keep is not None: | ||
| # Sort by change time of the workdirs and keep the newest workdirs | ||
| all_workdirs.sort(key=lambda workdir: workdir.stat().st_ctime, reverse=True) | ||
| all_workdirs = all_workdirs[keep:] | ||
|
|
||
| successful = True | ||
| total_size = 0 | ||
| for workdir in all_workdirs: | ||
| if not self._clean_workdir(workdir): | ||
| size = _dir_size(workdir) | ||
| total_size += size | ||
| if not self._clean_workdir(workdir, size): | ||
| successful = False | ||
|
|
||
| self.verbose( | ||
| f"Summary: {'Would free' if self.is_dry_run else 'Freed'} " | ||
| f"{tmt.utils.format_size(total_size)} of disk space.", | ||
| shift=1, | ||
| ) | ||
| return successful | ||
|
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -86,6 +86,15 @@ | |
| from tmt.hardware import Size | ||
|
|
||
|
|
||
| def format_size(size: int) -> str: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done: c4b334a |
||
| """Format a byte count into a human-readable string.""" | ||
| for unit in ('B', 'KB', 'MB', 'GB', 'TB'): | ||
| if size < 1024: | ||
| return f'{size:.1f} {unit}' | ||
| size = int(size / 1024) | ||
| return f'{size:.1f} PB' | ||
|
AthreyVinay marked this conversation as resolved.
Outdated
|
||
|
|
||
|
|
||
| def sanitize_string(text: str) -> str: | ||
| """Remove invalid Unicode characters from a string""" | ||
| try: | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.