Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ on:
- '.github/workflows/worker-images.yml'
- '.github/workflows/dependabot.yml'
- '.github/workflows/release.yml'
- '.github/workflows/deploy-docs.yml'
- '.github/workflows/codeql.yml'

push:
branches:
Expand Down Expand Up @@ -287,9 +289,7 @@ jobs:
docker buildx bake test
- name: Build go-md2man example in docs
run: |
version=$(cat docs/examples/go-md2man.yml | yq .version)
docker build -t go-md2man:$version -f docs/examples/go-md2man.yml --target=mariner2/rpm --output=_output .
docker build -t go-md2man:$version -f docs/examples/go-md2man.yml --target=mariner2 .
docker buildx bake examples
- name: dump logs
if: failure()
id: dump-logs
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ name: "CodeQL"

on:
push:
branches: ["main"]
branches: ["main", "release/**"]
paths-ignore:
- '.github/copilot-instructions.md'
pull_request:
# The branches below must be a subset of the branches above
branches: ["main"]
branches: ["main", "release/**"]
paths-ignore:
- '.github/copilot-instructions.md'
schedule:
Expand Down
8 changes: 7 additions & 1 deletion frontend/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func GetBuildArg(client gwclient.Client, k string) (string, bool) {
}

func SourceOptFromUIClient(ctx context.Context, c gwclient.Client, dc *dockerui.Client, platform *ocispecs.Platform) dalec.SourceOpts {
return dalec.SourceOpts{
sOpt := dalec.SourceOpts{
TargetPlatform: platform,
Resolver: c,
Forward: ForwarderFromClient(ctx, c),
Expand All @@ -129,6 +129,12 @@ func SourceOptFromUIClient(ctx context.Context, c gwclient.Client, dc *dockerui.
},
GitCredHelperOpt: withCredHelper(c),
}

sOpt.SourceFilter = sync.OnceValues(func() (dalec.SourceFilterConfig, error) {
return loadSourceFilterConfig(ctx, c, sOpt.GetContext)
})

return sOpt
}

func SourceOptFromClient(ctx context.Context, c gwclient.Client, platform *ocispecs.Platform) (dalec.SourceOpts, error) {
Expand Down
70 changes: 57 additions & 13 deletions frontend/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,43 @@ func marshalDockerfile(ctx context.Context, dt []byte, opts ...llb.ConstraintsOp
}

func getSigningConfigFromContext(ctx context.Context, client gwclient.Client, cfgPath string, configCtxName string, sOpt dalec.SourceOpts, opts ...llb.ConstraintsOpt) (*dalec.PackageSigner, error) {
dt, err := readConfigFromContext(ctx, client, cfgPath, configCtxName, sOpt, opts...)
if err != nil {
return nil, err
}

var pc dalec.PackageConfig
if err := yaml.Unmarshal(dt, &pc); err != nil {
return nil, err
}

return pc.Signer, nil
}

func getSourceFilterConfigFromContext(ctx context.Context, client gwclient.Client, cfgPath string, configCtxName string, getContext func(string, ...llb.LocalOption) (*llb.State, error), opts ...llb.ConstraintsOpt) (dalec.SourceFilterConfig, error) {
dt, err := readConfigFromContext(ctx, client, cfgPath, configCtxName, dalec.SourceOpts{
GetContext: getContext,
}, opts...)
if err != nil {
return dalec.SourceFilterConfig{}, err
}

return decodeSourceFilterConfig(ctx, dt)
}

func decodeSourceFilterConfig(ctx context.Context, dt []byte) (dalec.SourceFilterConfig, error) {
var cfg dalec.SourceFilterConfig
if err := yaml.UnmarshalContext(ctx, dt, &cfg, yaml.Strict()); err != nil {
return dalec.SourceFilterConfig{}, err
}
return cfg, nil
}

func readConfigFromContext(ctx context.Context, client gwclient.Client, cfgPath string, configCtxName string, sOpt dalec.SourceOpts, opts ...llb.ConstraintsOpt) ([]byte, error) {
src := dalec.Source{Path: cfgPath, Context: &dalec.SourceContext{Name: configCtxName}}
signConfigState := src.ToState("", sOpt, opts...)
configState := src.ToState("", dalec.SourceOpts{GetContext: sOpt.GetContext}, opts...)

scDef, err := signConfigState.Marshal(ctx)
scDef, err := configState.Marshal(ctx)
if err != nil {
return nil, err
}
Expand All @@ -163,19 +196,9 @@ func getSigningConfigFromContext(ctx context.Context, client gwclient.Client, cf
return nil, err
}

dt, err := ref.ReadFile(ctx, gwclient.ReadRequest{
return ref.ReadFile(ctx, gwclient.ReadRequest{
Filename: cfgPath,
})
if err != nil {
return nil, err
}

var pc dalec.PackageConfig
if err := yaml.Unmarshal(dt, &pc); err != nil {
return nil, err
}

return pc.Signer, nil
}

func MaybeSign(ctx context.Context, client gwclient.Client, st llb.State, spec *dalec.Spec, targetKey string, sOpt dalec.SourceOpts, opts ...llb.ConstraintsOpt) (llb.State, error) {
Expand Down Expand Up @@ -243,6 +266,27 @@ func getSignConfigCtxName(client gwclient.Client) string {
return client.BuildOpts().Opts["build-arg:"+buildArgDalecSigningConfigContextName]
}

func getSourceFilterConfigPath(client gwclient.Client) string {
return client.BuildOpts().Opts["build-arg:"+dalec.BuildArgDalecSourceFilterConfigPath]
}

func getSourceFilterContextNameWithDefault(client gwclient.Client) string {
configCtxName := dalec.DefaultSourceOptionsContextName
if cn := client.BuildOpts().Opts["build-arg:"+dalec.BuildArgDalecSourceFilterContextName]; cn != "" {
configCtxName = cn
}
return configCtxName
}

func loadSourceFilterConfig(ctx context.Context, client gwclient.Client, getContext func(string, ...llb.LocalOption) (*llb.State, error)) (dalec.SourceFilterConfig, error) {
cfgPath := getSourceFilterConfigPath(client)
if cfgPath == "" {
return dalec.SourceFilterConfig{}, nil
}

return getSourceFilterConfigFromContext(ctx, client, cfgPath, getSourceFilterContextNameWithDefault(client), getContext)
}

func forwardToSigner(ctx context.Context, client gwclient.Client, cfg *dalec.PackageSigner, s llb.State, opts ...llb.ConstraintsOpt) (llb.State, error) {
const (
// See https://github.com/moby/buildkit/blob/d8d946b85c52095d34a52ce210960832f4e06775/frontend/dockerui/context.go#L29
Expand Down
1 change: 1 addition & 0 deletions generator_cargohome.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,6 @@ func (s *Spec) CargohomeDeps(sOpt SourceOpts, worker llb.State, opts ...llb.Cons
})
}

deps = deps.With(sourceFilter(sOpt, opts...))
return &deps, nil
}
1 change: 1 addition & 0 deletions generator_gomod.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,5 +242,6 @@ func (s *Spec) GomodDeps(sOpt SourceOpts, worker llb.State, opts ...llb.Constrai
})
}

deps = deps.With(sourceFilter(sOpt, opts...))
return &deps, nil
}
2 changes: 1 addition & 1 deletion generator_nodemodules.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (s *Spec) NodeModDeps(sOpt SourceOpts, worker llb.State, opts ...llb.Constr
}
merged = merged.With(withNodeMod(gen, worker, key, opts...))
}
result[key] = merged
result[key] = merged.With(sourceFilterAtPath(sOpt, key, opts...))
}
return result, nil
}
3 changes: 2 additions & 1 deletion generator_pip.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ func (s *Spec) PipDeps(sOpt SourceOpts, worker llb.State, opts ...llb.Constraint
}

