Skip to content

Commit

Permalink
Render platform overrides in the UI
Browse files Browse the repository at this point in the history
  • Loading branch information
bduffany committed Dec 6, 2024
1 parent baac073 commit 8ef74ec
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 7 deletions.
12 changes: 8 additions & 4 deletions app/invocation/invocation.css
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,14 @@
font-size: 14px;
}

.action-section .platform-property-overridden * {
color: #757575;
}

.action-section .platform-property-note {
color: #757575;
}

.action-section .grpc-status-error {
color: #d32f2f;
}
Expand Down Expand Up @@ -1057,10 +1065,6 @@
font-weight: 600;
}

.prop-value {
color: #444;
}

.prop-value .detail {
color: #aaa;
}
Expand Down
54 changes: 51 additions & 3 deletions app/invocation/invocation_action_card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,19 @@ export default class InvocationActionCardComponent extends React.Component<Props
.catch((e) => console.error(e));
}

private getExecutionAuxiliaryMetadata(): execution_stats.ExecutionAuxiliaryMetadata | null | undefined {
const auxiliaryMetadata = this.state.actionResult?.executionMetadata?.auxiliaryMetadata;
if (!auxiliaryMetadata || auxiliaryMetadata.length == 0) {
return null;
}
for (const metadata of auxiliaryMetadata) {
if (metadata.typeUrl === execution_stats.ExecutionAuxiliaryMetadata.getTypeUrl()) {
return execution_stats.ExecutionAuxiliaryMetadata.decode(metadata.value);
}
}
return null;
}

// For firecracker actions, VM metadata is stored in the auxiliary metadata field
// of the execution metadata. Try to decode it into an object if it exists.
private getFirecrackerVMMetadata(): firecracker.VMMetadata | null | undefined {
Expand All @@ -572,7 +585,7 @@ export default class InvocationActionCardComponent extends React.Component<Props
return null;
}
for (const metadata of auxiliaryMetadata) {
if (metadata.typeUrl === "type.googleapis.com/firecracker.VMMetadata") {
if (metadata.typeUrl === firecracker.VMMetadata.getTypeUrl()) {
return firecracker.VMMetadata.decode(metadata.value);
}
}
Expand Down Expand Up @@ -875,11 +888,28 @@ export default class InvocationActionCardComponent extends React.Component<Props
);
}

private getPlatformOverrides(): Record<string, string> {
const overrides: Record<string, string> = {};
for (const prop of this.getExecutionAuxiliaryMetadata()?.platformOverrides?.properties ?? []) {
let value = prop.value ?? "";
// TODO: this redaction is also done on the server and can be removed
// after some time.
const nameLower = prop.name.toLowerCase();
if (nameLower.includes("username") || nameLower.includes("password") || nameLower.includes("env-overrides")) {
value = "<REDACTED>";
}
overrides[prop.name] = value;
}

return overrides;
}

render() {
const digest = parseActionDigest(this.props.search.get("actionDigest") ?? "");
if (!digest) return <></>;
const vmMetadata = this.getFirecrackerVMMetadata();
const executionId = this.getExecutionId();
const platformOverrides = this.getPlatformOverrides();

return (
<div className="invocation-action-card">
Expand Down Expand Up @@ -1004,17 +1034,35 @@ export default class InvocationActionCardComponent extends React.Component<Props
{this.state.command.platform?.properties.length ? (
<div className="action-list">
{this.state.command.platform?.properties.map((property) => (
<div>
<div
className={
platformOverrides.hasOwnProperty(property?.name ?? "")
? "platform-property-overridden"
: ""
}>
<span className="prop-name">{property.name}</span>
<span className="prop-value">={property.value}</span>
{platformOverrides.hasOwnProperty(property?.name ?? "") && <span> (overridden)</span>}
</div>
))}
{!this.state.command.platform?.properties.length && <div>(Default)</div>}
</div>
) : (
<div>None</div>
)}
</div>
{Object.keys(platformOverrides).length > 0 && (
<div className="action-section">
<div className="action-property-title">Platform overrides</div>
<div className="action-list">
{Object.entries(platformOverrides).map(([name, value]) => (
<div>
<span className="prop-name">{name}</span>
<span className="prop-value">={value}</span>
</div>
))}
</div>
</div>
)}
{!this.state.actionResult && this.renderExpectedOutputs(this.state.command)}
</div>
) : (
Expand Down
1 change: 1 addition & 0 deletions enterprise/server/remote_execution/execution_server/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ go_library(
"@org_golang_google_genproto//googleapis/longrunning",
"@org_golang_google_grpc//metadata",
"@org_golang_google_grpc//status",
"@org_golang_google_protobuf//types/known/anypb",
"@org_golang_google_protobuf//types/known/timestamppb",
"@org_golang_x_time//rate",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import (
"golang.org/x/time/rate"
"google.golang.org/genproto/googleapis/longrunning"
"google.golang.org/grpc/metadata"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/timestamppb"

espb "github.com/buildbuddy-io/buildbuddy/proto/execution_stats"
Expand Down Expand Up @@ -1094,6 +1095,7 @@ func (s *ExecutionServer) cacheExecuteResponse(ctx context.Context, taskID strin
}
arn := digest.NewResourceName(d, taskRN.GetInstanceName(), rspb.CacheType_AC, taskRN.GetDigestFunction())

redactCachedExecuteResponse(ctx, response)
b, err := proto.Marshal(response)
if err != nil {
return err
Expand Down Expand Up @@ -1208,6 +1210,39 @@ func (s *ExecutionServer) fetchActionAndCommand(ctx context.Context, actionResou
return action, cmd, nil
}

func redactCachedExecuteResponse(ctx context.Context, rsp *repb.ExecuteResponse) {
md := rsp.GetResult().GetExecutionMetadata()
for _, auxAny := range md.GetAuxiliaryMetadata() {
if auxAny.GetTypeUrl() == "type.googleapis.com/"+string((&espb.ExecutionAuxiliaryMetadata{}).ProtoReflect().Descriptor().FullName()) {
redactExecutionAuxiliaryMetadata(ctx, auxAny)
}
}
}

func redactExecutionAuxiliaryMetadata(ctx context.Context, auxAny *anypb.Any) {
md := &espb.ExecutionAuxiliaryMetadata{}
if err := proto.Unmarshal(auxAny.GetValue(), md); err != nil {
log.CtxErrorf(ctx, "Failed to unmarshal ExecutionAuxiliaryMetadata: %s", err)
return
}

// Redact platform overrides.
overrides := md.GetPlatformOverrides().GetProperties()
for _, p := range overrides {
name := strings.ToLower(p.GetName())
if strings.Contains(name, "password") || strings.Contains(name, "username") || strings.Contains(name, "env-overrides") {
p.Value = "<REDACTED>"
}
}

b, err := proto.Marshal(md)
if err != nil {
log.CtxErrorf(ctx, "Failed to marshal ExecutionAuxiliaryMetadata: %s", err)
return
}
auxAny.Value = b
}

func executionDuration(md *repb.ExecutedActionMetadata) (time.Duration, error) {
if err := md.GetWorkerStartTimestamp().CheckValid(); err != nil {
return 0, err
Expand Down

0 comments on commit 8ef74ec

Please sign in to comment.