Skip to content

Commit 25463ff

Browse files
tonistiigijsternberg
authored andcommitted
policy: fix metadata resolve via sessionpolicy for git and attestations
When support for these fields were added, tests were only written for static policies, missing the conversions for session variants. Signed-off-by: Tonis Tiigi <[email protected]> (cherry picked from commit 169afbf)
1 parent be1f38e commit 25463ff

3 files changed

Lines changed: 156 additions & 47 deletions

File tree

client/policy_test.go

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,8 @@ func testSourcePolicyParallelSession(t *testing.T, sb integration.Sandbox) {
299299

300300
func testSourcePolicySignedCommit(t *testing.T, sb integration.Sandbox) {
301301
requiresLinux(t)
302-
c, err := New(sb.Context(), sb.Address())
302+
ctx := sb.Context()
303+
c, err := New(ctx, sb.Address())
303304
require.NoError(t, err)
304305
defer c.Close()
305306

@@ -532,4 +533,101 @@ func testSourcePolicySignedCommit(t *testing.T, sb integration.Sandbox) {
532533
require.ErrorContains(t, err, tt.expectedErr, "test case %q failed", tt.name)
533534
})
534535
}
536+
537+
// session policy based test cases
538+
539+
type tcase struct {
540+
name string
541+
state func() llb.State
542+
callbacks []policysession.PolicyCallback
543+
expectedError string
544+
}
545+
546+
tcases := []tcase{
547+
{
548+
name: "gitchecksum",
549+
state: func() llb.State { return llb.Git(server.URL+"/.git", "", llb.GitRef("v2.0")) },
550+
callbacks: []policysession.PolicyCallback{
551+
func(ctx context.Context, req *policysession.CheckPolicyRequest) (*policysession.DecisionResponse, *pb.ResolveSourceMetaRequest, error) {
552+
require.Equal(t, gitURL+"#v2.0", req.Source.Source.Identifier)
553+
require.Nil(t, req.Source.Git)
554+
return nil, &pb.ResolveSourceMetaRequest{
555+
Source: req.Source.Source,
556+
Platform: req.Platform,
557+
}, nil
558+
},
559+
func(ctx context.Context, req *policysession.CheckPolicyRequest) (*policysession.DecisionResponse, *pb.ResolveSourceMetaRequest, error) {
560+
require.Equal(t, gitURL+"#v2.0", req.Source.Source.Identifier)
561+
require.NotNil(t, req.Source.Git)
562+
require.Len(t, req.Source.Git.Checksum, 40)
563+
require.Len(t, req.Source.Git.CommitChecksum, 40)
564+
require.NotEqual(t, req.Source.Git.Checksum, req.Source.Git.CommitChecksum)
565+
require.Nil(t, req.Source.Git.CommitObject)
566+
return &policysession.DecisionResponse{
567+
Action: sourcepolicypb.PolicyAction_ALLOW,
568+
}, nil, nil
569+
},
570+
},
571+
},
572+
{
573+
name: "gitobjects",
574+
state: func() llb.State { return llb.Git(server.URL+"/.git", "", llb.GitRef("v2.0")) },
575+
callbacks: []policysession.PolicyCallback{
576+
func(ctx context.Context, req *policysession.CheckPolicyRequest) (*policysession.DecisionResponse, *pb.ResolveSourceMetaRequest, error) {
577+
require.Equal(t, gitURL+"#v2.0", req.Source.Source.Identifier)
578+
require.Nil(t, req.Source.Git)
579+
return nil, &pb.ResolveSourceMetaRequest{
580+
Source: req.Source.Source,
581+
Platform: req.Platform,
582+
Git: &pb.ResolveSourceGitRequest{
583+
ReturnObject: true,
584+
},
585+
}, nil
586+
},
587+
func(ctx context.Context, req *policysession.CheckPolicyRequest) (*policysession.DecisionResponse, *pb.ResolveSourceMetaRequest, error) {
588+
require.Equal(t, gitURL+"#v2.0", req.Source.Source.Identifier)
589+
require.NotNil(t, req.Source.Git)
590+
require.Len(t, req.Source.Git.Checksum, 40)
591+
require.Len(t, req.Source.Git.CommitChecksum, 40)
592+
require.NotEqual(t, req.Source.Git.Checksum, req.Source.Git.CommitChecksum)
593+
require.NotNil(t, req.Source.Git.CommitObject)
594+
require.Greater(t, len(req.Source.Git.CommitObject), 50)
595+
return &policysession.DecisionResponse{
596+
Action: sourcepolicypb.PolicyAction_ALLOW,
597+
}, nil, nil
598+
},
599+
},
600+
},
601+
}
602+
603+
for _, tc := range tcases {
604+
t.Run(tc.name, func(t *testing.T) {
605+
st := tc.state()
606+
def, err := st.Marshal(ctx)
607+
require.NoError(t, err)
608+
609+
callCounter := 0
610+
611+
p := policysession.NewPolicyProvider(func(ctx context.Context, req *policysession.CheckPolicyRequest) (*policysession.DecisionResponse, *pb.ResolveSourceMetaRequest, error) {
612+
if callCounter >= len(tc.callbacks) {
613+
return nil, nil, errors.Errorf("too many calls to policy callback %d", callCounter)
614+
}
615+
cb := tc.callbacks[callCounter]
616+
callCounter++
617+
return cb(ctx, req)
618+
})
619+
620+
_, err = c.Solve(ctx, def, SolveOpt{
621+
SourcePolicyProvider: p,
622+
}, nil)
623+
if tc.expectedError != "" {
624+
require.Error(t, err)
625+
require.Contains(t, err.Error(), tc.expectedError)
626+
return
627+
}
628+
require.NoError(t, err)
629+
630+
require.Equal(t, len(tc.callbacks), callCounter, "not all policy callbacks were called")
631+
})
632+
}
535633
}

frontend/gateway/gateway.go

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -653,43 +653,7 @@ func (lbf *llbBridgeForwarder) ResolveSourceMeta(ctx context.Context, req *pb.Re
653653
if err != nil {
654654
return nil, err
655655
}
656-
657-
r := &pb.ResolveSourceMetaResponse{
658-
Source: resp.Op,
659-
}
660-
661-
if resp.Image != nil {
662-
r.Image = &pb.ResolveSourceImageResponse{
663-
Digest: string(resp.Image.Digest),
664-
Config: resp.Image.Config,
665-
}
666-
if resp.Image.AttestationChain != nil {
667-
r.Image.AttestationChain = toPBAttestationChain(resp.Image.AttestationChain)
668-
}
669-
}
670-
if resp.Git != nil {
671-
r.Git = &pb.ResolveSourceGitResponse{
672-
Checksum: resp.Git.Checksum,
673-
Ref: resp.Git.Ref,
674-
CommitChecksum: resp.Git.CommitChecksum,
675-
CommitObject: resp.Git.CommitObject,
676-
TagObject: resp.Git.TagObject,
677-
}
678-
}
679-
if resp.HTTP != nil {
680-
var lastModified *timestamp.Timestamp
681-
if resp.HTTP.LastModified != nil {
682-
lastModified = &timestamp.Timestamp{
683-
Seconds: resp.HTTP.LastModified.Unix(),
684-
}
685-
}
686-
r.HTTP = &pb.ResolveSourceHTTPResponse{
687-
Checksum: resp.HTTP.Digest.String(),
688-
Filename: resp.HTTP.Filename,
689-
LastModified: lastModified,
690-
}
691-
}
692-
return r, nil
656+
return ToPBResolveSourceMetaResponse(resp), nil
693657
}
694658

