travis, build: add support for multi-arch docker images

pull/23069/head
Péter Szilágyi 3 years ago
parent ef946a6c87
commit e9f99d1c91
No known key found for this signature in database
GPG Key ID: E9AE538CEDF8293D
  1. 37
      .travis.yml
  2. 70
      build/ci.go

@ -24,7 +24,38 @@ jobs:
script: script:
- go run build/ci.go lint - go run build/ci.go lint
# This builder does the Docker Hub build and upload for amd64 # These builders create the Docker sub-images for multi-arch push
- stage: prebuild
if: type = push
os: linux
arch: amd64
dist: bionic
go: 1.16.x
env:
- docker
services:
- docker
git:
submodules: false # avoid cloning ethereum/tests
script:
- go run build/ci.go docker -image -upload karalabe/geth-docker-test
- stage: prebuild
if: type = push
os: linux
arch: arm64
dist: bionic
go: 1.16.x
env:
- docker
services:
- docker
git:
submodules: false # avoid cloning ethereum/tests
script:
- go run build/ci.go docker -image -upload karalabe/geth-docker-test
# This builder does the Docker Hub multi-arch image
- stage: build - stage: build
if: type = push if: type = push
os: linux os: linux
@ -36,8 +67,10 @@ jobs:
- docker - docker
git: git:
submodules: false # avoid cloning ethereum/tests submodules: false # avoid cloning ethereum/tests
before_install:
- export DOCKER_CLI_EXPERIMENTAL=enabled
script: script:
- go run build/ci.go docker -upload karalabe/geth-docker-test - go run build/ci.go docker -manifest amd64,arm64 -upload karalabe/geth-docker-test
# This builder does the Ubuntu PPA upload # This builder does the Ubuntu PPA upload
- stage: build - stage: build

