Skip to content

Commit 9eced04

Browse files
authored
Merge pull request kubernetes#91007 from lsytj0413/fix-89443
test(e2e_node): Parallelize prepulling all images in `e2e_node` tests
2 parents bf94f27 + 6409489 commit 9eced04

File tree

2 files changed

+59
-19
lines changed

2 files changed

+59
-19
lines changed

test/e2e_node/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ go_library(
4141
"//staging/src/k8s.io/api/core/v1:go_default_library",
4242
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
4343
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
44+
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
4445
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
4546
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
4647
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",

test/e2e_node/image_list.go

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@ limitations under the License.
1717
package e2enode
1818

1919
import (
20+
"context"
2021
"fmt"
2122
"os"
2223
"os/exec"
2324
"os/user"
25+
"sync"
2426
"time"
2527

2628
"k8s.io/klog/v2"
2729

30+
utilerrors "k8s.io/apimachinery/pkg/util/errors"
2831
"k8s.io/apimachinery/pkg/util/sets"
2932
internalapi "k8s.io/cri-api/pkg/apis"
3033
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
@@ -41,6 +44,8 @@ const (
4144
maxImagePullRetries = 5
4245
// Sleep duration between image pull retry attempts.
4346
imagePullRetryDelay = time.Second
47+
// Number of parallel count to pull images.
48+
maxParallelImagePullCount = 5
4449
)
4550

4651
// NodePrePullImageList is a list of images used in node e2e test. These images will be prepulled
@@ -151,27 +156,61 @@ func PrePullAllImages() error {
151156
}
152157
images := framework.ImagePrePullList.List()
153158
klog.V(4).Infof("Pre-pulling images with %s %+v", puller.Name(), images)
154-
for _, image := range images {
155-
var (
156-
err error
157-
output []byte
158-
)
159-
for i := 0; i < maxImagePullRetries; i++ {
160-
if i > 0 {
161-
time.Sleep(imagePullRetryDelay)
162-
}
163-
if output, err = puller.Pull(image); err == nil {
164-
break
159+
160+
imageCh := make(chan int, len(images))
161+
for i := range images {
162+
imageCh <- i
163+
}
164+
close(imageCh)
165+
166+
pullErrs := make([]error, len(images))
167+
ctx, cancel := context.WithCancel(context.Background())
168+
defer cancel()
169+
170+
parallelImagePullCount := maxParallelImagePullCount
171+
if len(images) < parallelImagePullCount {
172+
parallelImagePullCount = len(images)
173+
}
174+
175+
var wg sync.WaitGroup
176+
wg.Add(parallelImagePullCount)
177+
for i := 0; i < parallelImagePullCount; i++ {
178+
go func() {
179+
defer wg.Done()
180+
181+
for i := range imageCh {
182+
var (
183+
pullErr error
184+
output []byte
185+
)
186+
for retryCount := 0; retryCount < maxImagePullRetries; retryCount++ {
187+
select {
188+
case <-ctx.Done():
189+
return
190+
default:
191+
}
192+
193+
if retryCount > 0 {
194+
time.Sleep(imagePullRetryDelay)
195+
}
196+
if output, pullErr = puller.Pull(images[i]); pullErr == nil {
197+
break
198+
}
199+
klog.Warningf("Failed to pull %s as user %q, retrying in %s (%d of %d): %v",
200+
images[i], usr.Username, imagePullRetryDelay.String(), retryCount+1, maxImagePullRetries, pullErr)
201+
}
202+
if pullErr != nil {
203+
klog.Warningf("Could not pre-pull image %s %v output: %s", images[i], pullErr, output)
204+
pullErrs[i] = pullErr
205+
cancel()
206+
return
207+
}
165208
}
166-
klog.Warningf("Failed to pull %s as user %q, retrying in %s (%d of %d): %v",
167-
image, usr.Username, imagePullRetryDelay.String(), i+1, maxImagePullRetries, err)
168-
}
169-
if err != nil {
170-
klog.Warningf("Could not pre-pull image %s %v output: %s", image, err, output)
171-
return err
172-
}
209+
}()
173210
}
174-
return nil
211+
212+
wg.Wait()
213+
return utilerrors.NewAggregate(pullErrs)
175214
}
176215

177216
// getGPUDevicePluginImage returns the image of GPU device plugin.

0 commit comments

Comments
 (0)