migrate Podman to containers/common/libimage

Migrate the Podman code base over to `common/libimage` which replaces
`libpod/image` and a lot of glue code entirely.

Note that I tried to leave bread crumbs for changed tests.

Miscellaneous changes:

 * Some errors yield different messages which required to alter some
   tests.

 * I fixed some pre-existing issues in the code.  Others were marked as
   `//TODO`s to prevent the PR from exploding.

 * The `NamesHistory` of an image is returned as is from the storage.
   Previously, we did some filtering which I think is undesirable.
   Instead we should return the data as stored in the storage.

 * Touched handlers use the ABI interfaces where possible.

 * Local image resolution: previously Podman would match "foo" on
   "myfoo".  This behaviour has been changed and Podman will now
   only match on repository boundaries such that "foo" would match
   "my/foo" but not "myfoo".  I consider the old behaviour to be a
   bug, at the very least an exotic corner case.

 * Futhermore, "foo:none" does *not* resolve to a local image "foo"
   without tag anymore.  It's a hill I am (almost) willing to die on.

 * `image prune` prints the IDs of pruned images.  Previously, in some
   cases, the names were printed instead.  The API clearly states ID,
   so we should stick to it.

 * Compat endpoint image removal with _force_ deletes the entire not
   only the specified tag.

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
Valentin Rothberg
2021-04-22 08:01:12 +02:00
parent 8eefca5a25
commit 0f7d54b026
190 changed files with 8669 additions and 7743 deletions

View File

@@ -0,0 +1,92 @@
package libimage
import (
"strings"
"github.com/containers/image/v5/docker/reference"
"github.com/pkg/errors"
)
// NormalizeName normalizes the provided name according to the conventions by
// Podman and Buildah. If tag and digest are missing, the "latest" tag will be
// used. If it's a short name, it will be prefixed with "localhost/".
//
// References to docker.io are normalized according to the Docker conventions.
// For instance, "docker.io/foo" turns into "docker.io/library/foo".
func NormalizeName(name string) (reference.Named, error) {
// NOTE: this code is in symmetrie with containers/image/pkg/shortnames.
ref, err := reference.Parse(name)
if err != nil {
return nil, errors.Wrapf(err, "error normalizing name %q", name)
}
named, ok := ref.(reference.Named)
if !ok {
return nil, errors.Errorf("%q is not a named reference", name)
}
// Enforce "localhost" if needed.
registry := reference.Domain(named)
if !(strings.ContainsAny(registry, ".:") || registry == "localhost") {
name = toLocalImageName(ref.String())
}
// Another parse which also makes sure that docker.io references are
// correctly normalized (e.g., docker.io/alpine to
// docker.io/library/alpine).
named, err = reference.ParseNormalizedNamed(name)
if err != nil {
return nil, err
}
if _, hasTag := named.(reference.NamedTagged); hasTag {
return named, nil
}
if _, hasDigest := named.(reference.Digested); hasDigest {
return named, nil
}
// Make sure to tag "latest".
return reference.TagNameOnly(named), nil
}
// prefix the specified name with "localhost/".
func toLocalImageName(name string) string {
return "localhost/" + strings.TrimLeft(name, "/")
}
// NameTagPair represents a RepoTag of an image.
type NameTagPair struct {
// Name of the RepoTag. Maybe "<none>".
Name string
// Tag of the RepoTag. Maybe "<none>".
Tag string
// for internal use
named reference.Named
}
// ToNameTagsPairs splits repoTags into name&tag pairs.
// Guaranteed to return at least one pair.
func ToNameTagPairs(repoTags []reference.Named) ([]NameTagPair, error) {
none := "<none>"
var pairs []NameTagPair
for i, named := range repoTags {
pair := NameTagPair{
Name: named.Name(),
Tag: none,
named: repoTags[i],
}
if tagged, isTagged := named.(reference.NamedTagged); isTagged {
pair.Tag = tagged.Tag()
}
pairs = append(pairs, pair)
}
if len(pairs) == 0 {
pairs = append(pairs, NameTagPair{Name: none, Tag: none})
}
return pairs, nil
}