func pullImages()

in internal/components/setup/kind.go [97:152]


func pullImages(ctx context.Context, images []string) error {
	cli, err := docker.NewClientWithOpts(docker.FromEnv)
	if err != nil {
		return err
	}
	defer cli.Close()

	localImages, err := listLocalImages(ctx, cli)
	if err != nil {
		return fmt.Errorf("list local images error: %w", err)
	}

	// filter local image
	filter := func(tags []string) []string {
		res := make([]string, 0)
		for _, tag := range tags {
			if _, ok := localImages[tag]; !ok {
				res = append(res, tag)
			}
		}
		return res
	}

	filterResult := filter(images)
	if len(filterResult) == 0 {
		return nil
	}

	var count int32
	var wg sync.WaitGroup
	for _, image := range filterResult {
		wg.Add(1)
		go func(image string) {
			defer wg.Done()
			logger.Log.Infof("image %s does not exist, will pull from remote", image)
			out, err := cli.ImagePull(ctx, image, types.ImagePullOptions{})
			if err != nil {
				logger.Log.WithError(err).Errorf("failed pull image: %s", image)
				return
			}
			defer out.Close()

			if _, err := io.ReadAll(out); err != nil {
				logger.Log.WithError(err).Errorf("failed pull image: %s", image)
				return
			}
			atomic.AddInt32(&count, 1)
			logger.Log.Infof("success pull image: %s", image)
		}(image)
	}
	wg.Wait()
	if int(count) != len(filterResult) {
		return errors.New("can not pull all images")
	}
	return nil
}