golang.org/x/build@v0.0.0-20240506185731-218518f32b70/internal/task/scratchfs.go (about)

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package task
     6  
     7  import (
     8  	"fmt"
     9  	"io/fs"
    10  	"math/rand"
    11  
    12  	"cloud.google.com/go/storage"
    13  	"golang.org/x/build/internal/gcsfs"
    14  	wf "golang.org/x/build/internal/workflow"
    15  )
    16  
    17  // ScratchFS manages scratch storage for workflows.
    18  type ScratchFS struct {
    19  	BaseURL string // BaseURL is a gs:// or file:// URL, no trailing slash. E.g., "gs://golang-release-staging/relui-scratch".
    20  	GCS     *storage.Client
    21  }
    22  
    23  // OpenRead opens a file in the workflow's scratch storage.
    24  func (s *ScratchFS) OpenRead(ctx *wf.TaskContext, name string) (fs.File, error) {
    25  	sfs, err := s.fs(ctx)
    26  	if err != nil {
    27  		return nil, err
    28  	}
    29  	return sfs.Open(name)
    30  }
    31  
    32  // ReadFile fully reads a file in the workflow's scratch storage.
    33  func (s *ScratchFS) ReadFile(ctx *wf.TaskContext, name string) ([]byte, error) {
    34  	sfs, err := s.fs(ctx)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	return fs.ReadFile(sfs, name)
    39  }
    40  
    41  // OpenWrite creates a new file in the workflow's scratch storage, with a name
    42  // based on baseName. It returns that name, as well as the open file.
    43  func (s *ScratchFS) OpenWrite(ctx *wf.TaskContext, baseName string) (name string, _ gcsfs.WriterFile, _ error) {
    44  	sfs, err := s.fs(ctx)
    45  	if err != nil {
    46  		return "", nil, err
    47  	}
    48  	name = fmt.Sprintf("%v-%v", rand.Int63(), baseName)
    49  	f, err := gcsfs.Create(sfs, name)
    50  	return name, f, err
    51  }
    52  
    53  // WriteFilename returns a filename that can be used to write a new scratch file
    54  // suitable for writing from an external systems.
    55  func (s *ScratchFS) WriteFilename(ctx *wf.TaskContext, baseName string) string {
    56  	return fmt.Sprintf("%v-%v", rand.Int63(), baseName)
    57  }
    58  
    59  // URL returns the URL of a file in the workflow's scratch storage, suitable
    60  // for passing to external systems.
    61  func (s *ScratchFS) URL(ctx *wf.TaskContext, name string) string {
    62  	return fmt.Sprintf("%v/%v/%v", s.BaseURL, ctx.WorkflowID.String(), name)
    63  }
    64  
    65  func (s *ScratchFS) fs(ctx *wf.TaskContext) (fs.FS, error) {
    66  	sfs, err := gcsfs.FromURL(ctx, s.GCS, s.BaseURL)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	return fs.Sub(sfs, ctx.WorkflowID.String())
    71  }