Merge pull request #30 from infosiftr/scratch-platform
Set DOCKER_DEFAULT_PLATFORM when building "FROM scratch" images
This commit is contained in:
commit
3ebdb4c18f
|
|
@ -1,5 +1,7 @@
|
||||||
package architecture
|
package architecture
|
||||||
|
|
||||||
|
import "path"
|
||||||
|
|
||||||
// https://github.com/opencontainers/image-spec/blob/v1.0.1/image-index.md#image-index-property-descriptions
|
// https://github.com/opencontainers/image-spec/blob/v1.0.1/image-index.md#image-index-property-descriptions
|
||||||
// see "platform" (under "manifests")
|
// see "platform" (under "manifests")
|
||||||
type OCIPlatform struct {
|
type OCIPlatform struct {
|
||||||
|
|
@ -25,3 +27,12 @@ var SupportedArches = map[string]OCIPlatform{
|
||||||
|
|
||||||
"windows-amd64": {OS: "windows", Architecture: "amd64"},
|
"windows-amd64": {OS: "windows", Architecture: "amd64"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://pkg.go.dev/github.com/containerd/containerd/platforms
|
||||||
|
func (p OCIPlatform) String() string {
|
||||||
|
return path.Join(
|
||||||
|
p.OS,
|
||||||
|
p.Architecture,
|
||||||
|
p.Variant,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,9 @@ func cmdBuild(c *cli.Context) error {
|
||||||
return cli.NewMultiError(fmt.Errorf(`failed fetching/scraping FROM for %q (tags %q)`, r.RepoName, entry.TagsString()), err)
|
return cli.NewMultiError(fmt.Errorf(`failed fetching/scraping FROM for %q (tags %q)`, r.RepoName, entry.TagsString()), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fromScratch := false
|
||||||
for _, from := range froms {
|
for _, from := range froms {
|
||||||
|
fromScratch = fromScratch || from == "scratch"
|
||||||
if from != "scratch" && pull != "never" {
|
if from != "scratch" && pull != "never" {
|
||||||
doPull := false
|
doPull := false
|
||||||
switch pull {
|
switch pull {
|
||||||
|
|
@ -93,7 +95,14 @@ func cmdBuild(c *cli.Context) error {
|
||||||
|
|
||||||
// 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)
|
// 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)
|
||||||
|
|
||||||
err = dockerBuild(cacheTag, entry.ArchFile(arch), archive)
|
var extraEnv []string = nil
|
||||||
|
if fromScratch {
|
||||||
|
// https://github.com/docker/cli/blob/v20.10.7/cli/command/image/build.go#L163
|
||||||
|
extraEnv = []string{"DOCKER_DEFAULT_PLATFORM=" + ociArch.String()}
|
||||||
|
// 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+
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dockerBuild(cacheTag, entry.ArchFile(arch), archive, extraEnv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewMultiError(fmt.Errorf(`failed building %q (tags %q)`, r.RepoName, entry.TagsString()), err)
|
return cli.NewMultiError(fmt.Errorf(`failed building %q (tags %q)`, r.RepoName, entry.TagsString()), err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -237,10 +237,16 @@ func (r Repo) dockerBuildUniqueBits(entry *manifest.Manifest2822Entry) ([]string
|
||||||
return uniqueBits, nil
|
return uniqueBits, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func dockerBuild(tag string, file string, context io.Reader) error {
|
func dockerBuild(tag string, file string, context io.Reader, extraEnv []string) error {
|
||||||
args := []string{"build", "-t", tag, "-f", file, "--rm", "--force-rm"}
|
args := []string{"build", "--tag", tag, "--file", file, "--rm", "--force-rm"}
|
||||||
args = append(args, "-")
|
args = append(args, "-")
|
||||||
cmd := exec.Command("docker", args...)
|
cmd := exec.Command("docker", args...)
|
||||||
|
if extraEnv != nil {
|
||||||
|
cmd.Env = append(os.Environ(), extraEnv...)
|
||||||
|
if debugFlag {
|
||||||
|
fmt.Printf("$ export %q\n", extraEnv)
|
||||||
|
}
|
||||||
|
}
|
||||||
cmd.Stdin = context
|
cmd.Stdin = context
|
||||||
if debugFlag {
|
if debugFlag {
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
|
|
||||||
|
"github.com/docker-library/bashbrew/architecture"
|
||||||
"github.com/docker-library/bashbrew/manifest"
|
"github.com/docker-library/bashbrew/manifest"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -22,6 +23,7 @@ var (
|
||||||
defaultCache string
|
defaultCache string
|
||||||
|
|
||||||
arch string
|
arch string
|
||||||
|
ociArch architecture.OCIPlatform
|
||||||
namespace string
|
namespace string
|
||||||
constraints []string
|
constraints []string
|
||||||
exclusiveConstraints bool
|
exclusiveConstraints bool
|
||||||
|
|
@ -166,6 +168,11 @@ func main() {
|
||||||
constraints = c.GlobalStringSlice("constraint")
|
constraints = c.GlobalStringSlice("constraint")
|
||||||
exclusiveConstraints = c.GlobalBool("exclusive-constraints")
|
exclusiveConstraints = c.GlobalBool("exclusive-constraints")
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
if ociArch, ok = architecture.SupportedArches[arch]; !ok {
|
||||||
|
return fmt.Errorf("invalid architecture: %q", arch)
|
||||||
|
}
|
||||||
|
|
||||||
archNamespaces = map[string]string{}
|
archNamespaces = map[string]string{}
|
||||||
for _, archMapping := range c.GlobalStringSlice("arch-namespace") {
|
for _, archMapping := range c.GlobalStringSlice("arch-namespace") {
|
||||||
splitArchMapping := strings.SplitN(archMapping, "=", 2)
|
splitArchMapping := strings.SplitN(archMapping, "=", 2)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue