Skip to content

Commit 19db362

Browse files
authored
feat: parallelize copy/client.ImageExistsAtRemote calls (#1)
1 parent 99c0304 commit 19db362

File tree

1 file changed

+26
-9
lines changed

1 file changed

+26
-9
lines changed

internal/commands/copy.go

+26-9
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"sync"
78
"time"
89

10+
"golang.org/x/sync/errgroup"
11+
912
"github.com/containers/image/v5/copy"
1013
dockerv5 "github.com/containers/image/v5/docker"
1114
"github.com/containers/image/v5/signature"
@@ -80,16 +83,30 @@ func runCopyCommand() error {
8083

8184
log.Infof("Finding images that need to be copied ...")
8285

86+
errs, errCtx := errgroup.WithContext(ctx)
87+
errs.SetLimit(20)
88+
var mu sync.Mutex
8389
var sourcesToCopy []manifest.Source
8490
for _, source := range sources {
85-
exists, err := client.ImageExistsAtRemote(ctx, source.TargetImage())
86-
if err != nil {
87-
return fmt.Errorf("image exists at remote: %w", err)
88-
}
91+
source := source
92+
errs.Go(func() error {
93+
exists, err := client.ImageExistsAtRemote(errCtx, source.TargetImage())
94+
if err != nil {
95+
return fmt.Errorf("image exists at remote: %w", err)
96+
}
8997

90-
if !exists || viper.GetBool("force") {
91-
sourcesToCopy = append(sourcesToCopy, source)
92-
}
98+
if !exists || viper.GetBool("force") {
99+
mu.Lock()
100+
sourcesToCopy = append(sourcesToCopy, source)
101+
mu.Unlock()
102+
}
103+
104+
return nil
105+
})
106+
}
107+
108+
if err := errs.Wait(); err != nil {
109+
return err
93110
}
94111

95112
if len(sourcesToCopy) == 0 {
@@ -135,12 +152,12 @@ func runCopyCommand() error {
135152
log.Infof("Copying image %s to %s", source.Image(), source.TargetImage())
136153
destRef, err := imageTransport.ParseReference(fmt.Sprintf("//%s", source.TargetImage()))
137154
if err != nil {
138-
return fmt.Errorf("Error parsing target image reference: %w", err)
155+
return fmt.Errorf("unable to parse target image reference: %w", err)
139156
}
140157

141158
srcRef, err := imageTransport.ParseReference(fmt.Sprintf("//%s", source.Image()))
142159
if err != nil {
143-
return fmt.Errorf("Error parsing source image reference: %w", err)
160+
return fmt.Errorf("unable to parse source image reference: %w", err)
144161
}
145162

146163
if _, err := copy.Image(ctx, policyContext, destRef, srcRef, &copyOptions); err != nil {

0 commit comments

Comments
 (0)