copyImages starts a goroutine for each tag that points to the image oldRepo@digest, or just copies the image by digest if there are no tags.
(_ context.Context, t task)
| 209 | // copyImages starts a goroutine for each tag that points to the image |
| 210 | // oldRepo@digest, or just copies the image by digest if there are no tags. |
| 211 | func (c *copier) copyImages(_ context.Context, t task) error { |
| 212 | // We only have to explicitly copy by digest if there are no tags pointing to this manifest. |
| 213 | if len(t.manifest.Tags) == 0 { |
| 214 | srcImg := fmt.Sprintf("%s@%s", t.oldRepo, t.digest) |
| 215 | dstImg := fmt.Sprintf("%s@%s", t.newRepo, t.digest) |
| 216 | |
| 217 | return crane.Copy(srcImg, dstImg, c.opt.crane...) |
| 218 | } |
| 219 | |
| 220 | // We only need to push the whole image once. |
| 221 | tag := t.manifest.Tags[0] |
| 222 | srcImg := fmt.Sprintf("%s:%s", t.oldRepo, tag) |
| 223 | dstImg := fmt.Sprintf("%s:%s", t.newRepo, tag) |
| 224 | |
| 225 | if err := crane.Copy(srcImg, dstImg, c.opt.crane...); err != nil { |
| 226 | return err |
| 227 | } |
| 228 | |
| 229 | if len(t.manifest.Tags) <= 1 { |
| 230 | // If there's only one tag, we're done. |
| 231 | return nil |
| 232 | } |
| 233 | |
| 234 | // Add the rest of the tags. |
| 235 | srcRef, err := name.ParseReference(srcImg) |
| 236 | if err != nil { |
| 237 | return err |
| 238 | } |
| 239 | desc, err := remote.Get(srcRef, c.opt.remote...) |
| 240 | if err != nil { |
| 241 | return err |
| 242 | } |
| 243 | |
| 244 | for _, tag := range t.manifest.Tags[1:] { |
| 245 | dstImg := t.newRepo.Tag(tag) |
| 246 | |
| 247 | if err := remote.Tag(dstImg, desc, c.opt.remote...); err != nil { |
| 248 | return err |
| 249 | } |
| 250 | } |
| 251 | |
| 252 | return nil |
| 253 | } |
| 254 | |
| 255 | // Retry temporary errors, 429, and 500+ with backoff. |
| 256 | func backoffErrors(bo retry.Backoff, f func() error) error { |
no test coverage detected