diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2025-07-11 15:44:40 +0200 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2025-07-14 11:30:46 +0000 |
| commit | ec20f94ff6effe4c2aab4b4a4ecdfb33180e6e77 (patch) | |
| tree | 57058c12e7ab2ca53553afdbd75d632d98c9c9a6 /syz-cluster/pkg | |
| parent | 76718eb73e3d1e2a43363d80ab15366706b6491f (diff) | |
syz-cluster: upload and share build config and log
Diffstat (limited to 'syz-cluster/pkg')
| -rw-r--r-- | syz-cluster/pkg/api/api.go | 1 | ||||
| -rw-r--r-- | syz-cluster/pkg/api/urls.go | 8 | ||||
| -rw-r--r-- | syz-cluster/pkg/controller/testutil.go | 19 | ||||
| -rw-r--r-- | syz-cluster/pkg/db/entities.go | 2 | ||||
| -rw-r--r-- | syz-cluster/pkg/db/migrations/2_extend_build.down.sql | 2 | ||||
| -rw-r--r-- | syz-cluster/pkg/db/migrations/2_extend_build.up.sql | 7 | ||||
| -rw-r--r-- | syz-cluster/pkg/reporter/api_test.go | 4 | ||||
| -rw-r--r-- | syz-cluster/pkg/service/build.go | 32 | ||||
| -rw-r--r-- | syz-cluster/pkg/service/finding.go | 2 |
9 files changed, 68 insertions, 9 deletions
diff --git a/syz-cluster/pkg/api/api.go b/syz-cluster/pkg/api/api.go index 5fcd0e797..d48175199 100644 --- a/syz-cluster/pkg/api/api.go +++ b/syz-cluster/pkg/api/api.go @@ -57,6 +57,7 @@ type Build struct { CommitDate time.Time `json:"commit_date"` ConfigName string `json:"config_name"` SeriesID string `json:"series_id"` + Compiler string `json:"compiler"` BuildSuccess bool `json:"build_success"` } diff --git a/syz-cluster/pkg/api/urls.go b/syz-cluster/pkg/api/urls.go index 54f447b97..f8af9c27b 100644 --- a/syz-cluster/pkg/api/urls.go +++ b/syz-cluster/pkg/api/urls.go @@ -29,3 +29,11 @@ func (g *URLGenerator) FindingCRepro(findingID string) string { func (g *URLGenerator) Series(seriesID string) string { return fmt.Sprintf("%s/series/%s", g.baseURL, seriesID) } + +func (g *URLGenerator) BuildConfig(buildID string) string { + return fmt.Sprintf("%s/builds/%s/config", g.baseURL, buildID) +} + +func (g *URLGenerator) BuildLog(buildID string) string { + return fmt.Sprintf("%s/builds/%s/log", g.baseURL, buildID) +} diff --git a/syz-cluster/pkg/controller/testutil.go b/syz-cluster/pkg/controller/testutil.go index 0a72914c7..c1ab8b6f5 100644 --- a/syz-cluster/pkg/controller/testutil.go +++ b/syz-cluster/pkg/controller/testutil.go @@ -39,7 +39,9 @@ func UploadTestSeries(t *testing.T, ctx context.Context, func UploadTestBuild(t *testing.T, ctx context.Context, client *api.Client, build *api.Build) *api.UploadBuildResp { ret, err := client.UploadBuild(ctx, &api.UploadBuildReq{ - Build: *build, + Build: *build, + Log: []byte("build log"), + Config: []byte("build config"), }) assert.NoError(t, err) assert.NotEmpty(t, ret.ID) @@ -74,6 +76,7 @@ func DummyBuild() *api.Build { TreeName: "mainline", ConfigName: "config", CommitHash: "abcd", + Compiler: "compiler", } } @@ -92,8 +95,14 @@ func DummyFindings() []*api.NewFinding { return findings } +type SeriesWithFindingIDs struct { + EntityIDs + BaseBuildID string + PatchedBuildID string +} + func FakeSeriesWithFindings(t *testing.T, ctx context.Context, env *app.AppEnvironment, - client *api.Client, series *api.Series) EntityIDs { + client *api.Client, series *api.Series) SeriesWithFindingIDs { ids := UploadTestSeries(t, ctx, client, series) baseBuild := UploadTestBuild(t, ctx, client, DummyBuild()) patchedBuild := UploadTestBuild(t, ctx, client, DummyBuild()) @@ -113,7 +122,11 @@ func FakeSeriesWithFindings(t *testing.T, ctx context.Context, env *app.AppEnvir assert.NoError(t, err) } MarkSessionFinished(t, env, ids.SessionID) - return ids + return SeriesWithFindingIDs{ + EntityIDs: ids, + BaseBuildID: baseBuild.ID, + PatchedBuildID: patchedBuild.ID, + } } func MarkSessionFinished(t *testing.T, env *app.AppEnvironment, sessionID string) { diff --git a/syz-cluster/pkg/db/entities.go b/syz-cluster/pkg/db/entities.go index c914d7361..9959e81b2 100644 --- a/syz-cluster/pkg/db/entities.go +++ b/syz-cluster/pkg/db/entities.go @@ -45,7 +45,9 @@ type Build struct { Arch string `spanner:"Arch"` ConfigName string `spanner:"ConfigName"` ConfigURI string `spanner:"ConfigURI"` + LogURI string `spanner:"LogURI"` Status string `spanner:"Status"` + Compiler string `spanner:"Compiler"` } func (b *Build) SetSeriesID(val string) { diff --git a/syz-cluster/pkg/db/migrations/2_extend_build.down.sql b/syz-cluster/pkg/db/migrations/2_extend_build.down.sql new file mode 100644 index 000000000..e96c67e95 --- /dev/null +++ b/syz-cluster/pkg/db/migrations/2_extend_build.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE Builds DROP COLUMN Compiler; +ALTER TABLE Builds DROP COLUMN LogURI; diff --git a/syz-cluster/pkg/db/migrations/2_extend_build.up.sql b/syz-cluster/pkg/db/migrations/2_extend_build.up.sql new file mode 100644 index 000000000..542d7ae33 --- /dev/null +++ b/syz-cluster/pkg/db/migrations/2_extend_build.up.sql @@ -0,0 +1,7 @@ +-- One cannot just add a non null column in spanner. + +ALTER TABLE Builds ADD COLUMN Compiler STRING(512) DEFAULT(''); +ALTER TABLE Builds ALTER COLUMN Compiler STRING(512) NOT NULL; + +ALTER TABLE Builds ADD COLUMN LogURI STRING(512) DEFAULT(''); +ALTER TABLE Builds ALTER COLUMN LogURI STRING(512) NOT NULL; diff --git a/syz-cluster/pkg/reporter/api_test.go b/syz-cluster/pkg/reporter/api_test.go index 279055e5a..69ee0c604 100644 --- a/syz-cluster/pkg/reporter/api_test.go +++ b/syz-cluster/pkg/reporter/api_test.go @@ -43,6 +43,8 @@ func TestAPIReportFlow(t *testing.T) { finding.LinkCRepro = "" assert.NotEmpty(t, finding.LinkSyzRepro, "%q's LinkSyzRepro is empty", finding.Title) finding.LinkSyzRepro = "" + assert.NotEmpty(t, finding.Build.ConfigLink, "%q's ConfigLink is empty", finding.Title) + finding.Build.ConfigLink = "" } assert.Equal(t, &api.SessionReport{ @@ -69,6 +71,7 @@ func TestAPIReportFlow(t *testing.T) { Repo: "mainline", BaseCommit: "abcd", Arch: "amd64", + Compiler: "compiler", }, }, { @@ -78,6 +81,7 @@ func TestAPIReportFlow(t *testing.T) { Repo: "mainline", BaseCommit: "abcd", Arch: "amd64", + Compiler: "compiler", }, }, }, diff --git a/syz-cluster/pkg/service/build.go b/syz-cluster/pkg/service/build.go index 40d716472..b6dcdb620 100644 --- a/syz-cluster/pkg/service/build.go +++ b/syz-cluster/pkg/service/build.go @@ -4,30 +4,38 @@ package service import ( + "bytes" "context" + "fmt" "github.com/google/syzkaller/syz-cluster/pkg/api" "github.com/google/syzkaller/syz-cluster/pkg/app" + "github.com/google/syzkaller/syz-cluster/pkg/blob" "github.com/google/syzkaller/syz-cluster/pkg/db" + "github.com/google/uuid" ) type BuildService struct { - buildRepo *db.BuildRepository + buildRepo *db.BuildRepository + blobStorage blob.Storage } func NewBuildService(env *app.AppEnvironment) *BuildService { return &BuildService{ - buildRepo: db.NewBuildRepository(env.Spanner), + buildRepo: db.NewBuildRepository(env.Spanner), + blobStorage: env.BlobStorage, } } func (s *BuildService) Upload(ctx context.Context, req *api.UploadBuildReq) (*api.UploadBuildResp, error) { build := &db.Build{ + ID: uuid.NewString(), Arch: req.Arch, ConfigName: req.ConfigName, TreeName: req.TreeName, CommitHash: req.CommitHash, CommitDate: req.CommitDate, + Compiler: req.Compiler, } if req.SeriesID != "" { build.SetSeriesID(req.SeriesID) @@ -37,7 +45,20 @@ func (s *BuildService) Upload(ctx context.Context, req *api.UploadBuildReq) (*ap } else { build.Status = db.BuildFailed } - // TODO: upload config and log. + if len(req.Log) > 0 { + var err error + build.LogURI, err = s.blobStorage.Write(bytes.NewReader(req.Log), "Build", build.ID, "log") + if err != nil { + return nil, fmt.Errorf("failed to write log: %w", err) + } + } + if len(req.Config) > 0 { + var err error + build.ConfigURI, err = s.blobStorage.Write(bytes.NewReader(req.Config), "Build", build.ID, "config") + if err != nil { + return nil, fmt.Errorf("failed to write kernel config: %w", err) + } + } err := s.buildRepo.Insert(ctx, build) if err != nil { return nil, err @@ -72,11 +93,12 @@ func (s *BuildService) LastBuild(ctx context.Context, req *api.LastBuildReq) (*a return resp, nil } -func makeBuildInfo(build *db.Build) api.BuildInfo { +func makeBuildInfo(url *api.URLGenerator, build *db.Build) api.BuildInfo { return api.BuildInfo{ Repo: build.TreeName, // TODO: we actually want to use repo URI here. BaseCommit: build.CommitHash, Arch: build.Arch, - ConfigLink: "", + Compiler: build.Compiler, + ConfigLink: url.BuildConfig(build.ID), } } diff --git a/syz-cluster/pkg/service/finding.go b/syz-cluster/pkg/service/finding.go index 2f238cc7d..001860e1c 100644 --- a/syz-cluster/pkg/service/finding.go +++ b/syz-cluster/pkg/service/finding.go @@ -100,7 +100,7 @@ func (s *FindingService) List(ctx context.Context, sessionID string, limit int) } build := testPerName[item.TestName].PatchedBuild if build != nil { - finding.Build = makeBuildInfo(build) + finding.Build = makeBuildInfo(s.urls, build) } bytes, err := blob.ReadAllBytes(s.blobStorage, item.ReportURI) if err != nil { |
