@@ -50,7 +50,6 @@ import (
5050 "path"
5151 "path/filepath"
5252 "runtime"
53- "strconv"
5453 "strings"
5554 "time"
5655
@@ -159,8 +158,8 @@ func main() {
159158 doLint (os .Args [2 :])
160159 case "archive" :
161160 doArchive (os .Args [2 :])
162- case "docker " :
163- doDocker (os .Args [2 :])
161+ case "dockerx " :
162+ doDockerBuildx (os .Args [2 :])
164163 case "debsrc" :
165164 doDebianSource (os .Args [2 :])
166165 case "nsis" :
@@ -723,10 +722,9 @@ func maybeSkipArchive(env build.Environment) {
723722}
724723
725724// Builds the docker images and optionally uploads them to Docker Hub.
726- func doDocker (cmdline []string ) {
725+ func doDockerBuildx (cmdline []string ) {
727726 var (
728- image = flag .Bool ("image" , false , `Whether to build and push an arch specific docker image` )
729- manifest = flag .String ("manifest" , "" , `Push a multi-arch docker image for the specified architectures (usually "amd64,arm64")` )
727+ platform = flag .String ("platform" , "" , `Push a multi-arch docker image for the specified architectures (usually "linux/amd64,linux/arm64")` )
730728 upload = flag .String ("upload" , "" , `Where to upload the docker image (usually "ethereum/client-go")` )
731729 )
732730 flag .CommandLine .Parse (cmdline )
@@ -761,129 +759,26 @@ func doDocker(cmdline []string) {
761759 case strings .HasPrefix (env .Tag , "v1." ):
762760 tags = []string {"stable" , fmt .Sprintf ("release-1.%d" , params .VersionMinor ), "v" + params .Version }
763761 }
764- // If architecture specific image builds are requested, build and push them
765- if * image {
766- build .MustRunCommand ("docker" , "build" , "--build-arg" , "COMMIT=" + env .Commit , "--build-arg" , "VERSION=" + params .VersionWithMeta , "--build-arg" , "BUILDNUM=" + env .Buildnum , "--tag" , fmt .Sprintf ("%s:TAG" , * upload ), "." )
767- build .MustRunCommand ("docker" , "build" , "--build-arg" , "COMMIT=" + env .Commit , "--build-arg" , "VERSION=" + params .VersionWithMeta , "--build-arg" , "BUILDNUM=" + env .Buildnum , "--tag" , fmt .Sprintf ("%s:alltools-TAG" , * upload ), "-f" , "Dockerfile.alltools" , "." )
768-
769- // Tag and upload the images to Docker Hub
770- for _ , tag := range tags {
771- gethImage := fmt .Sprintf ("%s:%s-%s" , * upload , tag , runtime .GOARCH )
772- toolImage := fmt .Sprintf ("%s:alltools-%s-%s" , * upload , tag , runtime .GOARCH )
773-
774- // If the image already exists (non version tag), check the build
775- // number to prevent overwriting a newer commit if concurrent builds
776- // are running. This is still a tiny bit racey if two published are
777- // done at the same time, but that's extremely unlikely even on the
778- // master branch.
779- for _ , img := range []string {gethImage , toolImage } {
780- if exec .Command ("docker" , "pull" , img ).Run () != nil {
781- continue // Generally the only failure is a missing image, which is good
782- }
783- buildnum , err := exec .Command ("docker" , "inspect" , "--format" , "{{index .Config.Labels \" buildnum\" }}" , img ).CombinedOutput ()
784- if err != nil {
785- log .Fatalf ("Failed to inspect container: %v\n Output: %s" , err , string (buildnum ))
786- }
787- buildnum = bytes .TrimSpace (buildnum )
788-
789- if len (buildnum ) > 0 && len (env .Buildnum ) > 0 {
790- oldnum , err := strconv .Atoi (string (buildnum ))
791- if err != nil {
792- log .Fatalf ("Failed to parse old image build number: %v" , err )
793- }
794- newnum , err := strconv .Atoi (env .Buildnum )
795- if err != nil {
796- log .Fatalf ("Failed to parse current build number: %v" , err )
797- }
798- if oldnum > newnum {
799- log .Fatalf ("Current build number %d not newer than existing %d" , newnum , oldnum )
800- } else {
801- log .Printf ("Updating %s from build %d to %d" , img , oldnum , newnum )
802- }
803- }
804- }
805- build .MustRunCommand ("docker" , "image" , "tag" , fmt .Sprintf ("%s:TAG" , * upload ), gethImage )
806- build .MustRunCommand ("docker" , "image" , "tag" , fmt .Sprintf ("%s:alltools-TAG" , * upload ), toolImage )
807- build .MustRunCommand ("docker" , "push" , gethImage )
808- build .MustRunCommand ("docker" , "push" , toolImage )
809- }
810- }
811- // If multi-arch image manifest push is requested, assemble it
812- if len (* manifest ) != 0 {
813- // Since different architectures are pushed by different builders, wait
814- // until all required images are updated.
815- var mismatch bool
816- for i := 0 ; i < 2 ; i ++ { // 2 attempts, second is race check
817- mismatch = false // hope there's no mismatch now
818-
819- for _ , tag := range tags {
820- for _ , arch := range strings .Split (* manifest , "," ) {
821- gethImage := fmt .Sprintf ("%s:%s-%s" , * upload , tag , arch )
822- toolImage := fmt .Sprintf ("%s:alltools-%s-%s" , * upload , tag , arch )
823-
824- for _ , img := range []string {gethImage , toolImage } {
825- if out , err := exec .Command ("docker" , "pull" , img ).CombinedOutput (); err != nil {
826- log .Printf ("Required image %s unavailable: %v\n Output: %s" , img , err , out )
827- mismatch = true
828- break
829- }
830- buildnum , err := exec .Command ("docker" , "inspect" , "--format" , "{{index .Config.Labels \" buildnum\" }}" , img ).CombinedOutput ()
831- if err != nil {
832- log .Fatalf ("Failed to inspect container: %v\n Output: %s" , err , string (buildnum ))
833- }
834- buildnum = bytes .TrimSpace (buildnum )
835-
836- if string (buildnum ) != env .Buildnum {
837- log .Printf ("Build number mismatch on %s: want %s, have %s" , img , env .Buildnum , buildnum )
838- mismatch = true
839- break
840- }
841- }
842- if mismatch {
843- break
844- }
845- }
846- if mismatch {
847- break
848- }
849- }
850- if mismatch {
851- // Build numbers mismatching, retry in a short time to
852- // avoid concurrent fails in both publisher images. If
853- // however the retry failed too, it means the concurrent
854- // builder is still crunching, let that do the publish.
855- if i == 0 {
856- time .Sleep (30 * time .Second )
857- }
858- continue
859- }
860- break
861- }
862- if mismatch {
863- log .Println ("Relinquishing publish to other builder" )
864- return
865- }
866- // Assemble and push the Geth manifest image
867- for _ , tag := range tags {
868- gethImage := fmt .Sprintf ("%s:%s" , * upload , tag )
869-
870- var gethSubImages []string
871- for _ , arch := range strings .Split (* manifest , "," ) {
872- gethSubImages = append (gethSubImages , gethImage + "-" + arch )
873- }
874- build .MustRunCommand ("docker" , append ([]string {"manifest" , "create" , gethImage }, gethSubImages ... )... )
875- build .MustRunCommand ("docker" , "manifest" , "push" , gethImage )
876- }
877- // Assemble and push the alltools manifest image
878- for _ , tag := range tags {
879- toolImage := fmt .Sprintf ("%s:alltools-%s" , * upload , tag )
880-
881- var toolSubImages []string
882- for _ , arch := range strings .Split (* manifest , "," ) {
883- toolSubImages = append (toolSubImages , toolImage + "-" + arch )
884- }
885- build .MustRunCommand ("docker" , append ([]string {"manifest" , "create" , toolImage }, toolSubImages ... )... )
886- build .MustRunCommand ("docker" , "manifest" , "push" , toolImage )
762+ // Need to create a mult-arch builder
763+ build .MustRunCommand ("docker" , "buildx" , "create" , "--use" , "--name" , "multi-arch-builder" , "--platform" , * platform )
764+
765+ for _ , spec := range []struct {
766+ file string
767+ base string
768+ }{
769+ {file : "Dockerfile" , base : fmt .Sprintf ("%s:" , * upload )},
770+ {file : "Dockerfile.alltools" , base : fmt .Sprintf ("%s:alltools-" , * upload )},
771+ } {
772+ for _ , tag := range tags { // latest, stable etc
773+ gethImage := fmt .Sprintf ("%s%s" , spec .base , tag )
774+ build .MustRunCommand ("docker" , "buildx" , "build" ,
775+ "--build-arg" , "COMMIT=" + env .Commit ,
776+ "--build-arg" , "VERSION=" + params .VersionWithMeta ,
777+ "--build-arg" , "BUILDNUM=" + env .Buildnum ,
778+ "--tag" , gethImage ,
779+ "--platform" , * platform ,
780+ "--push" ,
781+ "--file" , spec .file , "." )
887782 }
888783 }
889784}
0 commit comments