// Merge all cache states into a single state
merged := MergeAtPath(llb.Scratch(), cacheStates, "/")
merged := MergeAtPath(llb.Scratch(), cacheStates, "/", opts...)
merged = merged.With(sourceFilter(sOpt, opts...))
return &merged, nil
}
4 changes: 4 additions & 0 deletions load.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ func knownArg(key string) bool {
return true
case "DALEC_SKIP_TESTS":
return true
case "DALEC_SOURCE_FILTER_CONFIG_PATH":
return true
case "DALEC_SOURCE_FILTER_CONFIG_CONTEXT_NAME":
return true
case KeyDalecTarget:
return true
}
Expand Down
15 changes: 11 additions & 4 deletions packaging/linux/rpm/buildroot.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import (
)

func ToSpecLLB(spec *dalec.Spec, in llb.State, targetKey, dir string, opts ...llb.ConstraintsOpt) (llb.State, error) {
return RPMSpecWithSourceFilter(spec, in, targetKey, dir, dalec.SourceFilterConfig{}, opts...)
}

func RPMSpecWithSourceFilter(spec *dalec.Spec, in llb.State, targetKey, dir string, filter dalec.SourceFilterConfig, opts ...llb.ConstraintsOpt) (llb.State, error) {
if err := ValidateSpec(spec); err != nil {
return llb.Scratch(), fmt.Errorf("invalid spec: %w", err)
}
Expand All @@ -20,7 +24,7 @@ func ToSpecLLB(spec *dalec.Spec, in llb.State, targetKey, dir string, opts ...ll
buf.WriteString("# Automatically generated by " + info.Main.Path + "\n")
buf.WriteString("\n")

if err := WriteSpec(spec, targetKey, buf); err != nil {
if err := WriteSpecWithSourceFilter(spec, targetKey, filter, buf); err != nil {
return llb.Scratch(), err
}

Expand All @@ -39,11 +43,14 @@ func SpecToBuildrootLLB(worker llb.State, spec *dalec.Spec, sOpt dalec.SourceOpt
return llb.Scratch(), fmt.Errorf("invalid spec: %w", err)
}
opts = append(opts, dalec.ProgressGroup("Create RPM buildroot"))

sources, err := ToSourcesLLB(worker, spec, sOpt, opts...)
if err != nil {
return llb.Scratch(), err
return llb.Scratch(), fmt.Errorf("error generating sources: %w", err)
}

return ToSpecLLB(spec, dalec.MergeAtPath(llb.Scratch(), sources, "SOURCES"), targetKey, "", opts...)
filter, err := sOpt.GetSourceFilter()
if err != nil {
return llb.Scratch(), err
}
return RPMSpecWithSourceFilter(spec, dalec.MergeAtPath(llb.Scratch(), sources, "SOURCES", opts...), targetKey, "", filter, opts...)
}
52 changes: 50 additions & 2 deletions packaging/linux/rpm/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ var tmplFuncs = map[string]any{

type specWrapper struct {
*dalec.Spec
Target string
Target string
SourceFilter dalec.SourceFilterConfig
}

func (w *specWrapper) Changelog() (fmt.Stringer, error) {
Expand Down Expand Up @@ -313,21 +314,46 @@ func (w *specWrapper) Sources() (fmt.Stringer, error) {
if scanner.Err() != nil {
return nil, scanner.Err()
}
if !w.SourceFilter.IsEmpty() && isDir {
if err := docSourceFilter(b, "Exclusions", w.SourceFilter.GlobalExcludes); err != nil {
return nil, err
}
}
fmt.Fprintf(b, "Source%d: %s\n", idx, ref)
}

sourceIdx := len(keys)

if w.Spec.HasGomods() {
if !w.SourceFilter.IsEmpty() {
if err := docSourceFilter(b, "Exclusions", w.SourceFilter.GlobalExcludes); err != nil {
return nil, err
}
}
fmt.Fprintf(b, "Source%d: %s.tar.gz\n", sourceIdx, gomodsName)
sourceIdx += 1
}

if w.Spec.HasCargohomes() {
if !w.SourceFilter.IsEmpty() {
if err := docSourceFilter(b, "Exclusions", w.SourceFilter.GlobalExcludes); err != nil {
return nil, err
}
}
fmt.Fprintf(b, "Source%d: %s.tar.gz\n", sourceIdx, cargohomeName)
sourceIdx += 1
}

if w.Spec.HasPips() {
if !w.SourceFilter.IsEmpty() {
if err := docSourceFilter(b, "Exclusions", w.SourceFilter.GlobalExcludes); err != nil {
return nil, err
}
}
fmt.Fprintf(b, "Source%d: %s.tar.gz\n", sourceIdx, pipDepsName)
sourceIdx += 1
}

if len(w.Spec.Build.Steps) > 0 {
fmt.Fprintf(b, "Source%d: %s\n", sourceIdx, buildScriptName)
}
Expand All @@ -338,6 +364,24 @@ func (w *specWrapper) Sources() (fmt.Stringer, error) {
return b, nil
}

func docSourceFilter(w io.Writer, name string, values []string) error {
if _, err := fmt.Fprintf(w, "# %s:\n", name); err != nil {
return err
}
for _, value := range values {
scanner := bufio.NewScanner(strings.NewReader(value))
for scanner.Scan() {
if _, err := fmt.Fprintf(w, "# \t%s\n", scanner.Text()); err != nil {
return err
}
}
if err := scanner.Err(); err != nil {
return err
}
}
return nil
}

func (w *specWrapper) Release() string {
if w.Spec.Revision == "" {
return "1"
Expand Down Expand Up @@ -911,7 +955,11 @@ func (w *specWrapper) DisableAutoReq() string {

// WriteSpec generates an rpm spec from the provided [dalec.Spec] and distro target and writes it to the passed in writer
func WriteSpec(spec *dalec.Spec, target string, w io.Writer) error {
s := &specWrapper{spec, target}
return WriteSpecWithSourceFilter(spec, target, dalec.SourceFilterConfig{}, w)
}

func WriteSpecWithSourceFilter(spec *dalec.Spec, target string, filter dalec.SourceFilterConfig, w io.Writer) error {
s := &specWrapper{Spec: spec, Target: target, SourceFilter: filter}

err := specTmpl.Execute(w, s)
if err != nil {
Expand Down
Loading
Loading