Skip to content

Commit 3ebdb4c

Browse files
authored
Merge pull request #30 from infosiftr/scratch-platform
Set DOCKER_DEFAULT_PLATFORM when building "FROM scratch" images
2 parents cec2d64 + b9b4dac commit 3ebdb4c

File tree

4 files changed

+36
-3
lines changed

4 files changed

+36
-3
lines changed

architecture/oci-platform.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package architecture
22

3+
import "path"
4+
35
// https://github.com/opencontainers/image-spec/blob/v1.0.1/image-index.md#image-index-property-descriptions
46
// see "platform" (under "manifests")
57
type OCIPlatform struct {
@@ -25,3 +27,12 @@ var SupportedArches = map[string]OCIPlatform{
2527

2628
"windows-amd64": {OS: "windows", Architecture: "amd64"},
2729
}
30+
31+
// https://pkg.go.dev/github.com/containerd/containerd/platforms
32+
func (p OCIPlatform) String() string {
33+
return path.Join(
34+
p.OS,
35+
p.Architecture,
36+
p.Variant,
37+
)
38+
}

cmd/bashbrew/cmd-build.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ func cmdBuild(c *cli.Context) error {
4848
return cli.NewMultiError(fmt.Errorf(`failed fetching/scraping FROM for %q (tags %q)`, r.RepoName, entry.TagsString()), err)
4949
}
5050

51+
fromScratch := false
5152
for _, from := range froms {
53+
fromScratch = fromScratch || from == "scratch"
5254
if from != "scratch" && pull != "never" {
5355
doPull := false
5456
switch pull {
@@ -93,7 +95,14 @@ func cmdBuild(c *cli.Context) error {
9395

9496
// TODO use "meta.StageNames" to do "docker build --target" so we can tag intermediate stages too for cache (streaming "git archive" directly to "docker build" makes that a little hard to accomplish without re-streaming)
9597

96-
err = dockerBuild(cacheTag, entry.ArchFile(arch), archive)
98+
var extraEnv []string = nil
99+
if fromScratch {
100+
// https://github.com/docker/cli/blob/v20.10.7/cli/command/image/build.go#L163
101+
extraEnv = []string{"DOCKER_DEFAULT_PLATFORM=" + ociArch.String()}
102+
// ideally, we would set this via an explicit "--platform" flag on "docker build", but it's not supported without buildkit until 20.10+ and this is a trivial way to get Docker to do the right thing in both cases without explicitly trying to detect whether we're on 20.10+
103+
}
104+
105+
err = dockerBuild(cacheTag, entry.ArchFile(arch), archive, extraEnv)
97106
if err != nil {
98107
return cli.NewMultiError(fmt.Errorf(`failed building %q (tags %q)`, r.RepoName, entry.TagsString()), err)
99108
}

cmd/bashbrew/docker.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,16 @@ func (r Repo) dockerBuildUniqueBits(entry *manifest.Manifest2822Entry) ([]string
237237
return uniqueBits, nil
238238
}
239239

240-
func dockerBuild(tag string, file string, context io.Reader) error {
241-
args := []string{"build", "-t", tag, "-f", file, "--rm", "--force-rm"}
240+
func dockerBuild(tag string, file string, context io.Reader, extraEnv []string) error {
241+
args := []string{"build", "--tag", tag, "--file", file, "--rm", "--force-rm"}
242242
args = append(args, "-")
243243
cmd := exec.Command("docker", args...)
244+
if extraEnv != nil {
245+
cmd.Env = append(os.Environ(), extraEnv...)
246+
if debugFlag {
247+
fmt.Printf("$ export %q\n", extraEnv)
248+
}
249+
}
244250
cmd.Stdin = context
245251
if debugFlag {
246252
cmd.Stdout = os.Stdout

cmd/bashbrew/main.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/urfave/cli"
1010

11+
"github.com/docker-library/bashbrew/architecture"
1112
"github.com/docker-library/bashbrew/manifest"
1213
)
1314

@@ -22,6 +23,7 @@ var (
2223
defaultCache string
2324

2425
arch string
26+
ociArch architecture.OCIPlatform
2527
namespace string
2628
constraints []string
2729
exclusiveConstraints bool
@@ -166,6 +168,11 @@ func main() {
166168
constraints = c.GlobalStringSlice("constraint")
167169
exclusiveConstraints = c.GlobalBool("exclusive-constraints")
168170

171+
var ok bool
172+
if ociArch, ok = architecture.SupportedArches[arch]; !ok {
173+
return fmt.Errorf("invalid architecture: %q", arch)
174+
}
175+
169176
archNamespaces = map[string]string{}
170177
for _, archMapping := range c.GlobalStringSlice("arch-namespace") {
171178
splitArchMapping := strings.SplitN(archMapping, "=", 2)

0 commit comments

Comments
 (0)