PullImage pulls the provided image.
(ctx context.Context, config *PullImageConfig)
| 63 | |
| 64 | // PullImage pulls the provided image. |
| 65 | func PullImage(ctx context.Context, config *PullImageConfig) error { |
| 66 | authStr, err := config.Auth.Base64() |
| 67 | if err != nil { |
| 68 | return xerrors.Errorf("base64 encode auth: %w", err) |
| 69 | } |
| 70 | |
| 71 | pullImageFn := func() error { |
| 72 | var rd io.ReadCloser |
| 73 | rd, err = config.Client.ImagePull(ctx, config.Image, image.PullOptions{ |
| 74 | RegistryAuth: authStr, |
| 75 | }) |
| 76 | if err != nil { |
| 77 | return xerrors.Errorf("pull image: %w", err) |
| 78 | } |
| 79 | |
| 80 | err = processImagePullEvents(rd, config.ProgressFn) |
| 81 | if err != nil { |
| 82 | return xerrors.Errorf("process image pull events: %w", err) |
| 83 | } |
| 84 | return nil |
| 85 | } |
| 86 | |
| 87 | err = pullImageFn() |
| 88 | // We should bail early if we're going to fail due to a |
| 89 | // certificate error. We can't xerrors.As here since this is |
| 90 | // returned from the daemon so the client is reporting |
| 91 | // essentially an unwrapped error. |
| 92 | if isTLSVerificationErr(err) { |
| 93 | return err |
| 94 | } |
| 95 | |
| 96 | if err == nil { |
| 97 | return nil |
| 98 | } |
| 99 | |
| 100 | var pruned bool |
| 101 | for r, n := retry.New(time.Second, time.Second*3), 0; r.Wait(ctx) && n < 10; n++ { |
| 102 | err = pullImageFn() |
| 103 | if err != nil { |
| 104 | // If we failed to pull the image, try to prune existing images |
| 105 | // to free up space. |
| 106 | if xunix.IsNoSpaceErr(err) && !pruned { |
| 107 | pruned = true |
| 108 | // Pruning is best effort. |
| 109 | _, _ = PruneImages(ctx, config.Client) |
| 110 | } |
| 111 | // If we've already pruned and we still can't pull the image we |
| 112 | // should just exit. |
| 113 | if xunix.IsNoSpaceErr(err) && pruned { |
| 114 | return xerrors.Errorf("insufficient disk to pull image: %w", err) |
| 115 | } |
| 116 | continue |
| 117 | } |
| 118 | return nil |
| 119 | } |
| 120 | if err != nil { |
| 121 | return xerrors.Errorf("pull image: %w", err) |
| 122 | } |
no test coverage detected