mirror of https://github.com/containers/podman.git
pull: special case all-tags semantics
Supporting the all-tags semantics added some non-trivial code to the pull command which does not make use of `registries.conf` and introduced some regressions such as not adhering to the configured search registries. Speacial case the all-tags flags to let existing users of all-tags continue working while others can work again. This implies that the all-tags pull does not adhere to configured search registries while the default (non-all-tags) pull does. Note that this is a purely symptomaic fix. A final solution should include Buildah and the c/image library to avoid redundant and error-prone code across the projects. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1701922 Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
parent
b4cba6090d
commit
b90a5107e9
|
|
@ -46,7 +46,7 @@ func init() {
|
||||||
pullCommand.SetHelpTemplate(HelpTemplate())
|
pullCommand.SetHelpTemplate(HelpTemplate())
|
||||||
pullCommand.SetUsageTemplate(UsageTemplate())
|
pullCommand.SetUsageTemplate(UsageTemplate())
|
||||||
flags := pullCommand.Flags()
|
flags := pullCommand.Flags()
|
||||||
flags.BoolVar(&pullCommand.AllTags, "all-tags", false, "All tagged images inthe repository will be pulled")
|
flags.BoolVar(&pullCommand.AllTags, "all-tags", false, "All tagged images in the repository will be pulled")
|
||||||
flags.StringVar(&pullCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys")
|
flags.StringVar(&pullCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys")
|
||||||
flags.StringVar(&pullCommand.Creds, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry")
|
flags.StringVar(&pullCommand.Creds, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry")
|
||||||
flags.BoolVarP(&pullCommand.Quiet, "quiet", "q", false, "Suppress output information when pulling images")
|
flags.BoolVarP(&pullCommand.Quiet, "quiet", "q", false, "Suppress output information when pulling images")
|
||||||
|
|
@ -94,8 +94,9 @@ func pullCmd(c *cliconfig.PullValues) (retError error) {
|
||||||
return errors.Errorf("tag can't be used with --all-tags")
|
return errors.Errorf("tag can't be used with --all-tags")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := getContext()
|
ctx := getContext()
|
||||||
img := args[0]
|
imgArg := args[0]
|
||||||
|
|
||||||
var registryCreds *types.DockerAuthConfig
|
var registryCreds *types.DockerAuthConfig
|
||||||
|
|
||||||
|
|
@ -122,68 +123,86 @@ func pullCmd(c *cliconfig.PullValues) (retError error) {
|
||||||
dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!c.TlsVerify)
|
dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!c.TlsVerify)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Possible for docker-archive to have multiple tags, so use LoadFromArchiveReference instead
|
// Special-case for docker-archive which allows multiple tags.
|
||||||
if strings.HasPrefix(img, dockerarchive.Transport.Name()+":") {
|
if strings.HasPrefix(imgArg, dockerarchive.Transport.Name()+":") {
|
||||||
srcRef, err := alltransports.ParseImageName(img)
|
srcRef, err := alltransports.ParseImageName(imgArg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error parsing %q", img)
|
return errors.Wrapf(err, "error parsing %q", imgArg)
|
||||||
}
|
}
|
||||||
newImage, err := runtime.LoadFromArchiveReference(getContext(), srcRef, c.SignaturePolicy, writer)
|
newImage, err := runtime.LoadFromArchiveReference(getContext(), srcRef, c.SignaturePolicy, writer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error pulling image from %q", img)
|
return errors.Wrapf(err, "error pulling image from %q", imgArg)
|
||||||
}
|
}
|
||||||
fmt.Println(newImage[0].ID())
|
fmt.Println(newImage[0].ID())
|
||||||
} else {
|
|
||||||
authfile := getAuthFile(c.String("authfile"))
|
return nil
|
||||||
spec := img
|
}
|
||||||
systemContext := image.GetSystemContext("", authfile, false)
|
|
||||||
srcRef, err := alltransports.ParseImageName(spec)
|
authfile := getAuthFile(c.String("authfile"))
|
||||||
|
|
||||||
|
// FIXME: the default pull consults the registries.conf's search registries
|
||||||
|
// while the all-tags pull does not. This behavior must be fixed in the
|
||||||
|
// future and span across c/buildah, c/image and c/libpod to avoid redundant
|
||||||
|
// and error prone code.
|
||||||
|
//
|
||||||
|
// See https://bugzilla.redhat.com/show_bug.cgi?id=1701922 for background
|
||||||
|
// information.
|
||||||
|
if !c.Bool("all-tags") {
|
||||||
|
newImage, err := runtime.New(getContext(), imgArg, c.SignaturePolicy, authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, true, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dockerTransport := "docker://"
|
return errors.Wrapf(err, "error pulling image %q", imgArg)
|
||||||
logrus.Debugf("error parsing image name %q, trying with transport %q: %v", spec, dockerTransport, err)
|
|
||||||
spec = dockerTransport + spec
|
|
||||||
srcRef2, err2 := alltransports.ParseImageName(spec)
|
|
||||||
if err2 != nil {
|
|
||||||
return errors.Wrapf(err2, "error parsing image name %q", img)
|
|
||||||
}
|
|
||||||
srcRef = srcRef2
|
|
||||||
}
|
}
|
||||||
var names []string
|
fmt.Println(newImage.ID())
|
||||||
if c.Bool("all-tags") {
|
return nil
|
||||||
if srcRef.DockerReference() == nil {
|
}
|
||||||
return errors.New("Non-docker transport is currently not supported")
|
|
||||||
}
|
// FIXME: all-tags should use the libpod backend instead of baking its own bread.
|
||||||
tags, err := docker.GetRepositoryTags(ctx, systemContext, srcRef)
|
spec := imgArg
|
||||||
if err != nil {
|
systemContext := image.GetSystemContext("", authfile, false)
|
||||||
return errors.Wrapf(err, "error getting repository tags")
|
srcRef, err := alltransports.ParseImageName(spec)
|
||||||
}
|
if err != nil {
|
||||||
for _, tag := range tags {
|
dockerTransport := "docker://"
|
||||||
name := spec + ":" + tag
|
logrus.Debugf("error parsing image name %q, trying with transport %q: %v", spec, dockerTransport, err)
|
||||||
names = append(names, name)
|
spec = dockerTransport + spec
|
||||||
}
|
srcRef2, err2 := alltransports.ParseImageName(spec)
|
||||||
} else {
|
if err2 != nil {
|
||||||
names = append(names, spec)
|
return errors.Wrapf(err2, "error parsing image name %q", imgArg)
|
||||||
}
|
}
|
||||||
var foundIDs []string
|
srcRef = srcRef2
|
||||||
foundImage := true
|
}
|
||||||
for _, name := range names {
|
var names []string
|
||||||
newImage, err := runtime.New(getContext(), name, c.String("signature-policy"), authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, true, nil)
|
if srcRef.DockerReference() == nil {
|
||||||
if err != nil {
|
return errors.New("Non-docker transport is currently not supported")
|
||||||
logrus.Errorf("error pulling image %q", name)
|
}
|
||||||
foundImage = false
|
tags, err := docker.GetRepositoryTags(ctx, systemContext, srcRef)
|
||||||
continue
|
if err != nil {
|
||||||
}
|
return errors.Wrapf(err, "error getting repository tags")
|
||||||
foundIDs = append(foundIDs, newImage.ID())
|
}
|
||||||
|
for _, tag := range tags {
|
||||||
|
name := spec + ":" + tag
|
||||||
|
names = append(names, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
var foundIDs []string
|
||||||
|
foundImage := true
|
||||||
|
for _, name := range names {
|
||||||
|
newImage, err := runtime.New(getContext(), name, c.String("signature-policy"), authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, true, nil)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("error pulling image %q", name)
|
||||||
|
foundImage = false
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if len(names) == 1 && !foundImage {
|
foundIDs = append(foundIDs, newImage.ID())
|
||||||
return errors.Wrapf(err, "error pulling image %q", img)
|
}
|
||||||
}
|
if len(names) == 1 && !foundImage {
|
||||||
if len(names) > 1 {
|
return errors.Wrapf(err, "error pulling image %q", imgArg)
|
||||||
fmt.Println("Pulled Images:")
|
}
|
||||||
}
|
if len(names) > 1 {
|
||||||
for _, id := range foundIDs {
|
fmt.Println("Pulled Images:")
|
||||||
fmt.Println(id)
|
}
|
||||||
}
|
for _, id := range foundIDs {
|
||||||
} // end else if strings.HasPrefix(img, dockerarchive.Transport.Name()+":")
|
fmt.Println(id)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,8 @@ Image stored in local container/storage
|
||||||
|
|
||||||
All tagged images in the repository will be pulled.
|
All tagged images in the repository will be pulled.
|
||||||
|
|
||||||
|
Note: When using the all-tags flag, Podman will not iterate over the search registries in the containers-registries.conf(5) but will always use docker.io for unqualified image names.
|
||||||
|
|
||||||
**--authfile**
|
**--authfile**
|
||||||
|
|
||||||
Path of the authentication file. Default is ${XDG_RUNTIME\_DIR}/containers/auth.json, which is set using `podman login`.
|
Path of the authentication file. Default is ${XDG_RUNTIME\_DIR}/containers/auth.json, which is set using `podman login`.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue