func()

in gcs-fetcher/pkg/fetcher/fetcher.go [352:425]


func (gf *Fetcher) fetchObjectOnce(ctx context.Context, j job, dest string, breakerSig <-chan struct{}) fetchOnceResult {
	var result fetchOnceResult

	r, err := gf.GCS.NewReader(ctx, j.bucket, j.object)
	if err != nil {
		// Check for AccessDenied failure here and return a useful error message on Stderr and exit immediately.
		if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == http.StatusForbidden {
			// Try to parse out the robot name.
			match := robotRegex.FindStringSubmatch(err.Error())
			robot := "your Cloud Build service account"
			if len(match) == 2 {
				robot = match[1]
			}
			result.err = &permissionError{bucket: j.bucket, robot: robot}
			return result
		}
		result.err = fmt.Errorf("creating GCS reader for %q: %v", formatGCSName(j.bucket, j.object, j.generation), err)
		return result
	}
	defer func() {
		if cerr := r.Close(); cerr != nil {
			result.err = fmt.Errorf("Failed to close GCS reader: %v", cerr)
		}
	}()

	// If we're cancelled, just return.
	select {
	case <-breakerSig:
		result.err = errGCSTimeout
		return result
	default:
		// Fallthrough
	}

	f, err := gf.OS.Create(dest)
	if err != nil {
		result.err = fmt.Errorf("creating destination file %q: %v", dest, err)
		return result
	}
	defer func() {
		if cerr := f.Close(); cerr != nil {
			result.err = fmt.Errorf("Failed to close file %q: %v", dest, cerr)
		}
	}()

	h := sha1.New()
	n, err := io.Copy(f, io.TeeReader(r, h))
	if err != nil {
		result.err = fmt.Errorf("copying bytes from %q to %q: %v", formatGCSName(j.bucket, j.object, j.generation), dest, err)
		return result
	}

	// If we're cancelled, just return.
	select {
	case <-breakerSig:
		result.err = errGCSTimeout
		return result
	default:
		// Fallthrough
	}

	result.size = sizeBytes(n)

	// Verify the sha1sum before declaring success.
	if j.sha1sum != "" {
		got := strings.ToLower(fmt.Sprintf("%x", h.Sum(nil)))
		want := strings.ToLower(nonHexRegex.ReplaceAllString(j.sha1sum, ""))
		if got != want {
			result.err = fmt.Errorf("%s SHA mismatch, got %q, want %q", j.filename, got, want)
			return result
		}
	}
	return result
}