From e20bd2d429e345debc021365a0df0deac7357e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Sj=C3=B6berg?= Date: Thu, 23 Jul 2026 15:25:25 +0200 Subject: [PATCH] Add file system access profile to execute response Currently bb-portal uses the latest file system access profile saved to the FSAC. This profile may differ from the profile produced by the action being viewed, for example when viewing old action results. With this change, action result contains its corresponding access profile. --- pkg/builder/prefetching_build_executor.go | 11 ++++++++-- .../prefetching_build_executor_test.go | 22 +++++++++++++------ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/pkg/builder/prefetching_build_executor.go b/pkg/builder/prefetching_build_executor.go index f93378f6..fa741051 100644 --- a/pkg/builder/prefetching_build_executor.go +++ b/pkg/builder/prefetching_build_executor.go @@ -152,11 +152,13 @@ func (be *prefetchingBuildExecutor) Execute(ctx context.Context, filePool pool.F return nil }) - if err := group.Wait(); err == nil { + err = group.Wait() + newProfile := be.computeProfile(bloomFilterMonitor) + if err == nil { // Action completed successfully. Store an updated // profile in the File System Access Cache if it is // different from the one fetched previously. - if newProfile := be.computeProfile(bloomFilterMonitor); !proto.Equal(existingProfile, newProfile) { + if !proto.Equal(existingProfile, newProfile) { if err := be.fileSystemAccessCache.Put(ctx, reducedActionDigest, buffer.NewProtoBufferFromProto(newProfile, buffer.UserProvided)); err != nil { attachErrorToExecuteResponse(response, util.StatusWrap(err, "Failed to store file system access profile")) } @@ -165,6 +167,11 @@ func (be *prefetchingBuildExecutor) Execute(ctx context.Context, filePool pool.F response.Status = status.Convert(err).Proto() } + if newProfilePb, err := anypb.New(newProfile); err == nil { + response.Result.ExecutionMetadata.AuxiliaryMetadata = append(response.Result.ExecutionMetadata.AuxiliaryMetadata, newProfilePb) + } else { + attachErrorToExecuteResponse(response, util.StatusWrap(err, "Failed to marshal file system access profile")) + } if resourceUsage, err := anypb.New(bloomFilterMonitor.GetInputRootResourceUsage()); err == nil { response.Result.ExecutionMetadata.AuxiliaryMetadata = append(response.Result.ExecutionMetadata.AuxiliaryMetadata, resourceUsage) } else { diff --git a/pkg/builder/prefetching_build_executor_test.go b/pkg/builder/prefetching_build_executor_test.go index d6ed0c88..debfdc32 100644 --- a/pkg/builder/prefetching_build_executor_test.go +++ b/pkg/builder/prefetching_build_executor_test.go @@ -49,6 +49,10 @@ func TestPrefetchingBuildExecutor(t *testing.T) { digestFunction := digest.MustNewFunction("hello", remoteexecution.DigestFunction_MD5) executionStateUpdates := make(chan<- *remoteworker.CurrentState_Executing) + defaultFileSystemAccessProfile, err := anypb.New(&fsac.FileSystemAccessProfile{ + BloomFilter: []byte{0x80}, + BloomFilterHashFunctions: 1, + }) defaultInputRootResourceUsage, err := anypb.New(&resourceusage.InputRootResourceUsage{ DirectoriesResolved: 1, DirectoriesRead: 0, @@ -207,7 +211,7 @@ func TestPrefetchingBuildExecutor(t *testing.T) { &remoteexecution.ExecuteResponse{ Result: &remoteexecution.ActionResult{ ExecutionMetadata: &remoteexecution.ExecutedActionMetadata{ - AuxiliaryMetadata: []*anypb.Any{defaultInputRootResourceUsage}, + AuxiliaryMetadata: []*anypb.Any{defaultFileSystemAccessProfile, defaultInputRootResourceUsage}, }, }, Status: status.New(codes.Internal, "Failed to fetch file system access profile: Storage offline").Proto(), @@ -256,7 +260,7 @@ func TestPrefetchingBuildExecutor(t *testing.T) { &remoteexecution.ExecuteResponse{ Result: &remoteexecution.ActionResult{ ExecutionMetadata: &remoteexecution.ExecutedActionMetadata{ - AuxiliaryMetadata: []*anypb.Any{defaultInputRootResourceUsage}, + AuxiliaryMetadata: []*anypb.Any{defaultFileSystemAccessProfile, defaultInputRootResourceUsage}, }, }, Status: status.New(codes.Internal, "Failed to prefetch directory \".\": Storage offline").Proto(), @@ -317,7 +321,7 @@ func TestPrefetchingBuildExecutor(t *testing.T) { &remoteexecution.ExecuteResponse{ Result: &remoteexecution.ActionResult{ ExecutionMetadata: &remoteexecution.ExecutedActionMetadata{ - AuxiliaryMetadata: []*anypb.Any{defaultInputRootResourceUsage}, + AuxiliaryMetadata: []*anypb.Any{defaultFileSystemAccessProfile, defaultInputRootResourceUsage}, }, }, Status: status.New(codes.Internal, "Failed to prefetch file \"hello.txt\": Storage offline").Proto(), @@ -366,7 +370,7 @@ func TestPrefetchingBuildExecutor(t *testing.T) { &remoteexecution.ExecuteResponse{ Result: &remoteexecution.ActionResult{ ExecutionMetadata: &remoteexecution.ExecutedActionMetadata{ - AuxiliaryMetadata: []*anypb.Any{defaultInputRootResourceUsage}, + AuxiliaryMetadata: []*anypb.Any{defaultFileSystemAccessProfile, defaultInputRootResourceUsage}, }, }, Status: status.New(codes.Internal, "Failed to store file system access profile: Storage offline").Proto(), @@ -408,7 +412,7 @@ func TestPrefetchingBuildExecutor(t *testing.T) { &remoteexecution.ExecuteResponse{ Result: &remoteexecution.ActionResult{ ExecutionMetadata: &remoteexecution.ExecutedActionMetadata{ - AuxiliaryMetadata: []*anypb.Any{defaultInputRootResourceUsage}, + AuxiliaryMetadata: []*anypb.Any{defaultFileSystemAccessProfile, defaultInputRootResourceUsage}, }, }, }, @@ -456,7 +460,11 @@ func TestPrefetchingBuildExecutor(t *testing.T) { }, profile) return nil }) - + fileSystemAccessProfile, err := anypb.New(&fsac.FileSystemAccessProfile{ + BloomFilter: []byte{0x0b, 0x2a}, + BloomFilterHashFunctions: 9, + }) + require.NoError(t, err) inputRootResourceUsage, err := anypb.New(&resourceusage.InputRootResourceUsage{ DirectoriesResolved: 1, DirectoriesRead: 1, @@ -468,7 +476,7 @@ func TestPrefetchingBuildExecutor(t *testing.T) { &remoteexecution.ExecuteResponse{ Result: &remoteexecution.ActionResult{ ExecutionMetadata: &remoteexecution.ExecutedActionMetadata{ - AuxiliaryMetadata: []*anypb.Any{inputRootResourceUsage}, + AuxiliaryMetadata: []*anypb.Any{fileSystemAccessProfile, inputRootResourceUsage}, }, }, },