PullImage pulls an image according to the given request and credentials initialized at client creation from the Daemon config or credentials helpers configured there. It takes a caller-provided channel on which docker events are sent. Slow receivers will block the call.
(ctx context.Context, req PullImage, p events.Publisher[Event])
| 165 | // creation from the Daemon config or credentials helpers configured there. It takes a |
| 166 | // caller-provided channel on which docker events are sent. Slow receivers will block the call. |
| 167 | func (d *Client) PullImage(ctx context.Context, req PullImage, p events.Publisher[Event]) error { |
| 168 | ref, err := reference.ParseNormalizedNamed(req.Name) |
| 169 | if err != nil { |
| 170 | return fmt.Errorf("error parsing image name %s: %w", req.Name, err) |
| 171 | } |
| 172 | ref = reference.TagNameOnly(ref) |
| 173 | switch _, _, err = d.cl.ImageInspectWithRaw(ctx, ref.String()); { |
| 174 | case req.ForcePull: |
| 175 | if err != nil { |
| 176 | break |
| 177 | } |
| 178 | |
| 179 | if err = p.Publish(ctx, NewLogEvent(model.LogLevelInfo, fmt.Sprintf( |
| 180 | "image present, but force_pull_image is set; checking for updates: %s", |
| 181 | ref.String(), |
| 182 | ))); err != nil { |
| 183 | return err |
| 184 | } |
| 185 | case client.IsErrNotFound(err): |
| 186 | if err = p.Publish(ctx, NewLogEvent(model.LogLevelInfo, fmt.Sprintf( |
| 187 | "image not found, pulling image: %s", ref.String(), |
| 188 | ))); err != nil { |
| 189 | return err |
| 190 | } |
| 191 | case err != nil: |
| 192 | return fmt.Errorf("error checking if image exists %s: %w", ref.String(), err) |
| 193 | default: |
| 194 | if err = p.Publish(ctx, NewLogEvent(model.LogLevelInfo, fmt.Sprintf( |
| 195 | "image already found, skipping pull phase: %s", |
| 196 | ref.String(), |
| 197 | ))); err != nil { |
| 198 | return err |
| 199 | } |
| 200 | return nil |
| 201 | } |
| 202 | |
| 203 | if err = p.Publish(ctx, NewBeginStatsEvent(ImagePullStatsKind)); err != nil { |
| 204 | return err |
| 205 | } |
| 206 | defer func() { |
| 207 | if scErr := p.Publish(ctx, NewEndStatsEvent(ImagePullStatsKind)); scErr != nil { |
| 208 | d.log.WithError(scErr).Warn("did not send image pull done stats") |
| 209 | } |
| 210 | }() |
| 211 | |
| 212 | auth, err := d.getDockerAuths(ctx, ref, req.Registry, p) |
| 213 | if err != nil { |
| 214 | return fmt.Errorf("could not get docker authentication: %w", err) |
| 215 | } |
| 216 | |
| 217 | authString, err := registryToString(*auth) |
| 218 | if err != nil { |
| 219 | return fmt.Errorf("error encoding docker credentials: %w", err) |
| 220 | } |
| 221 | |
| 222 | logs, err := d.cl.ImagePull(ctx, ref.String(), types.ImagePullOptions{ |
| 223 | All: false, |
| 224 | RegistryAuth: authString, |