-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
podman system check
for checking storage consistency
Add a `podman system check` that performs consistency checks on local storage, optionally removing damaged items so that they can be recreated. Signed-off-by: Nalin Dahyabhai <[email protected]>
- Loading branch information
Showing
15 changed files
with
565 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
package system | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"time" | ||
|
||
"github.com/containers/common/pkg/completion" | ||
"github.com/containers/podman/v5/cmd/podman/registry" | ||
"github.com/containers/podman/v5/cmd/podman/validate" | ||
"github.com/containers/podman/v5/pkg/domain/entities/types" | ||
multierror "github.com/hashicorp/go-multierror" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var ( | ||
checkOptions = types.SystemCheckOptions{} | ||
checkDescription = ` | ||
podman system check | ||
Check storage for consistency and remove anything that looks damaged | ||
` | ||
|
||
checkCommand = &cobra.Command{ | ||
Use: "check [options]", | ||
Short: "Check storage consistency", | ||
Args: validate.NoArgs, | ||
Long: checkDescription, | ||
RunE: check, | ||
ValidArgsFunction: completion.AutocompleteNone, | ||
Example: `podman system check`, | ||
} | ||
) | ||
|
||
func init() { | ||
registry.Commands = append(registry.Commands, registry.CliCommand{ | ||
Command: checkCommand, | ||
Parent: systemCmd, | ||
}) | ||
flags := checkCommand.Flags() | ||
flags.BoolVarP(&checkOptions.Quick, "quick", "q", false, "Skip time-consuming checks. The default is to include time-consuming checks") | ||
flags.BoolVarP(&checkOptions.Repair, "repair", "r", false, "Remove inconsistent images") | ||
flags.BoolVarP(&checkOptions.RepairLossy, "force", "f", false, "Remove inconsistent images and containers") | ||
flags.DurationP("max", "m", 24*time.Hour, "Maximum allowed age of unreferenced layers") | ||
_ = checkCommand.RegisterFlagCompletionFunc("max", completion.AutocompleteNone) | ||
} | ||
|
||
func check(cmd *cobra.Command, args []string) error { | ||
flags := cmd.Flags() | ||
if flags.Changed("max") { | ||
maxAge, err := flags.GetDuration("max") | ||
if err != nil { | ||
return err | ||
} | ||
checkOptions.UnreferencedLayerMaximumAge = &maxAge | ||
} | ||
response, err := registry.ContainerEngine().SystemCheck(context.Background(), checkOptions) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if err = printSystemCheckResults(response); err != nil { | ||
return err | ||
} | ||
|
||
if !checkOptions.Repair && !checkOptions.RepairLossy && response.Errors { | ||
return errors.New("damage detected in local storage") | ||
} | ||
|
||
recheckOptions := checkOptions | ||
recheckOptions.Repair = false | ||
recheckOptions.RepairLossy = false | ||
if response, err = registry.ContainerEngine().SystemCheck(context.Background(), recheckOptions); err != nil { | ||
return err | ||
} | ||
if response.Errors { | ||
return errors.New("damage in local storage still present after repair attempt") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func printSystemCheckResults(report *types.SystemCheckReport) error { | ||
if !report.Errors { | ||
return nil | ||
} | ||
errorSlice := func(strs []string) []error { | ||
if strs == nil { | ||
return nil | ||
} | ||
errs := make([]error, len(strs)) | ||
for i, s := range strs { | ||
errs[i] = errors.New(s) | ||
} | ||
return errs | ||
} | ||
for damagedLayer, errorsSlice := range report.Layers { | ||
merr := multierror.Append(nil, errorSlice(errorsSlice)...) | ||
if err := merr.ErrorOrNil(); err != nil { | ||
fmt.Printf("Damaged layer %s:\n%s", damagedLayer, err) | ||
} | ||
} | ||
for _, removedLayer := range report.RemovedLayers { | ||
fmt.Printf("Deleted damaged layer: %s\n", removedLayer) | ||
} | ||
for damagedROLayer, errorsSlice := range report.ROLayers { | ||
merr := multierror.Append(nil, errorSlice(errorsSlice)...) | ||
if err := merr.ErrorOrNil(); err != nil { | ||
fmt.Printf("Damaged read-only layer %s:\n%s", damagedROLayer, err) | ||
} | ||
} | ||
for damagedImage, errorsSlice := range report.Images { | ||
merr := multierror.Append(nil, errorSlice(errorsSlice)...) | ||
if err := merr.ErrorOrNil(); err != nil { | ||
fmt.Printf("Damaged image %s:\n%s", damagedImage, err) | ||
} | ||
} | ||
for removedImage := range report.RemovedImages { | ||
fmt.Printf("Deleted damaged image: %s\n", removedImage) | ||
} | ||
for damagedROImage, errorsSlice := range report.ROImages { | ||
merr := multierror.Append(nil, errorSlice(errorsSlice)...) | ||
if err := merr.ErrorOrNil(); err != nil { | ||
fmt.Printf("Damaged read-only image %s\n%s", damagedROImage, err) | ||
} | ||
} | ||
for damagedContainer, errorsSlice := range report.Containers { | ||
merr := multierror.Append(nil, errorSlice(errorsSlice)...) | ||
if err := merr.ErrorOrNil(); err != nil { | ||
fmt.Printf("Damaged container %s:\n%s", damagedContainer, err) | ||
} | ||
} | ||
for removedContainer := range report.RemovedContainers { | ||
fmt.Printf("Deleted damaged container: %s\n", removedContainer) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
% podman-system-check 1 | ||
|
||
## NAME | ||
podman\-system\-check - Perform consistency checks on image and container storage | ||
|
||
## SYNOPSIS | ||
**podman system check** [*options*] | ||
|
||
## DESCRIPTION | ||
Perform consistency checks on image and container storage, reporting images and | ||
containers which have identified issues. | ||
|
||
## OPTIONS | ||
|
||
#### **--force**, **-f** | ||
|
||
When attempting to remove damaged images, also remove containers which depend | ||
on those images. By default, damaged images which are being used by containers | ||
are left alone. | ||
|
||
Containers which depend on damaged images do so regardless of which engine | ||
created them, but because podman only "knows" how to shut down containers that | ||
it started, the effect on still-running containers which were started by other | ||
engines is difficult to predict. | ||
|
||
#### **--max**, **-m**=*duration* | ||
|
||
When considering layers which are not used by any images or containers, assume | ||
that any layers which are more than *duration* old are the results of canceled | ||
attempts to pull images, and should be treated as though they are damaged. | ||
|
||
#### **--quick**, **-q** | ||
|
||
Skip checks which are known to be time-consuming. This will prevent some types | ||
of errors from being detected. | ||
|
||
#### **--repair**, **-r** | ||
|
||
Remove any images which are determined to have been damaged in some way, unless | ||
they are in use by containers. Use **--force** to remove containers which | ||
depend on damaged images, and those damaged images, as well. | ||
|
||
## EXAMPLE | ||
|
||
A reasonably quick check: | ||
``` | ||
podman system check --quick --repair --force | ||
``` | ||
|
||
A more thorough check: | ||
``` | ||
podman system check --repair --max=1h --force | ||
``` | ||
|
||
## SEE ALSO | ||
**[podman(1)](podman.1.md)**, **[podman-system(1)](podman-system.1.md)** | ||
|
||
## HISTORY | ||
April 2024 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.