github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/vcs/fuchsia.go (about)

     1  // Copyright 2018 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  package vcs
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"path/filepath"
    10  	"time"
    11  
    12  	"github.com/google/syzkaller/pkg/osutil"
    13  )
    14  
    15  // TODO: Check out branches and commits from Fuchsia's global integration repo
    16  // rather than fuchsia.git.
    17  type fuchsia struct {
    18  	dir  string
    19  	repo *gitRepo
    20  }
    21  
    22  func newFuchsia(dir string, opts []RepoOpt) *fuchsia {
    23  	// For now, don't clean up the Fuchsia repo when checking out new commits or branches.
    24  	// Otherwise, subsequent builds will fail due to missing GN args and other build configuration.
    25  	// TODO: Implement selective cleanup with `fx clean`.
    26  	opts = append(opts, OptPrecious)
    27  	return &fuchsia{
    28  		dir:  dir,
    29  		repo: newGitRepo(dir, nil, opts),
    30  	}
    31  }
    32  
    33  func (ctx *fuchsia) Poll(repo, branch string) (*Commit, error) {
    34  	if repo != "https://fuchsia.googlesource.com/fuchsia" || (branch != "main" && branch != "master") {
    35  		// Fuchsia ecosystem is hard-wired to the main repo + branch.
    36  		// The 'master' branch is a mirror of 'main'.
    37  		return nil, fmt.Errorf(
    38  			"fuchsia: can only check out 'main' or 'master' branch of https://fuchsia.googlesource.com/fuchsia",
    39  		)
    40  	}
    41  	if _, err := runSandboxed(ctx.dir, "./.jiri_root/bin/jiri", "update"); err != nil {
    42  		if err := ctx.initRepo(); err != nil {
    43  			return nil, err
    44  		}
    45  	}
    46  	return ctx.repo.Commit(HEAD)
    47  }
    48  
    49  func (ctx *fuchsia) initRepo() error {
    50  	if err := os.RemoveAll(ctx.dir); err != nil {
    51  		return fmt.Errorf("failed to remove repo dir: %w", err)
    52  	}
    53  	tmpDir := ctx.dir + ".tmp"
    54  	if err := osutil.MkdirAll(tmpDir); err != nil {
    55  		return fmt.Errorf("failed to create repo dir: %w", err)
    56  	}
    57  	defer os.RemoveAll(tmpDir)
    58  	if err := osutil.SandboxChown(tmpDir); err != nil {
    59  		return err
    60  	}
    61  	cmd := "curl -s 'https://fuchsia.googlesource.com/fuchsia/+/main/scripts/bootstrap?format=TEXT' |" +
    62  		"base64 --decode | bash"
    63  	// TODO: Remove the second `jiri update` once the `prebuilt_versions` hook is fixed.
    64  	// Expect and ignore an error from the bootstrap script's invocation of `jiri update`.
    65  	_, _ = runSandboxed(tmpDir, "bash", "-c", cmd)
    66  	// Run `jiri update` a second time; it should succeed.
    67  	if _, err := runSandboxed(filepath.Join(tmpDir, "fuchsia"), "./.jiri_root/bin/jiri", "update"); err != nil {
    68  		return err
    69  	}
    70  	return osutil.Rename(filepath.Join(tmpDir, "fuchsia"), ctx.dir)
    71  }
    72  
    73  func (ctx *fuchsia) CheckoutBranch(repo, branch string) (*Commit, error) {
    74  	return ctx.repo.CheckoutBranch(repo, branch)
    75  }
    76  
    77  func (ctx *fuchsia) CheckoutCommit(repo, commit string) (*Commit, error) {
    78  	return ctx.repo.CheckoutCommit(repo, commit)
    79  }
    80  
    81  func (ctx *fuchsia) SwitchCommit(commit string) (*Commit, error) {
    82  	return ctx.repo.SwitchCommit(commit)
    83  }
    84  
    85  func (ctx *fuchsia) Commit(commit string) (*Commit, error) {
    86  	return ctx.repo.Commit(commit)
    87  }
    88  
    89  func (ctx *fuchsia) GetCommitByTitle(title string) (*Commit, error) {
    90  	return ctx.repo.GetCommitByTitle(title)
    91  }
    92  
    93  func (ctx *fuchsia) GetCommitsByTitles(titles []string) ([]*Commit, []string, error) {
    94  	return ctx.repo.GetCommitsByTitles(titles)
    95  }
    96  
    97  func (ctx *fuchsia) ExtractFixTagsFromCommits(baseCommit, email string) ([]*Commit, error) {
    98  	return ctx.repo.ExtractFixTagsFromCommits(baseCommit, email)
    99  }
   100  
   101  func (ctx *fuchsia) ReleaseTag(commit string) (string, error) {
   102  	return ctx.repo.ReleaseTag(commit)
   103  }
   104  
   105  func (ctx *fuchsia) Contains(commit string) (bool, error) {
   106  	return ctx.repo.Contains(commit)
   107  }
   108  
   109  func (ctx *fuchsia) LatestCommits(afterCommit string, afterDate time.Time) ([]CommitShort, error) {
   110  	return ctx.repo.LatestCommits(afterCommit, afterDate)
   111  }
   112  
   113  func (ctx *fuchsia) Object(name, commit string) ([]byte, error) {
   114  	return ctx.repo.Object(name, commit)
   115  }
   116  
   117  func (ctx *fuchsia) MergeBases(firstCommit, secondCommit string) ([]*Commit, error) {
   118  	return ctx.repo.MergeBases(firstCommit, secondCommit)
   119  }
   120  
   121  func (ctx *fuchsia) CommitExists(commit string) (bool, error) {
   122  	return ctx.repo.CommitExists(commit)
   123  }
   124  
   125  func (ctx *fuchsia) PushCommit(repo, commit string) error {
   126  	// Fuchsia repo doesn't accept unauthenticated pushes.
   127  	return fmt.Errorf("not implemented for fuchsia: PushCommit")
   128  }