mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-21 10:09:07 +00:00
Merge pull request #3804 from giggsoff/allow-docker-multiarch
Allow store to docker multiarch builds
This commit is contained in:
commit
4e7f87e1ea
@ -191,20 +191,6 @@ func (p Pkg) Build(bos ...BuildOpt) error {
|
||||
return errors.New("must provide linuxkit build cache directory")
|
||||
}
|
||||
|
||||
// if targeting docker, be sure local arch is a build target
|
||||
if bo.targetDocker {
|
||||
var found bool
|
||||
for _, platform := range bo.platforms {
|
||||
if platform.Architecture == arch {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return fmt.Errorf("must build for local platform 'linux/%s' when targeting docker", arch)
|
||||
}
|
||||
}
|
||||
|
||||
if p.git != nil && bo.push && bo.release == "" {
|
||||
r, err := p.git.commitTag("HEAD")
|
||||
if err != nil {
|
||||
@ -243,6 +229,24 @@ func (p Pkg) Build(bos ...BuildOpt) error {
|
||||
} else {
|
||||
fmt.Fprintf(writer, "%s not found\n", ref)
|
||||
}
|
||||
if bo.targetDocker {
|
||||
notFound := false
|
||||
for _, platform := range bo.platforms {
|
||||
archRef, err := reference.Parse(fmt.Sprintf("%s-%s", p.FullTag(), platform.Architecture))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(writer, "checking for %s in local cache, fallback to remote registry...\n", archRef)
|
||||
if _, err := c.ImagePull(&archRef, "", platform.Architecture, false); err == nil {
|
||||
fmt.Fprintf(writer, "%s found or pulled\n", archRef)
|
||||
skipBuild = true
|
||||
} else {
|
||||
fmt.Fprintf(writer, "%s not found\n", archRef)
|
||||
notFound = true
|
||||
}
|
||||
}
|
||||
skipBuild = skipBuild && !notFound
|
||||
}
|
||||
}
|
||||
|
||||
if !skipBuild {
|
||||
@ -327,14 +331,28 @@ func (p Pkg) Build(bos ...BuildOpt) error {
|
||||
}
|
||||
|
||||
// if requested docker, load the image up
|
||||
// we will store images with arch suffix, i.e. -amd64
|
||||
// if one of the arch equals with system, we will add tag without suffix
|
||||
if bo.targetDocker {
|
||||
cacheSource := c.NewSource(&ref, arch, desc)
|
||||
reader, err := cacheSource.V1TarReader()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get reader from cache: %v", err)
|
||||
}
|
||||
if err := d.load(reader); err != nil {
|
||||
return err
|
||||
for _, platform := range bo.platforms {
|
||||
archRef, err := reference.Parse(fmt.Sprintf("%s-%s", p.FullTag(), platform.Architecture))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cacheSource := c.NewSource(&archRef, platform.Architecture, desc)
|
||||
reader, err := cacheSource.V1TarReader()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get reader from cache: %v", err)
|
||||
}
|
||||
if err := d.load(reader); err != nil {
|
||||
return err
|
||||
}
|
||||
if platform.Architecture == arch {
|
||||
err = d.tag(fmt.Sprintf("%s-%s", p.FullTag(), platform.Architecture), p.FullTag())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,9 +393,18 @@ func (p Pkg) Build(bos ...BuildOpt) error {
|
||||
}
|
||||
|
||||
// tag in docker, if requested
|
||||
// will tag all images with arch suffix
|
||||
// if one of the arch equals with system will add tag without suffix
|
||||
if bo.targetDocker {
|
||||
if err := d.tag(p.FullTag(), fullRelTag); err != nil {
|
||||
return err
|
||||
for _, platform := range bo.platforms {
|
||||
if err := d.tag(fmt.Sprintf("%s-%s", p.FullTag(), platform.Architecture), fmt.Sprintf("%s-%s", fullRelTag, platform.Architecture)); err != nil {
|
||||
return err
|
||||
}
|
||||
if platform.Architecture == arch {
|
||||
if err := d.tag(fmt.Sprintf("%s-%s", p.FullTag(), platform.Architecture), fullRelTag); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@ -116,7 +115,7 @@ func (c *cacheMocker) ImageLoad(ref *reference.Spec, architecture string, r io.R
|
||||
}
|
||||
|
||||
func (c *cacheMocker) imageWriteStream(ref *reference.Spec, architecture string, r io.Reader) (lktspec.ImageSource, error) {
|
||||
image := ref.String()
|
||||
image := fmt.Sprintf("%s-%s", ref.String(), architecture)
|
||||
|
||||
// make some random data for a layer
|
||||
b, err := ioutil.ReadAll(r)
|
||||
@ -154,10 +153,14 @@ func (c *cacheMocker) imageWriteStream(ref *reference.Spec, architecture string,
|
||||
Annotations: map[string]string{
|
||||
imagespec.AnnotationRefName: image,
|
||||
},
|
||||
Platform: ®istry.Platform{
|
||||
OS: "linux",
|
||||
Architecture: architecture,
|
||||
},
|
||||
}
|
||||
c.appendImage(image, desc)
|
||||
|
||||
return c.NewSource(ref, "", &desc), nil
|
||||
return c.NewSource(ref, architecture, &desc), nil
|
||||
}
|
||||
|
||||
func (c *cacheMocker) IndexWrite(ref *reference.Spec, descriptors ...registry.Descriptor) (lktspec.ImageSource, error) {
|
||||
@ -273,7 +276,13 @@ func (c cacheMockerSource) TarReader() (io.ReadCloser, error) {
|
||||
return nil, errors.New("unsupported")
|
||||
}
|
||||
func (c cacheMockerSource) V1TarReader() (io.ReadCloser, error) {
|
||||
return nil, errors.New("unsupported")
|
||||
_, found := c.c.images[c.ref.String()]
|
||||
if !found {
|
||||
return nil, fmt.Errorf("no image found with ref: %s", c.ref.String())
|
||||
}
|
||||
b := make([]byte, 256)
|
||||
rand.Read(b)
|
||||
return io.NopCloser(bytes.NewReader(b)), nil
|
||||
}
|
||||
func (c cacheMockerSource) Descriptor() *registry.Descriptor {
|
||||
return c.descriptor
|
||||
@ -281,14 +290,8 @@ func (c cacheMockerSource) Descriptor() *registry.Descriptor {
|
||||
|
||||
func TestBuild(t *testing.T) {
|
||||
var (
|
||||
nonLocal string
|
||||
cacheDir = "somecachedir"
|
||||
)
|
||||
if runtime.GOARCH == "amd64" {
|
||||
nonLocal = "arm64"
|
||||
} else {
|
||||
nonLocal = "amd64"
|
||||
}
|
||||
tests := []struct {
|
||||
msg string
|
||||
p Pkg
|
||||
@ -302,7 +305,7 @@ func TestBuild(t *testing.T) {
|
||||
{"not at head", Pkg{org: "foo", image: "bar", hash: "abc", arches: []string{"amd64"}, commitHash: "foo"}, nil, []string{"amd64"}, &dockerMocker{supportContexts: false}, &cacheMocker{}, "Cannot build from commit hash != HEAD"},
|
||||
{"no build cache", Pkg{org: "foo", image: "bar", hash: "abc", arches: []string{"amd64"}, commitHash: "HEAD"}, nil, []string{"amd64"}, &dockerMocker{supportContexts: false}, &cacheMocker{}, "must provide linuxkit build cache"},
|
||||
{"unsupported contexts", Pkg{org: "foo", image: "bar", hash: "abc", arches: []string{"amd64"}, commitHash: "HEAD"}, []BuildOpt{WithBuildCacheDir(cacheDir)}, []string{"amd64"}, &dockerMocker{supportContexts: false}, &cacheMocker{}, "contexts not supported, check docker version"},
|
||||
{"load docker without local platform", Pkg{org: "foo", image: "bar", hash: "abc", arches: []string{"amd64", "arm64"}, commitHash: "HEAD"}, []BuildOpt{WithBuildCacheDir(cacheDir), WithBuildTargetDockerCache()}, []string{nonLocal}, &dockerMocker{supportContexts: false}, &cacheMocker{}, "must build for local platform"},
|
||||
{"load docker without local platform", Pkg{org: "foo", image: "bar", hash: "abc", arches: []string{"amd64", "arm64"}, commitHash: "HEAD"}, []BuildOpt{WithBuildCacheDir(cacheDir), WithBuildTargetDockerCache()}, []string{"amd64", "arm64"}, &dockerMocker{supportContexts: true, enableBuild: true, images: map[string][]byte{}, enableTag: true}, &cacheMocker{enableImagePull: false, enableImageLoad: true, enableIndexWrite: true}, ""},
|
||||
{"amd64", Pkg{org: "foo", image: "bar", hash: "abc", arches: []string{"amd64", "arm64"}, commitHash: "HEAD"}, []BuildOpt{WithBuildCacheDir(cacheDir)}, []string{"amd64"}, &dockerMocker{supportContexts: true, enableBuild: true}, &cacheMocker{enableImagePull: false, enableImageLoad: true, enableIndexWrite: true}, ""},
|
||||
{"arm64", Pkg{org: "foo", image: "bar", hash: "abc", arches: []string{"amd64", "arm64"}, commitHash: "HEAD"}, []BuildOpt{WithBuildCacheDir(cacheDir)}, []string{"arm64"}, &dockerMocker{supportContexts: true, enableBuild: true}, &cacheMocker{enableImagePull: false, enableImageLoad: true, enableIndexWrite: true}, ""},
|
||||
{"amd64 and arm64", Pkg{org: "foo", image: "bar", hash: "abc", arches: []string{"amd64", "arm64"}, commitHash: "HEAD"}, []BuildOpt{WithBuildCacheDir(cacheDir)}, []string{"amd64", "arm64"}, &dockerMocker{supportContexts: true, enableBuild: true}, &cacheMocker{enableImagePull: false, enableImageLoad: true, enableIndexWrite: true}, ""},
|
||||
|
@ -288,7 +288,7 @@ func (dr *dockerRunnerImpl) builderEnsureContainer(ctx context.Context, name, im
|
||||
}
|
||||
// create the builder
|
||||
args := []string{"container", "run", "-d", "--name", name, "--privileged", image, "--allow-insecure-entitlement", "network.host", "--addr", fmt.Sprintf("unix://%s", buildkitSocketPath), "--debug"}
|
||||
msg := fmt.Sprintf("creating builder container '%s' in context '%s", name, dockerContext)
|
||||
msg := fmt.Sprintf("creating builder container '%s' in context '%s'", name, dockerContext)
|
||||
fmt.Println(msg)
|
||||
if err := dr.command(nil, ioutil.Discard, ioutil.Discard, args...); err != nil {
|
||||
return nil, err
|
||||
|
Loading…
Reference in New Issue
Block a user