Skip to content

Commit 2f39409

Browse files
committed
Use native platform to fetch sources, generate buildroot, etc
When building for a non-native platform (typically under qemu), use the native platform for most operations that do not need platform specific things, such as applying patches, tarring up sources, and fetching go module deps. Signed-off-by: Brian Goff <[email protected]>
1 parent a05e530 commit 2f39409

File tree

6 files changed

+62
-28
lines changed

6 files changed

+62
-28
lines changed

frontend/azlinux/handle_container.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func handleContainer(w worker) gwclient.BuildFunc {
2525

2626
pg := dalec.ProgressGroup("Building " + targetKey + " container: " + spec.Name)
2727

28-
rpmDir, err := specToRpmLLB(ctx, w, client, spec, sOpt, targetKey, pg, dalec.WithPlatform(platform))
28+
rpmDir, err := buildOutputRPM(ctx, w, client, spec, sOpt, targetKey, platform, pg)
2929
if err != nil {
3030
return nil, nil, fmt.Errorf("error creating rpm: %w", err)
3131
}

frontend/azlinux/handle_depsonly.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func handleDepsOnly(w worker) gwclient.BuildFunc {
3636
return nil, nil, err
3737
}
3838

39-
st, err := specToContainerLLB(w, spec, targetKey, rpmDir, files, sOpt, pg)
39+
st, err := specToContainerLLB(w, spec, targetKey, rpmDir, files, sOpt, pg, dalec.WithPlatform(platform))
4040
if err != nil {
4141
return nil, nil, err
4242
}

frontend/azlinux/handle_rpm.go

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/moby/buildkit/client/llb"
1212
gwclient "github.com/moby/buildkit/frontend/gateway/client"
1313
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
14+
"github.com/pkg/errors"
1415
)
1516