@ -183,7 +183,7 @@ func main() {
case "archive": case "archive":
doArchive(os.Args[2:]) doArchive(os.Args[2:])
case "docker": case "docker":
doDockerImage(os.Args[2:]) doDocker(os.Args[2:])
case "debsrc": case "debsrc":
doDebianSource(os.Args[2:]) doDebianSource(os.Args[2:])
case "nsis": case "nsis":
@ -455,9 +455,11 @@ func maybeSkipArchive(env build.Environment) {
} }
// Builds the docker images and optionally uploads them to Docker Hub. // Builds the docker images and optionally uploads them to Docker Hub.
func doDockerImage(cmdline []string) { func doDocker(cmdline []string) {
var ( var (
upload = flag.String("upload", "", `Where to upload the docker image (usually "ethereum/client-go")`) image = flag.Bool("image", false, `Whether to build and push an arch specific docker image`)
manifest = flag.String("manifest", "", `Push a multi-arch docker image for the specified architectures (usually "amd64,arm64")`)
upload = flag.String("upload", "", `Where to upload the docker image (usually "ethereum/client-go")`)
) )
flag.CommandLine.Parse(cmdline) flag.CommandLine.Parse(cmdline)
@ -465,6 +467,15 @@ func doDockerImage(cmdline []string) {
env := build.Env() env := build.Env()
maybeSkipArchive(env) maybeSkipArchive(env)
// Retrieve the upload credentials and authenticate
user := getenvBase64("DOCKER_HUB_USERNAME")
pass := getenvBase64("DOCKER_HUB_PASSWORD")
if len(user) > 0 && len(pass) > 0 {
auther := exec.Command("docker", "login", "-u", string(user), "--password-stdin")
auther.Stdin = bytes.NewReader(pass)
build.MustRun(auther)
}
// Retrieve the version infos to build and push to the following paths: // Retrieve the version infos to build and push to the following paths:
// - ethereum/client-go:latest - Pushes to the master branch, Geth only // - ethereum/client-go:latest - Pushes to the master branch, Geth only
// - ethereum/client-go:stable - Version tag publish on GitHub, Geth only // - ethereum/client-go:stable - Version tag publish on GitHub, Geth only
@ -482,25 +493,46 @@ func doDockerImage(cmdline []string) {
case strings.HasPrefix(env.Tag, "v1."): case strings.HasPrefix(env.Tag, "v1."):
tags = []string{"stable", fmt.Sprintf("release-1.%d", params.VersionMinor), params.Version} tags = []string{"stable", fmt.Sprintf("release-1.%d", params.VersionMinor), params.Version}
} }
// Build the docker images via CLI (don't pull in the `moby` dep to call 3 commands) // If architecture specific image builds are requested, build and push them
build.MustRunCommand("docker", "build", "--tag", fmt.Sprintf("%s:TAG", *upload), ".") if *image {
build.MustRunCommand("docker", "build", "--tag", fmt.Sprintf("%s:alltools-TAG", *upload), "-f", "Dockerfile.alltools", ".") build.MustRunCommand("docker", "build", "--tag", fmt.Sprintf("%s:TAG", *upload), ".")
build.MustRunCommand("docker", "build", "--tag", fmt.Sprintf("%s:alltools-TAG", *upload), "-f", "Dockerfile.alltools", ".")
// Retrieve the upload credentials and authenticate // Tag and upload the images to Docker Hub
user := getenvBase64("DOCKER_HUB_USERNAME") for _, tag := range tags {
pass := getenvBase64("DOCKER_HUB_PASSWORD") gethImage := fmt.Sprintf("%s:%s-%s", *upload, tag, runtime.GOARCH)
toolImage := fmt.Sprintf("%s:alltools-%s-%s", *upload, tag, runtime.GOARCH)
if len(user) > 0 && len(pass) > 0 { build.MustRunCommand("docker", "image", "tag", fmt.Sprintf("%s:TAG", *upload), gethImage)
auther := exec.Command("docker", "login", "-u", string(user), "--password-stdin") build.MustRunCommand("docker", "image", "tag", fmt.Sprintf("%s:alltools-TAG", *upload), toolImage)
auther.Stdin = bytes.NewReader(pass) build.MustRunCommand("docker", "push", gethImage)
build.MustRun(auther) build.MustRunCommand("docker", "push", toolImage)
}
} }
// Tag and upload the images to Docker Hub // If multi-arch image manifest push is requested, assemble it
for _, tag := range tags { if len(*manifest) != 0 {
build.MustRunCommand("docker", "image", "tag", fmt.Sprintf("%s:TAG", *upload), fmt.Sprintf("%s:%s", *upload, tag)) // Assemble and push the Geth manifest image
build.MustRunCommand("docker", "image", "tag", fmt.Sprintf("%s:alltools-TAG", *upload), fmt.Sprintf("%s:alltools-%s", *upload, tag)) for _, tag := range tags {
build.MustRunCommand("docker", "push", fmt.Sprintf("%s:%s", *upload, tag)) gethImage := fmt.Sprintf("%s:%s", *upload, tag)
build.MustRunCommand("docker", "push", fmt.Sprintf("%s:alltools-%s", *upload, tag))
var gethSubImages []string
for _, arch := range strings.Split(*manifest, ",") {
gethSubImages = append(gethSubImages, gethImage+"-"+arch)
}
build.MustRunCommand("docker", append([]string{"manifest", "create", gethImage}, gethSubImages...)...)
build.MustRunCommand("docker", "manifest", "push", gethImage)
}
// Assemble and push the alltools manifest image
for _, tag := range tags {
toolImage := fmt.Sprintf("%s:alltools-%s", *upload, tag)
var toolSubImages []string
for _, arch := range strings.Split(*manifest, ",") {
toolSubImages = append(toolSubImages, toolImage+"-"+arch)
}
build.MustRunCommand("docker", append([]string{"manifest", "create", toolImage}, toolSubImages...)...)
build.MustRunCommand("docker", "manifest", "push", toolImage)
}
} }
} }

Loading…
Cancel
Save