Clean up after unexpectedly terminated build

The `podman system prune` command is able to remove build containers that were created during the build, but were not removed because the build terminated unexpectedly.

By default, build containers are not removed to prevent interference with builds in progress. Use the **--build** flag when running the command to remove build containers as well.

Fixes: https://issues.redhat.com/browse/RHEL-62009

Signed-off-by: Jan Rodák <hony.com@seznam.cz>
This commit is contained in:
Jan Rodák
2025-01-20 21:39:54 +01:00
parent 3b6c7665b9
commit 81eb84fdaa
10 changed files with 158 additions and 11 deletions

View File

@ -33,6 +33,7 @@ import (
"github.com/containers/podman/v5/libpod/plugin"
"github.com/containers/podman/v5/libpod/shutdown"
"github.com/containers/podman/v5/pkg/domain/entities"
"github.com/containers/podman/v5/pkg/domain/entities/reports"
"github.com/containers/podman/v5/pkg/rootless"
"github.com/containers/podman/v5/pkg/systemd"
"github.com/containers/podman/v5/pkg/util"
@ -1264,6 +1265,43 @@ func (r *Runtime) LockConflicts() (map[uint32][]string, []uint32, error) {
return toReturn, locksHeld, nil
}
// PruneBuildContainers removes any build containers that were created during the build,
// but were not removed because the build was unexpectedly terminated.
//
// Note: This is not safe operation and should be executed only when no builds are in progress. It can interfere with builds in progress.
func (r *Runtime) PruneBuildContainers() ([]*reports.PruneReport, error) {
stageContainersPruneReports := []*reports.PruneReport{}
containers, err := r.store.Containers()
if err != nil {
return stageContainersPruneReports, err
}
for _, container := range containers {
path, err := r.store.ContainerDirectory(container.ID)
if err != nil {
return stageContainersPruneReports, err
}
if err := fileutils.Exists(filepath.Join(path, "buildah.json")); err != nil {
continue
}
report := &reports.PruneReport{
Id: container.ID,
}
size, err := r.store.ContainerSize(container.ID)
if err != nil {
report.Err = err
}
report.Size = uint64(size)
if err := r.store.DeleteContainer(container.ID); err != nil {
report.Err = errors.Join(report.Err, err)
}
stageContainersPruneReports = append(stageContainersPruneReports, report)
}
return stageContainersPruneReports, nil
}
// SystemCheck checks our storage for consistency, and depending on the options
// specified, will attempt to remove anything which fails consistency checks.
func (r *Runtime) SystemCheck(ctx context.Context, options entities.SystemCheckOptions) (entities.SystemCheckReport, error) {