Pull pulls the specified name. Name may refer to any of the supported transports from github.com/containers/image. If no transport is encoded, name will be treated as a reference to a registry (i.e., docker transport). Note that pullPolicy is only used when pulling from a container registry but i
(ctx context.Context, name string, pullPolicy config.PullPolicy, options *PullOptions)
| 51 | // and no local image has been found. This allows for an easier integration |
| 52 | // into some users of this package (e.g., Buildah). |
| 53 | func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullPolicy, options *PullOptions) ([]*Image, error) { |
| 54 | logrus.Debugf("Pulling image %s (policy: %s)", name, pullPolicy) |
| 55 | |
| 56 | if options == nil { |
| 57 | options = &PullOptions{} |
| 58 | } |
| 59 | |
| 60 | var possiblyUnqualifiedName string // used for short-name resolution |
| 61 | ref, err := alltransports.ParseImageName(name) |
| 62 | if err != nil { |
| 63 | // Check whether `name` points to a transport. If so, we |
| 64 | // return the error. Otherwise we assume that `name` refers to |
| 65 | // an image on a registry (e.g., "fedora"). |
| 66 | // |
| 67 | // NOTE: the `docker` transport is an exception to support a |
| 68 | // `pull docker:latest` which would otherwise return an error. |
| 69 | if t := alltransports.TransportFromImageName(name); t != nil && t.Name() != registryTransport.Transport.Name() { |
| 70 | return nil, err |
| 71 | } |
| 72 | |
| 73 | // If the image clearly refers to a local one, we can look it up directly. |
| 74 | // In fact, we need to since they are not parseable. |
| 75 | if strings.HasPrefix(name, "sha256:") || (len(name) == 64 && !strings.ContainsAny(name, "/.:@")) { |
| 76 | if pullPolicy == config.PullPolicyAlways { |
| 77 | return nil, errors.Errorf("pull policy is always but image has been referred to by ID (%s)", name) |
| 78 | } |
| 79 | local, _, err := r.LookupImage(name, nil) |
| 80 | if err != nil { |
| 81 | return nil, err |
| 82 | } |
| 83 | return []*Image{local}, err |
| 84 | } |
| 85 | |
| 86 | // Docker compat: strip off the tag iff name is tagged and digested |
| 87 | // (e.g., fedora:latest@sha256...). In that case, the tag is stripped |
| 88 | // off and entirely ignored. The digest is the sole source of truth. |
| 89 | normalizedName, normalizeError := normalizeTaggedDigestedString(name) |
| 90 | if normalizeError != nil { |
| 91 | return nil, normalizeError |
| 92 | } |
| 93 | name = normalizedName |
| 94 | |
| 95 | // If the input does not include a transport assume it refers |
| 96 | // to a registry. |
| 97 | dockerRef, dockerErr := alltransports.ParseImageName("docker://" + name) |
| 98 | if dockerErr != nil { |
| 99 | return nil, err |
| 100 | } |
| 101 | ref = dockerRef |
| 102 | possiblyUnqualifiedName = name |
| 103 | } else if ref.Transport().Name() == registryTransport.Transport.Name() { |
| 104 | // Normalize the input if we're referring to the docker |
| 105 | // transport directly. That makes sure that a `docker://fedora` |
| 106 | // will resolve directly to `docker.io/library/fedora:latest` |
| 107 | // and not be subject to short-name resolution. |
| 108 | named := ref.DockerReference() |
| 109 | if named == nil { |
| 110 | return nil, errors.New("internal error: unexpected nil reference") |