manifest: rm should not remove referenced images.

Following PR makes sure that `podman manifest rm <list>` only removes
the named manifest list and not referenced images.

Bumping and squashing c/common to v0.43.3-0.20210902095222-a7acc160fb25
in same commit in order to make sure build commit test passes.

Signed-off-by: Aditya Rajan <arajan@redhat.com>
This commit is contained in:
Aditya Rajan
2021-09-02 17:17:22 +05:30
parent 4207d959a6
commit cba114dd36
17 changed files with 87 additions and 22 deletions

View File

@ -52,6 +52,10 @@ func (r *Runtime) DiskUsage(ctx context.Context) ([]ImageDiskUsage, error) {
// diskUsageForImage returns the disk-usage baseistics for the specified image.
func diskUsageForImage(ctx context.Context, image *Image, tree *layerTree) ([]ImageDiskUsage, error) {
if err := image.isCorrupted(""); err != nil {
return nil, err
}
base := ImageDiskUsage{
ID: image.ID(),
Created: image.Created(),

View File

@ -74,7 +74,10 @@ func (i *Image) isCorrupted(name string) error {
}
if _, err := ref.NewImage(context.Background(), nil); err != nil {
return errors.Errorf("Image %s exists in local storage but may be corrupted: %v", name, err)
if name == "" {
name = i.ID()[:12]
}
return errors.Errorf("Image %s exists in local storage but may be corrupted (remove the image to resolve the issue): %v", name, err)
}
return nil
}

View File

@ -161,8 +161,14 @@ type LookupImageOptions struct {
// If set, do not look for items/instances in the manifest list that
// match the current platform but return the manifest list as is.
// only check for manifest list, return ErrNotAManifestList if not found.
lookupManifest bool
// If matching images resolves to a manifest list, return manifest list
// instead of resolving to image instance, if manifest list is not found
// try resolving image.
ManifestList bool
// If the image resolves to a manifest list, we usually lookup a
// matching instance and error if none could be found. In this case,
// just return the manifest list. Required for image removal.
@ -305,11 +311,14 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, options *Loo
}
return nil, err
}
if options.lookupManifest {
if options.lookupManifest || options.ManifestList {
if isManifestList {
return image, nil
}
return nil, errors.Wrapf(ErrNotAManifestList, candidate)
// return ErrNotAManifestList if lookupManifest is set otherwise try resolving image.
if options.lookupManifest {
return nil, errors.Wrapf(ErrNotAManifestList, candidate)
}
}
if isManifestList {
@ -532,6 +541,11 @@ type RemoveImagesOptions struct {
// using a removed image. Use RemoveContainerFunc for a custom logic.
// If set, all child images will be removed as well.
Force bool
// LookupManifest will expect all specified names to be manifest lists (no instance look up).
// This allows for removing manifest lists.
// By default, RemoveImages will attempt to resolve to a manifest instance matching
// the local platform (i.e., os, architecture, variant).
LookupManifest bool
// RemoveContainerFunc allows for a custom logic for removing
// containers using a specific image. By default, all containers in
// the local containers storage will be removed (if Force is set).
@ -591,13 +605,22 @@ func (r *Runtime) RemoveImages(ctx context.Context, names []string, options *Rem
toDelete := []string{}
// Look up images in the local containers storage and fill out
// toDelete and the deleteMap.
switch {
case len(names) > 0:
// prepare lookupOptions
var lookupOptions *LookupImageOptions
if options.LookupManifest {
// LookupManifest configured as true make sure we only remove manifests and no referenced images.
lookupOptions = &LookupImageOptions{lookupManifest: true}
} else {
lookupOptions = &LookupImageOptions{returnManifestIfNoInstance: true}
}
// Look up the images one-by-one. That allows for removing
// images that have been looked up successfully while reporting
// lookup errors at the end.
for _, name := range names {
img, resolvedName, err := r.LookupImage(name, &LookupImageOptions{returnManifestIfNoInstance: true})
img, resolvedName, err := r.LookupImage(name, lookupOptions)
if err != nil {
appendError(err)
continue

View File

@ -778,7 +778,7 @@ func (c *NetworkConfig) Validate() error {
}
}
if stringsEq(c.CNIPluginDirs, cniBinDir) {
if stringsEq(c.CNIPluginDirs, DefaultCNIPluginDirs) {
return nil
}

View File

@ -262,7 +262,13 @@ default_sysctls = [
# Path to directory where CNI plugin binaries are located.
#
#cni_plugin_dirs = ["/usr/libexec/cni"]
#cni_plugin_dirs = [
# "/usr/local/libexec/cni",
# "/usr/libexec/cni",
# "/usr/local/lib/cni",
# "/usr/lib/cni",
# "/opt/cni/bin",
#]
# The network name of the default CNI network to attach pods to.
#

View File

@ -76,10 +76,12 @@ var (
"CAP_SYS_CHROOT",
}
cniBinDir = []string{
// It may seem a bit unconventional, but it is necessary to do so
DefaultCNIPluginDirs = []string{
"/usr/local/libexec/cni",
"/usr/libexec/cni",
"/usr/lib/cni",
"/usr/local/lib/cni",
"/usr/lib/cni",
"/opt/cni/bin",
}
@ -207,7 +209,7 @@ func DefaultConfig() (*Config, error) {
DefaultNetwork: "podman",
DefaultSubnet: DefaultSubnet,
NetworkConfigDir: cniConfig,
CNIPluginDirs: cniBinDir,
CNIPluginDirs: DefaultCNIPluginDirs,
},
Engine: *defaultEngineConfig,
Secrets: defaultSecretConfig(),

View File

@ -236,6 +236,7 @@ func DefaultProfile() *Seccomp {
"madvise",
"mbind",
"memfd_create",
"memfd_secret",
"mincore",
"mkdir",
"mkdirat",

View File

@ -242,6 +242,7 @@
"madvise",
"mbind",
"memfd_create",
"memfd_secret",
"mincore",
"mkdir",
"mkdirat",

View File

@ -1,4 +1,4 @@
package version
// Version is the version of the build.
const Version = "0.43.2"
const Version = "0.43.3-dev"