copySingleImageFromRegistry pulls the specified, possibly unqualified, name from a registry. On successful pull it returns the ID of the image in local storage.
(ctx context.Context, imageName string, pullPolicy config.PullPolicy, options *PullOptions)
| 431 | // from a registry. On successful pull it returns the ID of the image in local |
| 432 | // storage. |
| 433 | func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName string, pullPolicy config.PullPolicy, options *PullOptions) ([]string, error) { //nolint:gocyclo |
| 434 | // Sanity check. |
| 435 | if err := pullPolicy.Validate(); err != nil { |
| 436 | return nil, err |
| 437 | } |
| 438 | |
| 439 | var ( |
| 440 | localImage *Image |
| 441 | resolvedImageName string |
| 442 | err error |
| 443 | ) |
| 444 | |
| 445 | // Always check if there's a local image. If so, we should use its |
| 446 | // resolved name for pulling. Assume we're doing a `pull foo`. |
| 447 | // If there's already a local image "localhost/foo", then we should |
| 448 | // attempt pulling that instead of doing the full short-name dance. |
| 449 | // |
| 450 | // NOTE that we only do platform checks if the specified values differ |
| 451 | // from the local platform. Unfortunately, there are many images used |
| 452 | // in the wild which don't set the correct value(s) in the config |
| 453 | // causing various issues such as containers/podman/issues/10682. |
| 454 | lookupImageOptions := &LookupImageOptions{Variant: options.Variant} |
| 455 | if options.Architecture != runtime.GOARCH { |
| 456 | lookupImageOptions.Architecture = options.Architecture |
| 457 | } |
| 458 | if options.OS != runtime.GOOS { |
| 459 | lookupImageOptions.OS = options.OS |
| 460 | } |
| 461 | localImage, resolvedImageName, err = r.LookupImage(imageName, lookupImageOptions) |
| 462 | if err != nil && errors.Cause(err) != storage.ErrImageUnknown { |
| 463 | logrus.Errorf("Looking up %s in local storage: %v", imageName, err) |
| 464 | } |
| 465 | |
| 466 | // If the local image is corrupted, we need to repull it. |
| 467 | if localImage != nil { |
| 468 | if err := localImage.isCorrupted(imageName); err != nil { |
| 469 | logrus.Error(err) |
| 470 | localImage = nil |
| 471 | } |
| 472 | } |
| 473 | |
| 474 | customPlatform := len(options.Architecture)+len(options.OS)+len(options.Variant) > 0 |
| 475 | if customPlatform && pullPolicy != config.PullPolicyAlways && pullPolicy != config.PullPolicyNever { |
| 476 | // Unless the pull policy is always/never, we must |
| 477 | // pessimistically assume that the local image has an invalid |
| 478 | // architecture (see containers/podman/issues/10682). Hence, |
| 479 | // whenever the user requests a custom platform, set the pull |
| 480 | // policy to "newer" to make sure we're pulling down the |
| 481 | // correct image. |
| 482 | // |
| 483 | // NOTE that this is will even override --pull={false,never}. |
| 484 | pullPolicy = config.PullPolicyNewer |
| 485 | logrus.Debugf("Enforcing pull policy to %q to pull custom platform (arch: %q, os: %q, variant: %q) - local image may mistakenly specify wrong platform", pullPolicy, options.Architecture, options.OS, options.Variant) |
| 486 | } |
| 487 | |
| 488 | if pullPolicy == config.PullPolicyNever { |
| 489 | if localImage != nil { |
| 490 | logrus.Debugf("Pull policy %q and %s resolved to local image %s", pullPolicy, imageName, resolvedImageName) |
no test coverage detected