-
Notifications
You must be signed in to change notification settings - Fork 605
add rego integration to source policies #3539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
814f646
e915162
65dcf8f
fb5d8e6
1c6e562
f593cb0
8f7b555
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,8 +4,11 @@ import ( | |
| "bytes" | ||
| "context" | ||
| "io" | ||
| "io/fs" | ||
| "log" | ||
| "maps" | ||
| "os" | ||
| "path" | ||
| "path/filepath" | ||
| "slices" | ||
| "strconv" | ||
|
|
@@ -21,6 +24,7 @@ import ( | |
| "github.com/distribution/reference" | ||
| "github.com/docker/buildx/builder" | ||
| "github.com/docker/buildx/driver" | ||
| "github.com/docker/buildx/policy" | ||
| "github.com/docker/buildx/util/buildflags" | ||
| "github.com/docker/buildx/util/confutil" | ||
| "github.com/docker/buildx/util/dockerutil" | ||
|
|
@@ -38,6 +42,7 @@ import ( | |
| "github.com/moby/buildkit/session/sshforward/sshprovider" | ||
| "github.com/moby/buildkit/session/upload/uploadprovider" | ||
| "github.com/moby/buildkit/solver/pb" | ||
| "github.com/moby/buildkit/sourcepolicy/policysession" | ||
| "github.com/moby/buildkit/util/apicaps" | ||
| "github.com/moby/buildkit/util/entitlements" | ||
| "github.com/moby/buildkit/util/gitutil" | ||
|
|
@@ -322,6 +327,28 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt *O | |
| } | ||
| defers = append(defers, releaseLoad) | ||
|
|
||
| if opt.Inputs.policy != nil { | ||
| env := policy.Env{} | ||
| for k, v := range opt.BuildArgs { | ||
| if env.Args == nil { | ||
| env.Args = map[string]*string{} | ||
| } | ||
| env.Args[k] = &v | ||
| } | ||
| env.Filename = path.Base(opt.Inputs.DockerfilePath) | ||
| env.Target = opt.Target | ||
| env.Labels = opt.Labels | ||
| p := policy.NewPolicy(policy.Opt{ | ||
| Files: opt.Inputs.policy.Files, | ||
| Env: env, | ||
| Log: func(msg string) { | ||
| log.Printf("[policy] %s", msg) | ||
| }, | ||
| FS: opt.Inputs.policy.FS, | ||
| }) | ||
| so.SourcePolicyProvider = policysession.NewPolicyProvider(p.CheckPolicy) | ||
| } | ||
|
|
||
| // add node identifier to shared key if one was specified | ||
| if so.SharedKey != "" { | ||
| so.SharedKey += ":" + cfg.TryNodeIdentifier() | ||
|
|
@@ -413,6 +440,7 @@ func loadInputs(ctx context.Context, d *driver.DriverHandle, inp *Inputs, pw pro | |
| var ( | ||
| err error | ||
| dockerfileReader io.ReadCloser | ||
| contextDir string | ||
| dockerfileDir string | ||
| dockerfileName = inp.DockerfilePath | ||
| dockerfileSrcName = inp.DockerfilePath | ||
|
|
@@ -454,12 +482,14 @@ func loadInputs(ctx context.Context, d *driver.DriverHandle, inp *Inputs, pw pro | |
| if err := setLocalMount("context", inp.ContextPath, target); err != nil { | ||
| return nil, err | ||
| } | ||
| contextDir = inp.ContextPath | ||
| } | ||
| } | ||
| case osutil.IsLocalDir(inp.ContextPath): | ||
| if err := setLocalMount("context", inp.ContextPath, target); err != nil { | ||
| return nil, err | ||
| } | ||
| contextDir = inp.ContextPath | ||
| sharedKey := inp.ContextPath | ||
| if p, err := filepath.Abs(sharedKey); err == nil { | ||
| sharedKey = filepath.Base(p) | ||
|
|
@@ -535,6 +565,39 @@ func loadInputs(ctx context.Context, d *driver.DriverHandle, inp *Inputs, pw pro | |
| return nil, err | ||
| } | ||
| dockerfileName = handleLowercaseDockerfile(dockerfileDir, dockerfileName) | ||
|
|
||
| if fi, err := os.Lstat(filepath.Join(dockerfileDir, dockerfileName+".rego")); err == nil { | ||
| if fi.Mode().IsRegular() { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason to reject symlink?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just wanted to make sure there is no breakout here. Normally this shouldn't matter as Dockerfile path symlinks are already resolved and default policy is relative to that resolved path. But I'm ok with symlinks only for policy as well, as long as breakout cases are protected. |
||
| dt, err := os.ReadFile(filepath.Join(dockerfileDir, dockerfileName+".rego")) | ||
| if err != nil { | ||
| return nil, errors.Wrapf(err, "failed to read policy file %s.rego", dockerfileName) | ||
| } | ||
| inp.policy = &policyOpt{ | ||
| Files: []policy.File{ | ||
| { | ||
| Filename: dockerfileName + ".rego", | ||
| Data: dt, | ||
| }, | ||
| }, | ||
| FS: func() (fs.StatFS, func() error, error) { | ||
| if contextDir == "" { | ||
| return nil, nil, errors.Errorf("unimplemented, cannot use policy file without a local build context") | ||
| } | ||
| root, err := os.OpenRoot(contextDir) | ||
| if err != nil { | ||
| return nil, nil, errors.Wrapf(err, "failed to open root for policy file %s.rego", dockerfileName) | ||
| } | ||
| baseFS := root.FS() | ||
| statFS, ok := baseFS.(fs.StatFS) | ||
| if !ok { | ||
| root.Close() | ||
| return nil, nil, errors.Errorf("invalid root FS type %T", baseFS) | ||
| } | ||
| return statFS, root.Close, nil | ||
| }, | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| target.FrontendAttrs["filename"] = dockerfileName | ||
|
|
@@ -653,7 +716,7 @@ func setLocalMount(name, dir string, so *client.SolveOpt) error { | |
| if so.LocalMounts == nil { | ||
| so.LocalMounts = map[string]fsutil.FS{} | ||
| } | ||
| so.LocalMounts[name] = &fs{FS: lm, dir: dir} | ||
| so.LocalMounts[name] = &fsMount{FS: lm, dir: dir} | ||
| return nil | ||
| } | ||
|
|
||
|
|
@@ -765,12 +828,12 @@ func handleLowercaseDockerfile(dir, p string) string { | |
| return p | ||
| } | ||
|
|
||
| type fs struct { | ||
| type fsMount struct { | ||
| fsutil.FS | ||
| dir string | ||
| } | ||
|
|
||
| var _ fsutil.FS = &fs{} | ||
| var _ fsutil.FS = &fsMount{} | ||
|
|
||
| func CreateSSH(ssh []*buildflags.SSH) (session.Attachable, error) { | ||
| configs := make([]sshprovider.AgentConfig, 0, len(ssh)) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: err should be returned if
err != nil && !errors.Is(err, os.ErrNotExist)e.g., EACCES