Cross-build release-archives w/ arch in filename

Fixes #11417

Cross-building the podman-remote documentation requires a functional
native architecture executable.  However `make` only deals with
files/timestamps, it doesn't understand if an existing binary will
function on the system or not.  This makes building cross-platform
releases incredibly accident-prone and fragile.

A practical way to deal with this, is via multiple conditional (nested)
`make` calls along with careful manipulation of `$GOOS` and `$GOARCH`.
Also, when cross-building releases be kind to humans and cleanup
any non-native binaries left behind.

Update the `Alt Arch. Cross` Cirrus-CI task to build release archives
for all Linux architectures supported by golang and podman.  Update
the `OSX Cross` task to additionally build for the M1 (arm64)
architecture.

Finally, update the release process documentation to reflect the
new locations (Cirrus-CI task names) for the release archives.  Include
a note about additional manual work being required to produce the
signed `.dmg` file for MacOS.

Signed-off-by: Chris Evich <cevich@redhat.com>
This commit is contained in:
Chris Evich
2021-09-09 13:46:21 -04:00
parent cd7b48198c
commit 319fcf52fc
4 changed files with 107 additions and 41 deletions

View File

@ -359,11 +359,15 @@ osx_alt_build_task:
TEST_FLAVOR: "altbuild" TEST_FLAVOR: "altbuild"
ALT_NAME: 'OSX Cross' ALT_NAME: 'OSX Cross'
osx_instance: osx_instance:
image: 'catalina-base' image: 'big-sur-base'
script: setup_script:
- brew install go - brew install go
- brew install go-md2man - brew install go-md2man
- make podman-remote-release-darwin.zip - go version
build_amd64_script:
- make podman-remote-release-darwin_amd64.zip
build_arm64_script:
- make podman-remote-release-darwin_arm64.zip GOARCH=arm64
always: *binary_artifacts always: *binary_artifacts

View File