695659
func (lbf *llbBridgeForwarder) ResolveImageConfig(ctx context.Context, req *pb.ResolveImageConfigRequest) (*pb.ResolveImageConfigResponse, error) {
@@ -1705,6 +1669,45 @@ func getCaps(label string) map[string]struct{} {
17051669
return out
17061670
}
17071671

1672+
func ToPBResolveSourceMetaResponse(in *sourceresolver.MetaResponse) *pb.ResolveSourceMetaResponse {
1673+
r := &pb.ResolveSourceMetaResponse{
1674+
Source: in.Op,
1675+
}
1676+
1677+
if in.Image != nil {
1678+
r.Image = &pb.ResolveSourceImageResponse{
1679+
Digest: string(in.Image.Digest),
1680+
Config: in.Image.Config,
1681+
}
1682+
if in.Image.AttestationChain != nil {
1683+
r.Image.AttestationChain = toPBAttestationChain(in.Image.AttestationChain)
1684+
}
1685+
}
1686+
if in.Git != nil {
1687+
r.Git = &pb.ResolveSourceGitResponse{
1688+
Checksum: in.Git.Checksum,
1689+
Ref: in.Git.Ref,
1690+
CommitChecksum: in.Git.CommitChecksum,
1691+
CommitObject: in.Git.CommitObject,
1692+
TagObject: in.Git.TagObject,
1693+
}
1694+
}
1695+
if in.HTTP != nil {
1696+
var lastModified *timestamp.Timestamp
1697+
if in.HTTP.LastModified != nil {
1698+
lastModified = &timestamp.Timestamp{
1699+
Seconds: in.HTTP.LastModified.Unix(),
1700+
}
1701+
}
1702+
r.HTTP = &pb.ResolveSourceHTTPResponse{
1703+
Checksum: in.HTTP.Digest.String(),
1704+
Filename: in.HTTP.Filename,
1705+
LastModified: lastModified,
1706+
}
1707+
}
1708+
return r
1709+
}
1710+
17081711
func toPBAttestationChain(ac *sourceresolver.AttestationChain) *pb.AttestationChain {
17091712
if ac == nil {
17101713
return nil

solver/llbsolver/policy.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"strings"
66

77
"github.com/moby/buildkit/client/llb/sourceresolver"
8+
"github.com/moby/buildkit/frontend/gateway"
89
gatewaypb "github.com/moby/buildkit/frontend/gateway/pb"
910
"github.com/moby/buildkit/solver/pb"
1011
"github.com/moby/buildkit/sourcepolicy"
@@ -88,19 +89,26 @@ func (p *policyEvaluator) Evaluate(ctx context.Context, op *pb.Op) (bool, error)
8889
Platform: toOCIPlatform(metareq.Platform),
8990
}
9091
}
92+
93+
if metareq.Image != nil {
94+
if op.ImageOpt == nil {
95+
op.ImageOpt = &sourceresolver.ResolveImageOpt{}
96+
}
97+
op.ImageOpt.NoConfig = metareq.Image.NoConfig
98+
op.ImageOpt.AttestationChain = metareq.Image.AttestationChain
99+
}
100+
101+
if metareq.Git != nil {
102+
op.GitOpt = &sourceresolver.ResolveGitOpt{
103+
ReturnObject: metareq.Git.ReturnObject,
104+
}
105+
}
106+
91107
resp, err := p.resolveSourceMetadata(ctx, metareq.Source, op, false)
92108
if err != nil {
93109
return false, errors.Wrap(err, "error resolving source metadata from policy request")
94110
}
95-
req.Source = &gatewaypb.ResolveSourceMetaResponse{
96-
Source: resp.Op,
97-
}
98-
if resp.Image != nil {
99-
req.Source.Image = &gatewaypb.ResolveSourceImageResponse{
100-
Digest: resp.Image.Digest.String(),
101-
Config: resp.Image.Config,
102-
}
103-
}
111+
req.Source = gateway.ToPBResolveSourceMetaResponse(resp)
104112
continue
105113
}
106114

0 commit comments

Comments
 (0)