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
No known key found for this signature in database
GPG key ID: 03EDC70FD578067F
4 changed files with 107 additions and 41 deletions

View file

@ -359,11 +359,15 @@ osx_alt_build_task:
TEST_FLAVOR: "altbuild"
ALT_NAME: 'OSX Cross'
osx_instance:
image: 'catalina-base'
script:
image: 'big-sur-base'
setup_script:
- brew install go
- 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

View file

@ -23,6 +23,7 @@
export GOPROXY=https://proxy.golang.org
GO ?= go
GOCMD = CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO)
COVERAGE_PATH ?= .coverage
DESTDIR ?=
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
CGO_ENABLED ?= 1
# 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)
BINSFX := .exe
SRCBINDIR := bin/windows
@ -162,7 +167,7 @@ BINSFX := -remote
SRCBINDIR := bin
endif
# 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
env GO111MODULE=off \
@ -239,11 +244,11 @@ gofmt: ## Verify the source code gofmt
.PHONY: test/checkseccomp/checkseccomp
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
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
volume-plugin-test-img:
@ -251,7 +256,7 @@ volume-plugin-test-img:
.PHONY: test/goecho/goecho
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
$(GO) build -o $@ ./test/version/
@ -292,8 +297,7 @@ ifeq (,$(findstring systemd,$(BUILDTAGS)))
Install libsystemd on Ubuntu or systemd-devel on rpm based \
distro for journald support."
endif
CGO_ENABLED=$(CGO_ENABLED) \
$(GO) build \
$(GOCMD) build \
$(BUILDFLAGS) \
-ldflags '$(LDFLAGS_PODMAN)' \
-tags "$(BUILDTAGS)" \
@ -304,18 +308,14 @@ $(SRCBINDIR):
mkdir -p $(SRCBINDIR)
$(SRCBINDIR)/podman$(BINSFX): $(SRCBINDIR) .gopathok $(SOURCES) go.mod go.sum
CGO_ENABLED=$(CGO_ENABLED) \
GOOS=$(GOOS) \
$(GO) build \
$(GOCMD) build \
$(BUILDFLAGS) \
-ldflags '$(LDFLAGS_PODMAN)' \
-tags "${REMOTETAGS}" \
-o $@ ./cmd/podman
$(SRCBINDIR)/podman-remote-static: $(SRCBINDIR) .gopathok $(SOURCES) go.mod go.sum
CGO_ENABLED=0 \
GOOS=$(GOOS) \
$(GO) build \
$(GOCMD) build \
$(BUILDFLAGS) \
-ldflags '$(LDFLAGS_PODMAN_STATIC)' \
-tags "${REMOTETAGS}" \
@ -333,6 +333,7 @@ podman-remote-linux: ## Build podman-remote for Linux
$(MAKE) \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=$(GOARCH) \
bin/podman-remote
PHONY: podman-remote-static
@ -350,6 +351,7 @@ podman-remote-darwin: ## Build podman-remote for macOS
$(MAKE) \
CGO_ENABLED=0 \
GOOS=darwin \
GOARCH=$(GOARCH) \
bin/darwin/podman
###
@ -359,7 +361,7 @@ podman-remote-darwin: ## Build podman-remote for macOS
.PHONY: generate-bindings
generate-bindings:
ifneq ($(GOOS),darwin)
GO111MODULE=off $(GO) generate ./pkg/bindings/... ;
GO111MODULE=off $(GOCMD) generate ./pkg/bindings/... ;
endif
# 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
# 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
mkdir -p docs/build/remote
ln -sf $(CURDIR)/docs/source/markdown/links docs/build/man/
docs/remote-docs.sh \
$* \
$(GOOS) \
docs/build/remote/$* \
$(if $(findstring windows,$*),docs/source/markdown,docs/build/man)
@ -602,35 +606,65 @@ tests-expect-exit:
### 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 SUBDIR := podman-v$(call err_if_empty,RELEASE_NUMBER))
$(eval _DSTARGS := "DESTDIR=$(TMPDIR)/$(SUBDIR)" "PREFIX=/usr")
$(eval GOARCH := $*)
mkdir -p "$(TMPDIR)/$(SUBDIR)"
$(MAKE) install.bin install.remote install.man \
install.systemd "DESTDIR=$(TMPDIR)/$(SUBDIR)" "PREFIX=/usr"
$(MAKE) GOOS=$(GOOS) GOARCH=$(NATIVE_GOARCH) \
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)"
if [[ "$(GOARCH)" != "$(NATIVE_GOARCH)" ]]; then $(MAKE) clean-binaries; fi
-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 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)"
$(MAKE) \
GOOS=$* \
DESTDIR=$(TMPDIR)/ \
BINDIR=$(SUBDIR) \
SELINUXOPT="" \
install.remote-nobuild
cp -r ./docs/build/remote/$* "$(TMPDIR)/$(SUBDIR)/docs/"
$(MAKE) GOOS=$(GOOS) GOARCH=$(NATIVE_GOARCH) \
clean-binaries podman-remote-$(GOOS)-docs
if [[ "$(GOARCH)" != "$(NATIVE_GOARCH)" ]]; then \
$(MAKE) CGO_ENABLED=0 $(GOPLAT) BUILDTAGS="$(BUILDTAGS_CROSS)" \
clean-binaries podman-remote-$(GOOS); \
else \
$(MAKE) $(GOPLAT) podman-remote-$(GOOS); \
fi
cp -r ./docs/build/remote/$(GOOS) "$(TMPDIR)/$(SUBDIR)/docs/"
cp ./contrib/remote/containers.conf "$(TMPDIR)/$(SUBDIR)/"
$(MAKE) $(GOPLAT) $(_DSTARGS) SELINUXOPT="" install.remote-nobuild
cd "$(TMPDIR)" && \
zip --recurse-paths "$(CURDIR)/$@" "./"
if [[ "$(GOARCH)" != "$(NATIVE_GOARCH)" ]]; then $(MAKE) clean-binaries; fi
-rm -rf "$(TMPDIR)"
.PHONY: podman.msi
podman.msi: test/version/version ## Build podman-remote, package for installation on Windows
$(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)
find $(DOCFILE) -print | \
wixl-heat --var var.ManSourceDir --component-group ManFiles \
@ -821,8 +855,13 @@ uninstall:
rm -f ${DESTDIR}${USERSYSTEMDDIR}/podman.socket
rm -f ${DESTDIR}${USERSYSTEMDDIR}/podman.service
.PHONY: clean-binaries
clean-binaries: ## Remove platform/architecture specific binary files
rm -rf \
bin \
.PHONY: clean
clean: ## Clean all make artifacts
clean: clean-binaries ## Clean all make artifacts
rm -rf \
.gopathok \
_output \
@ -830,7 +869,6 @@ clean: ## Clean all make artifacts
$(wildcard podman-remote*.zip) \
$(wildcard podman_tmp_*) \
$(wildcard podman*.tar.gz) \
bin \
build \
test/checkseccomp/checkseccomp \
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
(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
(the binaries which were actually tested). Visit each of the
"Build for ...", "Static Build", and "... Cross" tasks.
1. Under the "Artifacts" section of each task, click the "gosrc" item,
1. For anything other than an RC, download the new release artifacts from CI
(the binaries which were actually tested). The items are
located under the *checks* tab in github for:
* `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`).
Save the the archive with a meaningful name, for example
`podman-v3.0.0.msi`.
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`.
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
`sha256sum *.tar.gz *.zip *.msi > shasums` to generate SHA sums.
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
make clean
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() {
local -a arches
local arch
req_env_vars ALT_NAME
# Defined in .cirrus.yml
# shellcheck disable=SC2154
@ -221,7 +223,7 @@ function _run_altbuild() {
make build-all-new-commits GIT_BASE_BRANCH=origin/$DEST_BRANCH
;;
*Windows*)
make podman-remote-release-windows.zip
make podman-remote-release-windows_amd64.zip
make podman.msi
;;
*Without*)
@ -232,7 +234,21 @@ function _run_altbuild() {
rpmbuild --rebuild ./podman-*.src.rpm
;;
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*)
req_env_vars CTR_FQIN