@ -23,6 +23,7 @@
export GOPROXY=https://proxy.golang.org export GOPROXY=https://proxy.golang.org
GO ?= go GO ?= go
GOCMD = CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO)
COVERAGE_PATH ?= .coverage COVERAGE_PATH ?= .coverage
DESTDIR ?= DESTDIR ?=
EPOCH_TEST_COMMIT ?= $(shell git merge-base $${DEST_BRANCH:-main} HEAD) EPOCH_TEST_COMMIT ?= $(shell git merge-base $${DEST_BRANCH:-main} HEAD)
@ -150,7 +151,11 @@ err_if_empty = $(if $(strip $($(1))),$(strip $($(1))),$(error Required variable
# Podman does not work w/o CGO_ENABLED, except in some very specific cases # Podman does not work w/o CGO_ENABLED, except in some very specific cases
CGO_ENABLED ?= 1 CGO_ENABLED ?= 1
# Default to the native OS type and architecture unless otherwise specified # Default to the native OS type and architecture unless otherwise specified
GOOS ?= $(shell $(GO) env GOOS) NATIVE_GOOS := $(shell env -u GOOS $(GO) env GOOS)
GOOS ?= $(NATIVE_GOOS)
# Default to the native architecture type
NATIVE_GOARCH := $(shell env -u GOARCH $(GO) env GOARCH)
GOARCH ?= $(NATIVE_GOARCH)
ifeq ($(call err_if_empty,GOOS),windows) ifeq ($(call err_if_empty,GOOS),windows)
BINSFX := .exe BINSFX := .exe
SRCBINDIR := bin/windows SRCBINDIR := bin/windows
@ -162,7 +167,7 @@ BINSFX := -remote
SRCBINDIR := bin SRCBINDIR := bin
endif endif
# Necessary for nested-$(MAKE) calls and docs/remote-docs.sh # Necessary for nested-$(MAKE) calls and docs/remote-docs.sh
export GOOS CGO_ENABLED BINSFX SRCBINDIR export GOOS GOARCH CGO_ENABLED BINSFX SRCBINDIR
define go-get define go-get
env GO111MODULE=off \ env GO111MODULE=off \
@ -239,11 +244,11 @@ gofmt: ## Verify the source code gofmt
.PHONY: test/checkseccomp/checkseccomp .PHONY: test/checkseccomp/checkseccomp
test/checkseccomp/checkseccomp: .gopathok $(wildcard test/checkseccomp/*.go) test/checkseccomp/checkseccomp: .gopathok $(wildcard test/checkseccomp/*.go)
$(GO) build $(BUILDFLAGS) -ldflags '$(LDFLAGS_PODMAN)' -tags "$(BUILDTAGS)" -o $@ ./test/checkseccomp $(GOCMD) build $(BUILDFLAGS) -ldflags '$(LDFLAGS_PODMAN)' -tags "$(BUILDTAGS)" -o $@ ./test/checkseccomp
.PHONY: test/testvol/testvol .PHONY: test/testvol/testvol
test/testvol/testvol: .gopathok $(wildcard test/testvol/*.go) test/testvol/testvol: .gopathok $(wildcard test/testvol/*.go)
$(GO) build $(BUILDFLAGS) -ldflags '$(LDFLAGS_PODMAN)' -o $@ ./test/testvol $(GOCMD) build $(BUILDFLAGS) -ldflags '$(LDFLAGS_PODMAN)' -o $@ ./test/testvol
.PHONY: volume-plugin-test-image .PHONY: volume-plugin-test-image
volume-plugin-test-img: volume-plugin-test-img:
@ -251,7 +256,7 @@ volume-plugin-test-img:
.PHONY: test/goecho/goecho .PHONY: test/goecho/goecho
test/goecho/goecho: .gopathok $(wildcard test/goecho/*.go) test/goecho/goecho: .gopathok $(wildcard test/goecho/*.go)
$(GO) build $(BUILDFLAGS) -ldflags '$(LDFLAGS_PODMAN)' -o $@ ./test/goecho $(GOCMD) build $(BUILDFLAGS) -ldflags '$(LDFLAGS_PODMAN)' -o $@ ./test/goecho
test/version/version: .gopathok version/version.go test/version/version: .gopathok version/version.go
$(GO) build -o $@ ./test/version/ $(GO) build -o $@ ./test/version/
@ -292,8 +297,7 @@ ifeq (,$(findstring systemd,$(BUILDTAGS)))
Install libsystemd on Ubuntu or systemd-devel on rpm based \ Install libsystemd on Ubuntu or systemd-devel on rpm based \
distro for journald support." distro for journald support."
endif endif
CGO_ENABLED=$(CGO_ENABLED) \ $(GOCMD) build \
$(GO) build \
$(BUILDFLAGS) \ $(BUILDFLAGS) \
-ldflags '$(LDFLAGS_PODMAN)' \ -ldflags '$(LDFLAGS_PODMAN)' \
-tags "$(BUILDTAGS)" \ -tags "$(BUILDTAGS)" \
@ -304,18 +308,14 @@ $(SRCBINDIR):
mkdir -p $(SRCBINDIR) mkdir -p $(SRCBINDIR)
$(SRCBINDIR)/podman$(BINSFX): $(SRCBINDIR) .gopathok $(SOURCES) go.mod go.sum $(SRCBINDIR)/podman$(BINSFX): $(SRCBINDIR) .gopathok $(SOURCES) go.mod go.sum
CGO_ENABLED=$(CGO_ENABLED) \ $(GOCMD) build \
GOOS=$(GOOS) \
$(GO) build \
$(BUILDFLAGS) \ $(BUILDFLAGS) \
-ldflags '$(LDFLAGS_PODMAN)' \ -ldflags '$(LDFLAGS_PODMAN)' \
-tags "${REMOTETAGS}" \ -tags "${REMOTETAGS}" \
-o $@ ./cmd/podman -o $@ ./cmd/podman
$(SRCBINDIR)/podman-remote-static: $(SRCBINDIR) .gopathok $(SOURCES) go.mod go.sum $(SRCBINDIR)/podman-remote-static: $(SRCBINDIR) .gopathok $(SOURCES) go.mod go.sum
CGO_ENABLED=0 \ $(GOCMD) build \
GOOS=$(GOOS) \
$(GO) build \
$(BUILDFLAGS) \ $(BUILDFLAGS) \
-ldflags '$(LDFLAGS_PODMAN_STATIC)' \ -ldflags '$(LDFLAGS_PODMAN_STATIC)' \
-tags "${REMOTETAGS}" \ -tags "${REMOTETAGS}" \
@ -333,6 +333,7 @@ podman-remote-linux: ## Build podman-remote for Linux
$(MAKE) \ $(MAKE) \
CGO_ENABLED=0 \ CGO_ENABLED=0 \
GOOS=linux \ GOOS=linux \
GOARCH=$(GOARCH) \
bin/podman-remote bin/podman-remote
PHONY: podman-remote-static PHONY: podman-remote-static
@ -350,6 +351,7 @@ podman-remote-darwin: ## Build podman-remote for macOS
$(MAKE) \ $(MAKE) \
CGO_ENABLED=0 \ CGO_ENABLED=0 \
GOOS=darwin \ GOOS=darwin \
GOARCH=$(GOARCH) \
bin/darwin/podman bin/darwin/podman
### ###
@ -359,7 +361,7 @@ podman-remote-darwin: ## Build podman-remote for macOS
.PHONY: generate-bindings .PHONY: generate-bindings
generate-bindings: generate-bindings:
ifneq ($(GOOS),darwin) ifneq ($(GOOS),darwin)
GO111MODULE=off $(GO) generate ./pkg/bindings/... ; GO111MODULE=off $(GOCMD) generate ./pkg/bindings/... ;
endif endif
# DO NOT USE: use local-cross instead # DO NOT USE: use local-cross instead
@ -444,12 +446,14 @@ docs: $(MANPAGES) ## Generate documentation
# docs/remote-docs.sh requires a locally executable 'podman-remote' binary # docs/remote-docs.sh requires a locally executable 'podman-remote' binary
# in addition to the target-archetecture binary (if any). # in addition to the target-archetecture binary (if any).
install-podman-remote-%-docs: podman-remote-$(shell env -i HOME=$$HOME PATH=$$PATH go env GOOS) docs $(MANPAGES) podman-remote-%-docs: podman-remote-$(NATIVE_GOOS)
$(eval GOOS := $*)
$(MAKE) docs $(MANPAGES)
rm -rf docs/build/remote rm -rf docs/build/remote
mkdir -p docs/build/remote mkdir -p docs/build/remote
ln -sf $(CURDIR)/docs/source/markdown/links docs/build/man/ ln -sf $(CURDIR)/docs/source/markdown/links docs/build/man/
docs/remote-docs.sh \ docs/remote-docs.sh \
$* \ $(GOOS) \
docs/build/remote/$* \ docs/build/remote/$* \
$(if $(findstring windows,$*),docs/source/markdown,docs/build/man) $(if $(findstring windows,$*),docs/source/markdown,docs/build/man)
@ -602,35 +606,65 @@ tests-expect-exit:
### Release/Packaging targets ### Release/Packaging targets
### ###
podman-release.tar.gz: test/version/version binaries docs ## Build all binaries, docs., and installation tree, into a tarball. .PHONY: podman-release
podman-release: podman-release-$(GOARCH).tar.gz # Build all Linux binaries for $GOARCH, docs., and installation tree, into a tarball.
# The following two targets are nuanced and complex:
# Cross-building the podman-remote documentation requires a functional
# native architecture executable. However `make` only deals with
# files/timestamps, it doesn't understand if an existing binary will
# function on the system or not. This makes building cross-platform
# releases incredibly accident-prone and fragile. The only practical
# way to deal with this, is via multiple conditional (nested) `make`
# calls along with careful manipulation of `$GOOS` and `$GOARCH`.
podman-release-%.tar.gz: test/version/version
$(eval TMPDIR := $(shell mktemp -d podman_tmp_XXXX)) $(eval TMPDIR := $(shell mktemp -d podman_tmp_XXXX))
$(eval SUBDIR := podman-v$(call err_if_empty,RELEASE_NUMBER)) $(eval SUBDIR := podman-v$(call err_if_empty,RELEASE_NUMBER))
$(eval _DSTARGS := "DESTDIR=$(TMPDIR)/$(SUBDIR)" "PREFIX=/usr")
$(eval GOARCH := $*)
mkdir -p "$(TMPDIR)/$(SUBDIR)" mkdir -p "$(TMPDIR)/$(SUBDIR)"
$(MAKE) install.bin install.remote install.man \ $(MAKE) GOOS=$(GOOS) GOARCH=$(NATIVE_GOARCH) \
install.systemd "DESTDIR=$(TMPDIR)/$(SUBDIR)" "PREFIX=/usr" clean-binaries docs podman-remote-$(GOOS)-docs
if [[ "$(GOARCH)" != "$(NATIVE_GOARCH)" ]]; then \
$(MAKE) CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) \
BUILDTAGS="$(BUILDTAGS_CROSS)" clean-binaries binaries; \
else \
$(MAKE) GOOS=$(GOOS) GOARCH=$(GOARCH) binaries; \
fi
$(MAKE) $(_DSTARGS) install.bin-nobuild install.remote-nobuild install.man install.systemd
tar -czvf $@ --xattrs -C "$(TMPDIR)" "./$(SUBDIR)" tar -czvf $@ --xattrs -C "$(TMPDIR)" "./$(SUBDIR)"
if [[ "$(GOARCH)" != "$(NATIVE_GOARCH)" ]]; then $(MAKE) clean-binaries; fi
-rm -rf "$(TMPDIR)" -rm -rf "$(TMPDIR)"
podman-remote-release-%.zip: test/version/version podman-remote-% install-podman-remote-%-docs ## Build podman-remote for GOOS=%, docs., and installation zip. podman-remote-release-%.zip: test/version/version ## Build podman-remote for %=$GOOS_$GOARCH, and docs. into an installation zip.
$(eval TMPDIR := $(shell mktemp -d podman_tmp_XXXX)) $(eval TMPDIR := $(shell mktemp -d podman_tmp_XXXX))
$(eval SUBDIR := podman-$(call err_if_empty,RELEASE_NUMBER)) $(eval SUBDIR := podman-$(call err_if_empty,RELEASE_NUMBER))
$(eval _DSTARGS := "DESTDIR=$(TMPDIR)/$(SUBDIR)" "PREFIX=/usr")
$(eval GOOS := $(firstword $(subst _, ,$*)))
$(eval GOARCH := $(lastword $(subst _, ,$*)))
$(eval _GOPLAT := GOOS=$(call err_if_empty,GOOS) GOARCH=$(call err_if_empty,GOARCH))
mkdir -p "$(TMPDIR)/$(SUBDIR)" mkdir -p "$(TMPDIR)/$(SUBDIR)"
$(MAKE) \ $(MAKE) GOOS=$(GOOS) GOARCH=$(NATIVE_GOARCH) \
GOOS=$* \ clean-binaries podman-remote-$(GOOS)-docs
DESTDIR=$(TMPDIR)/ \ if [[ "$(GOARCH)" != "$(NATIVE_GOARCH)" ]]; then \
BINDIR=$(SUBDIR) \ $(MAKE) CGO_ENABLED=0 $(GOPLAT) BUILDTAGS="$(BUILDTAGS_CROSS)" \
SELINUXOPT="" \ clean-binaries podman-remote-$(GOOS); \
install.remote-nobuild else \
cp -r ./docs/build/remote/$* "$(TMPDIR)/$(SUBDIR)/docs/" $(MAKE) $(GOPLAT) podman-remote-$(GOOS); \
fi
cp -r ./docs/build/remote/$(GOOS) "$(TMPDIR)/$(SUBDIR)/docs/"
cp ./contrib/remote/containers.conf "$(TMPDIR)/$(SUBDIR)/" cp ./contrib/remote/containers.conf "$(TMPDIR)/$(SUBDIR)/"
$(MAKE) $(GOPLAT) $(_DSTARGS) SELINUXOPT="" install.remote-nobuild
cd "$(TMPDIR)" && \ cd "$(TMPDIR)" && \
zip --recurse-paths "$(CURDIR)/$@" "./" zip --recurse-paths "$(CURDIR)/$@" "./"
if [[ "$(GOARCH)" != "$(NATIVE_GOARCH)" ]]; then $(MAKE) clean-binaries; fi
-rm -rf "$(TMPDIR)" -rm -rf "$(TMPDIR)"
.PHONY: podman.msi .PHONY: podman.msi
podman.msi: test/version/version ## Build podman-remote, package for installation on Windows podman.msi: test/version/version ## Build podman-remote, package for installation on Windows
$(MAKE) podman-v$(RELEASE_NUMBER).msi $(MAKE) podman-v$(RELEASE_NUMBER).msi
podman-v$(RELEASE_NUMBER).msi: podman-remote-windows install-podman-remote-windows-docs podman-v$(RELEASE_NUMBER).msi: podman-remote-windows podman-remote-windows-docs
$(eval DOCFILE := docs/build/remote/windows) $(eval DOCFILE := docs/build/remote/windows)
find $(DOCFILE) -print | \ find $(DOCFILE) -print | \
wixl-heat --var var.ManSourceDir --component-group ManFiles \ wixl-heat --var var.ManSourceDir --component-group ManFiles \
@ -821,8 +855,13 @@ uninstall:
rm -f ${DESTDIR}${USERSYSTEMDDIR}/podman.socket rm -f ${DESTDIR}${USERSYSTEMDDIR}/podman.socket
rm -f ${DESTDIR}${USERSYSTEMDDIR}/podman.service rm -f ${DESTDIR}${USERSYSTEMDDIR}/podman.service
.PHONY: clean-binaries
clean-binaries: ## Remove platform/architecture specific binary files
rm -rf \
bin \
.PHONY: clean .PHONY: clean
clean: ## Clean all make artifacts clean: clean-binaries ## Clean all make artifacts
rm -rf \ rm -rf \
.gopathok \ .gopathok \
_output \ _output \
@ -830,7 +869,6 @@ clean: ## Clean all make artifacts
$(wildcard podman-remote*.zip) \ $(wildcard podman-remote*.zip) \
$(wildcard podman_tmp_*) \ $(wildcard podman_tmp_*) \
$(wildcard podman*.tar.gz) \ $(wildcard podman*.tar.gz) \
bin \
build \ build \
test/checkseccomp/checkseccomp \ test/checkseccomp/checkseccomp \
test/goecho/goecho \ test/goecho/goecho \

View File

@ -234,16 +234,24 @@ spelled with complete minutiae.
1. Return to the Cirrus-CI Build page for the new release tag, confirm 1. Return to the Cirrus-CI Build page for the new release tag, confirm
(or wait for) it to complete, re-running any failed tasks as appropriate. (or wait for) it to complete, re-running any failed tasks as appropriate.
1. For anything other than an RC, download the new release artifacts 1. For anything other than an RC, download the new release artifacts from CI
(the binaries which were actually tested). Visit each of the (the binaries which were actually tested). The items are
"Build for ...", "Static Build", and "... Cross" tasks. located under the *checks* tab in github for:
1. Under the "Artifacts" section of each task, click the "gosrc" item,
* `Cirrus CI / Alt Arch. Cross` - tarball for each architecture
* `Cirrus CI / OSX Cross` - two zip files (amd64 and arm64)
* `Cirrus CI / Windows Cross` - an `msi` file
* `Cirrus CI / Static Build` - the `bin/podman-remote` file
Under the "Artifacts" section of each task, click the "gosrc" link,
find and download the release archive (`zip`, `tar.gz` or `.msi`). find and download the release archive (`zip`, `tar.gz` or `.msi`).
Save the the archive with a meaningful name, for example Save the the archive with a meaningful name, for example
`podman-v3.0.0.msi`. `podman-v3.0.0.msi`.
1. For the "Static Build" task, find the compiled `podman` and `podman-remote` 1. For the "Static Build" task, find the compiled `podman` and `podman-remote`
binaries under the "binary", "bin" links. Tar these files as binaries under the "binary", then "bin" links. Tar these files as
`podman-static.tar.gz`. `podman-static.tar.gz`.
1. The `podman-vX.Y.Z.dmg` file is produced manually by someone in
posession of a developer signing key.
1. In the directory where you downloaded the archives, run 1. In the directory where you downloaded the archives, run
`sha256sum *.tar.gz *.zip *.msi > shasums` to generate SHA sums. `sha256sum *.tar.gz *.zip *.msi > shasums` to generate SHA sums.
1. Go to `https://github.com/containers/podman/releases/tag/vX.Y.Z` and 1. Go to `https://github.com/containers/podman/releases/tag/vX.Y.Z` and

View File

@ -205,10 +205,12 @@ function _run_build() {
# Ensure always start from clean-slate with all vendor modules downloaded # Ensure always start from clean-slate with all vendor modules downloaded
make clean make clean
make vendor make vendor
make podman-release.tar.gz # includes podman, podman-remote, and docs make podman-release # includes podman, podman-remote, and docs
} }
function _run_altbuild() { function _run_altbuild() {
local -a arches
local arch
req_env_vars ALT_NAME req_env_vars ALT_NAME
# Defined in .cirrus.yml # Defined in .cirrus.yml
# shellcheck disable=SC2154 # shellcheck disable=SC2154
@ -221,7 +223,7 @@ function _run_altbuild() {
make build-all-new-commits GIT_BASE_BRANCH=origin/$DEST_BRANCH make build-all-new-commits GIT_BASE_BRANCH=origin/$DEST_BRANCH
;; ;;
*Windows*) *Windows*)
make podman-remote-release-windows.zip make podman-remote-release-windows_amd64.zip
make podman.msi make podman.msi
;; ;;
*Without*) *Without*)
@ -232,7 +234,21 @@ function _run_altbuild() {
rpmbuild --rebuild ./podman-*.src.rpm rpmbuild --rebuild ./podman-*.src.rpm
;; ;;
Alt*Cross) Alt*Cross)
make local-cross arches=(\
amd64
ppc64le
arm
arm64
386
s390x
mips
mipsle
mips64
mips64le)
for arch in "${arches[@]}"; do
msg "Building release archive for $arch"
make podman-release-${arch}.tar.gz GOARCH=$arch
done
;; ;;
*Static*) *Static*)
req_env_vars CTR_FQIN req_env_vars CTR_FQIN