From 5f2e250ba3ede16f0208c30a4624f5f46fbcb201 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Sat, 24 Feb 2024 00:57:23 +0000 Subject: [PATCH] Add some validation at the rpm level These fields are required to build an rpm. When the fields are not there rpmbuild gives an error about the fields, but those field names are different so its confusing to the user. This checks those fields early so we can give a better error message. Signed-off-by: Brian Goff --- frontend/mariner2/handle_rpm.go | 4 ++++ frontend/rpm/handle_buildroot.go | 3 +++ frontend/rpm/handle_rpm.go | 26 ++++++++++++++++++++++++++ frontend/rpm/handle_spec.go | 3 +++ 4 files changed, 36 insertions(+) diff --git a/frontend/mariner2/handle_rpm.go b/frontend/mariner2/handle_rpm.go index d5dc79ee5..434be0af3 100644 --- a/frontend/mariner2/handle_rpm.go +++ b/frontend/mariner2/handle_rpm.go @@ -33,6 +33,10 @@ func tdnfCacheMountWithPrefix(prefix string) llb.RunOption { } func handleRPM(ctx context.Context, client gwclient.Client, spec *dalec.Spec) (gwclient.Reference, *image.Image, error) { + if err := rpm.ValidateSpec(spec); err != nil { + return nil, nil, fmt.Errorf("rpm: invalid spec: %w", err) + } + pg := dalec.ProgressGroup("Building mariner2 rpm: " + spec.Name) sOpt, err := frontend.SourceOptFromClient(ctx, client) if err != nil { diff --git a/frontend/rpm/handle_buildroot.go b/frontend/rpm/handle_buildroot.go index 24af9a01c..b9f181587 100644 --- a/frontend/rpm/handle_buildroot.go +++ b/frontend/rpm/handle_buildroot.go @@ -42,6 +42,9 @@ func BuildrootHandler(target string) frontend.BuildFunc { // SpecToBuildrootLLB converts a dalec.Spec to an rpm buildroot func SpecToBuildrootLLB(spec *dalec.Spec, target string, sOpt dalec.SourceOpts, opts ...llb.ConstraintsOpt) (llb.State, error) { + if err := ValidateSpec(spec); err != nil { + return llb.Scratch(), fmt.Errorf("invalid spec: %w", err) + } opts = append(opts, dalec.ProgressGroup("Create RPM buildroot")) sources, err := Dalec2SourcesLLB(spec, sOpt, opts...) if err != nil { diff --git a/frontend/rpm/handle_rpm.go b/frontend/rpm/handle_rpm.go index 4a6e8a4af..c85f21e72 100644 --- a/frontend/rpm/handle_rpm.go +++ b/frontend/rpm/handle_rpm.go @@ -1,6 +1,9 @@ package rpm import ( + "errors" + "fmt" + "github.com/Azure/dalec" "github.com/moby/buildkit/client/llb" ) @@ -35,3 +38,26 @@ func Build(topDir, workerImg llb.State, specPath string, opts ...llb.Constraints ). AddMount("/build/out", llb.Scratch()) } + +var errMissingRequiredField = errors.New("missing required field") + +// ValidateSpec makes sure all the necessary fields are present in the spec to make rpmbuild work +// This validation is specific to rpmbuild. +func ValidateSpec(spec *dalec.Spec) (out error) { + if spec.Name == "" { + out = errors.Join(out, fmt.Errorf("%w: name", errMissingRequiredField)) + } + if spec.Version == "" { + out = errors.Join(out, fmt.Errorf("%w: version", errMissingRequiredField)) + } + if spec.Revision == "" { + out = errors.Join(out, fmt.Errorf("%w: revision", errMissingRequiredField)) + } + if spec.Description == "" { + out = errors.Join(out, fmt.Errorf("%w: description", errMissingRequiredField)) + } + if spec.Website == "" { + out = errors.Join(out, fmt.Errorf("%w: website", errMissingRequiredField)) + } + return out +} diff --git a/frontend/rpm/handle_spec.go b/frontend/rpm/handle_spec.go index 78d4d6731..c5749d2a4 100644 --- a/frontend/rpm/handle_spec.go +++ b/frontend/rpm/handle_spec.go @@ -39,6 +39,9 @@ func SpecHandler(target string) frontend.BuildFunc { } func Dalec2SpecLLB(spec *dalec.Spec, in llb.State, target, dir string, opts ...llb.ConstraintsOpt) (llb.State, error) { + if err := ValidateSpec(spec); err != nil { + return llb.Scratch(), fmt.Errorf("invalid spec: %w", err) + } opts = append(opts, dalec.ProgressGroup("Generate RPM spec")) buf := bytes.NewBuffer(nil) info, _ := debug.ReadBuildInfo()