Directly build restic binary in release Docker container

This commit is contained in:
Michael Eischer 2023-05-19 17:43:11 +02:00
parent 2293835242
commit 43fa051546
4 changed files with 28 additions and 23 deletions

View file

@ -4,7 +4,6 @@
changelog/
doc/
docker/
helpers/
# Files
.gitignore

View file

@ -1,20 +1,18 @@
FROM --platform=$BUILDPLATFORM alpine:latest as helper
# the official binaries are cross-built from Linux running on an AMD64 host
# other architectures also seem to generate identical binaries but stay on the safe side
FROM --platform=linux/amd64 restic/builder:latest as helper
ARG VERSION
ARG TARGETOS
ARG TARGETARCH
# add release binary for the appropriate platform
COPY restic_${VERSION}_${TARGETOS}_${TARGETARCH}.bz2 /
RUN apk add --update --no-cache bzip2
RUN set -e && \
bzcat restic_${VERSION}_${TARGETOS}_${TARGETARCH}.bz2 > restic && \
chmod +x restic
COPY . /restic
RUN go run helpers/build-release-binaries/main.go --platform $TARGETOS/$TARGETARCH --skip-compress
RUN mv /output/restic_${TARGETOS}_${TARGETARCH} /output/restic
FROM alpine:latest
COPY --from=helper /restic /usr/bin
COPY --from=helper /output/restic /usr/bin
RUN apk add --update --no-cache ca-certificates fuse openssh-client tzdata jq
ENTRYPOINT ["/usr/bin/restic"]

View file

@ -22,6 +22,8 @@ var opts = struct {
OutputDir string
Tags string
PlatformSubset string
Platform string
SkipCompress bool
Version string
}{}
@ -31,6 +33,8 @@ func init() {
pflag.StringVarP(&opts.OutputDir, "output", "o", "/output", "path to the output `directory`")
pflag.StringVar(&opts.Tags, "tags", "", "additional build `tags`")
pflag.StringVar(&opts.PlatformSubset, "platform-subset", "", "specify `n/t` to only build this subset")
pflag.StringVarP(&opts.Platform, "platform", "p", "", "specify `os/arch` to only build this specific platform")
pflag.BoolVar(&opts.SkipCompress, "skip-compress", false, "skip binary compression step")
pflag.StringVar(&opts.Version, "version", "", "use `x.y.z` as the version for output files")
pflag.Parse()
}
@ -188,7 +192,9 @@ func buildForTarget(sourceDir, outputDir, goos, goarch string) (filename string)
filename = build(sourceDir, outputDir, goos, goarch)
touch(filepath.Join(outputDir, filename), mtime)
chmod(filepath.Join(outputDir, filename), 0755)
filename = compress(goos, outputDir, filename)
if !opts.SkipCompress {
filename = compress(goos, outputDir, filename)
}
return filename
}
@ -311,6 +317,8 @@ func main() {
if err != nil {
die("%s", err)
}
} else if opts.Platform != "" {
targets = buildPlatformList([]string{opts.Platform})
}
sourceDir := abs(opts.SourceDir)

View file

@ -4,6 +4,7 @@ import (
"bufio"
"bytes"
"fmt"
"math/rand"
"os"
"os/exec"
"path/filepath"
@ -409,19 +410,19 @@ func signFiles(filenames ...string) {
}
}
func updateDocker(outputDir, version string) string {
run("docker", "buildx", "create", "--name", "restic-release-builder", "--driver", "docker-container", "--bootstrap")
func updateDocker(sourceDir, version string) string {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
builderName := fmt.Sprintf("restic-release-builder-%d", r.Int())
run("docker", "buildx", "create", "--name", builderName, "--driver", "docker-container", "--bootstrap")
cmds := ""
buildCmd := fmt.Sprintf("docker buildx build --builder %s --platform linux/386,linux/amd64,linux/arm,linux/arm64 --pull -f docker/Dockerfile.release %q", builderName, sourceDir)
run("sh", "-c", buildCmd+" --no-cache")
publishCmds := ""
for _, tag := range []string{"restic/restic:latest", "restic/restic:" + version} {
cmd := fmt.Sprintf("docker buildx build --builder restic-release-builder --platform linux/386,linux/amd64,linux/arm,linux/arm64 --pull --tag %q -f docker/Dockerfile.release --build-arg VERSION=%q %q", tag, version, outputDir)
run("sh", "-c", cmd)
cmds += cmd + " --push\n"
publishCmds += buildCmd + fmt.Sprintf(" --tag %q --push\n", tag)
}
return cmds + "\ndocker buildx rm restic-release-builder"
return publishCmds + "\ndocker buildx rm " + builderName
}
func tempdir(prefix string) string {
@ -470,15 +471,14 @@ func main() {
extractTar(tarFilename, sourceDir)
runBuild(sourceDir, opts.OutputDir, opts.Version)
rmdir(sourceDir)
sha256sums(opts.OutputDir, filepath.Join(opts.OutputDir, "SHA256SUMS"))
signFiles(filepath.Join(opts.OutputDir, "SHA256SUMS"), tarFilename)
dockerCmds := updateDocker(opts.OutputDir, opts.Version)
dockerCmds := updateDocker(sourceDir, opts.Version)
msg("done, output dir is %v", opts.OutputDir)
msg("now run:\n\ngit push --tags origin master\n%s\n", dockerCmds)
msg("now run:\n\ngit push --tags origin master\n%s\n\nrm -rf %q", dockerCmds, sourceDir)
}