Skip to content
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

Implement --keep for tmt clean #3183

Merged
merged 1 commit into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ tmt-1.40.0
Add the ``--workdir-root`` option for the ``tmt clean`` command so
that users can specify the directory they want to clean.

Add the ``--keep`` option for the ``tmt clean guests`` command.
Users can now choose to keep the selected number of latest guests
and clean the rest to release the resources.
Add the ``--keep`` option for the ``tmt clean guests`` and ``tmt clean``
commands. Users can now choose to keep the selected number of latest guests,
and maybe also runs, clean the rest to release the resources.


tmt-1.39.0
Expand Down
20 changes: 16 additions & 4 deletions tests/clean/basic/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ rlJournalStart
rlPhaseEnd

rlPhaseStartTest "Create a couple of runs"
for id in {001..004}; do
for id in {001..005}; do
rlRun "tmt --feeling-safe run --id clean-$id"
rlAssertExists "$root/clean-$id"
done
Expand All @@ -20,23 +20,35 @@ rlJournalStart
rlAssertExists "$root/clean-001"
rlAssertExists "$root/clean-002"
rlAssertExists "$root/clean-003"
rlAssertNotExists "$root/clean-004"
rlAssertExists "$root/clean-004"
rlAssertNotExists "$root/clean-005"
rlPhaseEnd

rlPhaseStartTest "Remove selected (full path)"
rlRun "tmt clean -v --id $root/clean-001"
rlAssertNotExists "$root/clean-001"
rlAssertExists "$root/clean-002"
rlAssertExists "$root/clean-003"
rlAssertNotExists "$root/clean-004"
rlAssertExists "$root/clean-004"
rlAssertNotExists "$root/clean-005"
rlPhaseEnd

rlPhaseStartTest "Remove selected (name)"
rlRun "tmt clean -v --id clean-002"
rlAssertNotExists "$root/clean-001"
rlAssertNotExists "$root/clean-002"
rlAssertExists "$root/clean-003"
rlAssertNotExists "$root/clean-004"
rlAssertExists "$root/clean-004"
rlAssertNotExists "$root/clean-005"
rlPhaseEnd

rlPhaseStartTest "Skip latest guests and runs"
rlRun "tmt clean -v --keep 1"
rlAssertNotExists "$root/clean-001"
rlAssertNotExists "$root/clean-002"
rlAssertNotExists "$root/clean-003"
rlAssertExists "$root/clean-004"
rlAssertNotExists "$root/clean-005"
rlPhaseEnd

rlPhaseStartTest "Create a couple of runs in non-default root workdir"
Expand Down
6 changes: 2 additions & 4 deletions tmt/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3997,7 +3997,7 @@ def _stop_running_guests(self, run: Run) -> bool:
self.cli_invocation.options['quiet'] = quiet
return successful

def guests(self, run_ids: tuple[str, ...]) -> bool:
def guests(self, run_ids: tuple[str, ...], keep: Optional[int]) -> bool:
""" Clean guests of runs """
self.info('guests', color='blue')
self.verbose('workdir root', self.workdir_root)
Expand All @@ -4009,7 +4009,6 @@ def guests(self, run_ids: tuple[str, ...]) -> bool:
successful = True
assert self._cli_context_object is not None # narrow type
all_workdirs = list(tmt.utils.generate_runs(self.workdir_root, run_ids))
keep = self.opt('keep')
if keep is not None:
# Sort by modify time of the workdirs to keep the newest guests
all_workdirs.sort(
Expand Down Expand Up @@ -4038,7 +4037,7 @@ def _clean_workdir(self, path: Path) -> bool:
return False
return True

def runs(self, id_: tuple[str, ...]) -> bool:
def runs(self, id_: tuple[str, ...], keep: Optional[int]) -> bool:
""" Clean workdirs of runs """
self.info('runs', color='blue')
self.verbose('workdir root', self.workdir_root)
Expand All @@ -4050,7 +4049,6 @@ def runs(self, id_: tuple[str, ...]) -> bool:
assert last_run.workdir is not None # narrow type
return self._clean_workdir(last_run.workdir)
all_workdirs = list(tmt.utils.generate_runs(self.workdir_root, id_))
keep = self.opt('keep')
if keep is not None:
# Sort by modify time of the workdirs and keep the newest workdirs
all_workdirs.sort(
Expand Down
14 changes: 10 additions & 4 deletions tmt/cli/_root.py
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,9 @@ def _construct_trying_provision_options(params: Any) -> dict[str, Any]:
@option(
'-i', '--id', 'id_', metavar="ID", multiple=True,
help='Identifier (name or directory path) of the run to be cleaned.')
@option(
'-k', '--keep', type=int, default=None,
help='The number of latest workdirs to keep, clean the rest.')
@option(
'-s', '--skip', choices=CLEAN_RESOURCES,
help='The resources which should be kept on the disk.', multiple=True)
Expand All @@ -1645,6 +1648,7 @@ def _construct_trying_provision_options(params: Any) -> dict[str, Any]:
def clean(context: Context,
last: bool,
id_: tuple[str, ...],
keep: Optional[int],
skip: list[str],
_workdir_root: Optional[str],
**kwargs: Any) -> None:
Expand Down Expand Up @@ -1691,9 +1695,9 @@ def clean(context: Context,
cli_invocation=CliInvocation.from_context(context),
workdir_root=workdir_root)
if workdir_root.exists():
if 'guests' not in skip and not clean_obj.guests(id_):
if 'guests' not in skip and not clean_obj.guests(id_, keep):
exit_code = 1
if 'runs' not in skip and not clean_obj.runs(id_):
if 'runs' not in skip and not clean_obj.runs(id_, keep):
exit_code = 1
else:
clean_obj.warn(
Expand Down Expand Up @@ -1774,7 +1778,8 @@ def clean_runs(
workdir_root=effective_workdir_root(workdir_root))
context.obj.clean_partials["runs"].append(
lambda: clean_obj.runs(
(context.parent and context.parent.params.get('id_', [])) or id_))
(context.parent and context.parent.params.get('id_', [])) or id_,
(context.parent and context.parent.params.get('keep', [])) or keep))


@clean.command(name='guests')
Expand Down Expand Up @@ -1822,7 +1827,8 @@ def clean_guests(
workdir_root=effective_workdir_root(workdir_root))
context.obj.clean_partials["guests"].append(
lambda: clean_obj.guests(
(context.parent and context.parent.params.get('id_', [])) or id_))
(context.parent and context.parent.params.get('id_', [])) or id_,
(context.parent and context.parent.params.get('keep', [])) or keep))


# ignore[arg-type]: click code expects click.Context, but we use our own type for better type
Expand Down
Loading