1617
func handleRPM(w worker) gwclient.BuildFunc {
@@ -26,7 +27,7 @@ func handleRPM(w worker) gwclient.BuildFunc {
2627
return nil, nil, err
2728
}
2829

29-
st, err := specToRpmLLB(ctx, w, client, spec, sOpt, targetKey, pg, dalec.WithPlatform(platform))
30+
st, err := buildOutputRPM(ctx, w, client, spec, sOpt, targetKey, platform, pg)
3031
if err != nil {
3132
return nil, nil, err
3233
}
@@ -53,7 +54,7 @@ func handleRPM(w worker) gwclient.BuildFunc {
5354
}
5455

5556
// Creates and installs an rpm meta-package that requires the passed in deps as runtime-dependencies
56-
func installBuildDepsPackage(target string, packageName string, w worker, deps map[string]dalec.PackageConstraints, installOpts ...installOpt) installFunc {
57+
func installBuildDepsPackage(target string, packageName string, w worker, sOpt dalec.SourceOpts, deps map[string]dalec.PackageConstraints, platform *ocispecs.Platform, installOpts ...installOpt) installFunc {
5758
// depsOnly is a simple dalec spec that only includes build dependencies and their constraints
5859
depsOnly := dalec.Spec{
5960
Name: fmt.Sprintf("%s-build-dependencies", packageName),
@@ -66,11 +67,11 @@ func installBuildDepsPackage(target string, packageName string, w worker, deps m
6667
},
6768
}
6869

69-
return func(ctx context.Context, client gwclient.Client, sOpt dalec.SourceOpts) (llb.RunOption, error) {
70+
return func(ctx context.Context, Opt dalec.SourceOpts) (llb.RunOption, error) {
7071
pg := dalec.ProgressGroup("Building container for build dependencies")
7172

7273
// create an RPM with just the build dependencies, using our same base worker
73-
rpmDir, err := specToRpmLLB(ctx, w, client, &depsOnly, sOpt, target, pg)
74+
rpmDir, err := createRPM(ctx, w, sOpt, &depsOnly, target, platform, pg)
7475
if err != nil {
7576
return nil, err
7677
}
@@ -91,20 +92,15 @@ func installBuildDepsPackage(target string, packageName string, w worker, deps m
9192
}
9293
}
9394

94-
func installBuildDeps(ctx context.Context, w worker, client gwclient.Client, spec *dalec.Spec, targetKey string, opts ...llb.ConstraintsOpt) (llb.StateOption, error) {
95+
func installBuildDeps(ctx context.Context, w worker, sOpt dalec.SourceOpts, spec *dalec.Spec, targetKey string, platform *ocispecs.Platform, opts ...llb.ConstraintsOpt) (llb.StateOption, error) {
9596
deps := spec.GetBuildDeps(targetKey)
9697
if len(deps) == 0 {
9798
return func(in llb.State) llb.State { return in }, nil
9899
}
99100

100-
sOpt, err := frontend.SourceOptFromClient(ctx, client)
101-
if err != nil {
102-
return nil, err
103-
}
104-
105101
opts = append(opts, dalec.ProgressGroup("Install build deps"))
106102

107-
installOpt, err := installBuildDepsPackage(targetKey, spec.Name, w, deps, installWithConstraints(opts))(ctx, client, sOpt)
103+
installOpt, err := installBuildDepsPackage(targetKey, spec.Name, w, sOpt, deps, platform, installWithConstraints(opts))(ctx, sOpt)
108104
if err != nil {
109105
return nil, err
110106
}
@@ -114,24 +110,58 @@ func installBuildDeps(ctx context.Context, w worker, client gwclient.Client, spe
114110
}, nil
115111
}
116112

117-
func specToRpmLLB(ctx context.Context, w worker, client gwclient.Client, spec *dalec.Spec, sOpt dalec.SourceOpts, targetKey string, opts ...llb.ConstraintsOpt) (llb.State, error) {
118-
base, err := w.Base(sOpt, opts...)
113+
func createBuildroot(ctx context.Context, w worker, sOpt dalec.SourceOpts, spec *dalec.Spec, targetKey string, opts ...llb.ConstraintsOpt) (llb.State, error) {
114+
opts = append(opts, dalec.ProgressGroup("Prepare rpm build root"))
115+
116+
// Always generate the build root usign the native platform
117+
// There is nothing it does that should require the requested target platform
118+
native, err := w.Base(sOpt, opts...)
119119
if err != nil {
120120
return llb.Scratch(), err
121121
}
122122

123-
installOpt, err := installBuildDeps(ctx, w, client, spec, targetKey, opts...)
123+
if spec.HasGomods() {
124+
// Since the spec has go mods in it, we need to make sure we have go
125+
// installed in the image.
126+
nativeInstallDeps, err := installBuildDeps(ctx, w, sOpt, spec, targetKey, nil, opts...)
127+
if err != nil {
128+
return llb.Scratch(), err
129+
}
130+
131+
native = native.With(nativeInstallDeps)
132+
}
133+
134+
return rpm.SpecToBuildrootLLB(native, spec, sOpt, targetKey, opts...)
135+
}
136+
137+
func createRPM(ctx context.Context, w worker, sOpt dalec.SourceOpts, spec *dalec.Spec, targetKey string, platform *ocispecs.Platform, opts ...llb.ConstraintsOpt) (llb.State, error) {
138+
br, err := createBuildroot(ctx, w, sOpt, spec, targetKey, opts...)
139+
if err != nil {
140+
return llb.Scratch(), errors.Wrap(err, "error creating rpm build root")
141+
}
142+
143+
specPath := filepath.Join("SPECS", spec.Name, spec.Name+".spec")
144+
145+
// Build the RPM with the target platform
146+
opts = append(opts, dalec.WithPlatform(platform))
147+
base, err := w.Base(sOpt, opts...)
124148
if err != nil {
125149
return llb.Scratch(), err
126150
}
127-
base = base.With(installOpt)
128151

129-
br, err := rpm.SpecToBuildrootLLB(base, spec, sOpt, targetKey, opts...)
152+
installDeps, err := installBuildDeps(ctx, w, sOpt, spec, targetKey, platform, opts...)
130153
if err != nil {
131154
return llb.Scratch(), err
132155
}
133-
specPath := filepath.Join("SPECS", spec.Name, spec.Name+".spec")
134-
st := rpm.Build(br, base, specPath, opts...)
135156

157+
base = base.With(installDeps)
158+
return rpm.Build(br, base, specPath, opts...), nil
159+
}
160+
161+
func buildOutputRPM(ctx context.Context, w worker, client gwclient.Client, spec *dalec.Spec, sOpt dalec.SourceOpts, targetKey string, platform *ocispecs.Platform, opts ...llb.ConstraintsOpt) (llb.State, error) {
162+
st, err := createRPM(ctx, w, sOpt, spec, targetKey, platform, opts...)
163+
if err != nil {
164+
return llb.Scratch(), err
165+
}
136166
return frontend.MaybeSign(ctx, client, st, spec, targetKey, sOpt)
137167
}

frontend/azlinux/handler.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const (
1818
tdnfCacheDir = "/var/cache/tdnf"
1919
)
2020

21-
type installFunc func(context.Context, gwclient.Client, dalec.SourceOpts) (llb.RunOption, error)
21+
type installFunc func(context.Context, dalec.SourceOpts) (llb.RunOption, error)
2222

2323
type worker interface {
2424
Base(sOpt dalec.SourceOpts, opts ...llb.ConstraintsOpt) (llb.State, error)
@@ -62,12 +62,12 @@ func handleDebug(w worker) gwclient.BuildFunc {
6262
if err != nil {
6363
return nil, err
6464
}
65-
return rpm.HandleDebug(getSpecWorker(ctx, w, client, sOpt))(ctx, client)
65+
return rpm.HandleDebug(getSpecWorker(ctx, w, sOpt))(ctx, client)
6666
}
6767
}
6868

69-
func getSpecWorker(ctx context.Context, w worker, client gwclient.Client, sOpt dalec.SourceOpts) rpm.WorkerFunc {
70-
return func(resolver llb.ImageMetaResolver, spec *dalec.Spec, targetKey string, opts ...llb.ConstraintsOpt) (llb.State, error) {
69+
func getSpecWorker(ctx context.Context, w worker, sOpt dalec.SourceOpts) rpm.WorkerFunc {
70+
return func(resolver llb.ImageMetaResolver, spec *dalec.Spec, targetKey string, platform *ocispecs.Platform, opts ...llb.ConstraintsOpt) (llb.State, error) {
7171
st, err := w.Base(sOpt, opts...)
7272
if err != nil {
7373
return llb.Scratch(), err
@@ -83,7 +83,7 @@ func getSpecWorker(ctx context.Context, w worker, client gwclient.Client, sOpt d
8383
return llb.Scratch(), errors.New("spec contains go modules but does not have golang in build deps")
8484
}
8585

86-
installOpt, err := installBuildDeps(ctx, w, client, spec, targetKey, opts...)
86+
installOpt, err := installBuildDeps(ctx, w, sOpt, spec, targetKey, platform, opts...)
8787
if err != nil {
8888
return llb.Scratch(), err
8989
}

frontend/rpm/handle_buildroot.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
1212
)
1313

14-
type WorkerFunc func(resolver llb.ImageMetaResolver, spec *dalec.Spec, targetKey string, opts ...llb.ConstraintsOpt) (llb.State, error)
14+
type WorkerFunc func(resolver llb.ImageMetaResolver, spec *dalec.Spec, targetKey string, platform *ocispecs.Platform, opts ...llb.ConstraintsOpt) (llb.State, error)
1515

1616
func HandleBuildroot(wf WorkerFunc) gwclient.BuildFunc {
1717
return func(ctx context.Context, client gwclient.Client) (*gwclient.Result, error) {
@@ -21,7 +21,9 @@ func HandleBuildroot(wf WorkerFunc) gwclient.BuildFunc {
2121
return nil, nil, err
2222
}
2323

24-
worker, err := wf(sOpt.Resolver, spec, targetKey)
24+
// Note, we are not passing platform down here because everything should
25+
// be able to work regardless of platform, so prefer the native platform.
26+
worker, err := wf(sOpt.Resolver, spec, targetKey, platform)
2527
if err != nil {
2628
return nil, nil, err
2729
}

frontend/rpm/handle_sources.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ func HandleSources(wf WorkerFunc) gwclient.BuildFunc {
2121
return nil, nil, err
2222
}
2323

24-
worker, err := wf(sOpt.Resolver, spec, targetKey)
24+
worker, err := wf(sOpt.Resolver, spec, targetKey, platform)
2525
if err != nil {
2626
return nil, nil, err
2727
}
2828

29+
// Note, we are not passing platform down here because everything should
30+
// be able to work regardless of platform, so prefer the native platform.
2931
sources, err := Dalec2SourcesLLB(worker, spec, sOpt)
3032
if err != nil {
3133
return nil, nil, err

0 commit comments

Comments
 (0)