prow/clonerefs/run.go
func (o Options) Run() error {
	var env []string
	if len(o.KeyFiles) > 0 {
		var err error
		env, err = addSSHKeys(o.KeyFiles)
		if err != nil {
			logrus.WithError(err).Error("Failed to add SSH keys.")
			// Continue on error. Clones will fail with an appropriate error message
			// that initupload can consume whereas quitting without writing the clone
			// record log is silent and results in an errored prow job instead of a
			// failed one.
		}
	}
	if len(o.HostFingerprints) > 0 {
		if err := addHostFingerprints(o.HostFingerprints); err != nil {
			logrus.WithError(err).Error("failed to add host fingerprints")
		}
	}

	var numWorkers int
	if o.MaxParallelWorkers != 0 {
		numWorkers = o.MaxParallelWorkers
	} else {
		numWorkers = len(o.GitRefs)
	}

	wg := &sync.WaitGroup{}
	wg.Add(numWorkers)

	input := make(chan prowapi.Refs)
	output := make(chan clone.Record, len(o.GitRefs))
	for i := 0; i < numWorkers; i++ {
		go func() {
			defer wg.Done()
			for ref := range input {
				output <- cloneFunc(ref, o.SrcRoot, o.GitUserName, o.GitUserEmail, o.CookiePath, env)
			}
		}()
	}

	for _, ref := range o.GitRefs {
		input <- ref
	}

	close(input)
	wg.Wait()
	close(output)

	var results []clone.Record
	for record := range output {
		results = append(results, record)
	}

	logData, err := json.Marshal(results)
	if err != nil {
		return fmt.Errorf("failed to marshal clone records: %v", err)
	}

	if err := ioutil.WriteFile(o.Log, logData, 0755); err != nil {
		return fmt.Errorf("failed to write clone records: %v", err)
	}

	return nil
}
func (o Options) Run() error {
	var env []string
	if len(o.KeyFiles) > 0 {
		var err error
		env, err = addSSHKeys(o.KeyFiles)
		if err != nil {
			logrus.WithError(err).Error("Failed to add SSH keys.")
			// Continue on error. Clones will fail with an appropriate error message
			// that initupload can consume whereas quitting without writing the clone
			// record log is silent and results in an errored prow job instead of a
			// failed one.
		}
	}
	if len(o.HostFingerprints) > 0 {
		if err := addHostFingerprints(o.HostFingerprints); err != nil {
			logrus.WithError(err).Error("failed to add host fingerprints")
		}
	}

	var numWorkers int
	if o.MaxParallelWorkers != 0 {
		numWorkers = o.MaxParallelWorkers
	} else {
		numWorkers = len(o.GitRefs)
	}

	wg := &sync.WaitGroup{}
	wg.Add(numWorkers)

	input := make(chan prowapi.Refs)
	output := make(chan clone.Record, len(o.GitRefs))
	for i := 0; i < numWorkers; i++ {
		go func() {
			defer wg.Done()
			for ref := range input {
				output <- cloneFunc(ref, o.SrcRoot, o.GitUserName, o.GitUserEmail, o.CookiePath, env)
			}
		}()
	}

	for _, ref := range o.GitRefs {
		input <- ref
	}

	close(input)
	wg.Wait()
	close(output)

	var results []clone.Record
	for record := range output {
		results = append(results, record)
	}

	logData, err := json.Marshal(results)
	if err != nil {
		return fmt.Errorf("failed to marshal clone records: %v", err)
	}

	if err := ioutil.WriteFile(o.Log, logData, 0755); err != nil {
		return fmt.Errorf("failed to write clone records: %v", err)
	}

	return nil
}
// Run clones the configured refs