Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added .gcloudignore
Empty file.
13 changes: 8 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
ARG ARCH=amd64
FROM --platform=linux/${ARCH} gcr.io/distroless/static-debian12@sha256:87bce11be0af225e4ca761c40babb06d6d559f5767fbf7dc3c47f0f1a466b92c
FROM gcr.io/distroless/static-debian12@sha256:87bce11be0af225e4ca761c40babb06d6d559f5767fbf7dc3c47f0f1a466b92c

ADD etcd /usr/local/bin/
ADD etcdctl /usr/local/bin/
ADD etcdutl /usr/local/bin/
ARG TARGETARCH
ARG VERSION
ARG BUILD_DIR

ADD ${BUILD_DIR}/etcd-${VERSION}-linux-${TARGETARCH}/etcd /usr/local/bin/
ADD ${BUILD_DIR}/etcd-${VERSION}-linux-${TARGETARCH}/etcdctl /usr/local/bin/
ADD ${BUILD_DIR}/etcd-${VERSION}-linux-${TARGETARCH}/etcdutl /usr/local/bin/

WORKDIR /var/etcd/
WORKDIR /var/lib/etcd/
Expand Down
19 changes: 19 additions & 0 deletions cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# See https://cloud.google.com/cloud-build/docs/build-config
timeout: 1800s
options:
machineType: "E2_HIGHCPU_32"
steps:
# Push the images
- name: "gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20251110-7ccd542560"
id: images
entrypoint: bash
args:
- scripts/build-release.sh
env:
- REGISTRY=$_REGISTRY
- GCS_LOCATION=$_GCS_LOCATION
- CI=1
- BUILDX_NO_DEFAULT_ATTESTATIONS=1
substitutions:
_REGISTRY: gcr.io/k8s-staging-etcd #us-central1-docker.pkg.dev/k8s-staging-images/us-central1/etcd
_GCS_LOCATION: k8s-staging-etcd/releases
76 changes: 20 additions & 56 deletions scripts/build-binary.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,65 +18,28 @@ set -euo pipefail
source ./scripts/test_lib.sh

VER=${1:-}
REPOSITORY="${REPOSITORY:[email protected]:etcd-io/etcd.git}"

if [ -z "$VER" ]; then
echo "Usage: ${0} VERSION" >> /dev/stderr
exit 255
VER=$(git describe --tags --always --dirty)
fi

function setup_env {
local ver=${1}
local proj=${2}

if [ ! -d "${proj}" ]; then
run git clone "${REPOSITORY}"
fi

pushd "${proj}" >/dev/null
run git fetch --all
run git checkout "${ver}"
popd >/dev/null
}


function package {
local target=${1}
local srcdir="${2}/bin"

local ccdir="${srcdir}/${GOOS}_${GOARCH}"
if [ -d "${ccdir}" ]; then
srcdir="${ccdir}"
fi
local ext=""
if [ "${GOOS}" == "windows" ]; then
ext=".exe"
fi
for bin in etcd etcdctl etcdutl; do
cp "${srcdir}/${bin}" "${target}/${bin}${ext}"
done

cp etcd/README.md "${target}"/README.md
cp etcd/etcdctl/README.md "${target}"/README-etcdctl.md
cp etcd/etcdctl/READMEv2.md "${target}"/READMEv2-etcdctl.md
cp etcd/etcdutl/README.md "${target}"/README-etcdutl.md

cp -R etcd/Documentation "${target}"/Documentation
cp README.md "${target}"/README.md
cp etcdctl/README.md "${target}"/README-etcdctl.md
cp etcdctl/READMEv2.md "${target}"/READMEv2-etcdctl.md
cp etcdutl/README.md "${target}"/README-etcdutl.md
cp -R Documentation "${target}/"
}

function main {
local proj="etcd"

mkdir -p release
cd release
setup_env "${VER}" "${proj}"

local tarcmd=tar
if [[ $(go env GOOS) == "darwin" ]]; then
echo "Please use linux machine for release builds."
exit 1
if [ "$(go env GOOS)" == "darwin" ]; then
tarcmd=gtar
fi

for os in darwin windows linux; do
export GOOS=${os}
TARGET_ARCHS=("amd64")
Expand All @@ -94,20 +57,21 @@ function main {
for TARGET_ARCH in "${TARGET_ARCHS[@]}"; do
export GOARCH=${TARGET_ARCH}

pushd etcd >/dev/null
GO_LDFLAGS="-s -w" ./scripts/build.sh
popd >/dev/null

TARGET="etcd-${VER}-${GOOS}-${GOARCH}"
mkdir "${TARGET}"
package "${TARGET}" "${proj}"
TARGET="release/etcd-${VER}-${GOOS}-${GOARCH}"
VERSION="${VER}" BINDIR="${TARGET}" GO_LDFLAGS="-s -w" scripts/build.sh
package "${TARGET}"

if [ ${GOOS} == "linux" ]; then
${tarcmd} cfz "${TARGET}.tar.gz" "${TARGET}"
echo "Wrote release/${TARGET}.tar.gz"
# https://reproducible-builds.org/docs/archives/#full-example
GZIP=-n ${tarcmd} --sort=name \
--mtime="UTC 1970-01-01" \
--owner=0 --group=0 --numeric-owner \
--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime \
-zcf "${TARGET}.tar.gz" "${TARGET}"
echo "Wrote ${TARGET}.tar.gz"
else
zip -qr "${TARGET}.zip" "${TARGET}"
echo "Wrote release/${TARGET}.zip"
zip -qrX "${TARGET}.zip" "${TARGET}"
echo "Wrote ${TARGET}.zip"
fi
done
done
Expand Down
76 changes: 42 additions & 34 deletions scripts/build-docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,49 +15,57 @@

set -euo pipefail

if [ "$#" -ne 1 ]; then
echo "Usage: $0 VERSION" >&2
exit 1
fi
source ./scripts/test_lib.sh

VERSION=${1}
VERSION=${1:-}
if [ -z "$VERSION" ]; then
echo "Usage: ${0} VERSION" >&2
exit 1
fi

ARCH=$(go env GOARCH)
VERSION="${VERSION}-${ARCH}"
DOCKERFILE="Dockerfile"
PLATFORMS=${2:-"linux/amd64,linux/arm64,linux/ppc64le,linux/s390x"}

if [ -z "${BINARYDIR:-}" ]; then
RELEASE="etcd-${1}"-$(go env GOOS)-${ARCH}
BINARYDIR="${RELEASE}"
TARFILE="${RELEASE}.tar.gz"
TARURL="https://github.com/etcd-io/etcd/releases/download/${1}/${TARFILE}"
if ! curl -f -L -o "${TARFILE}" "${TARURL}" ; then
echo "Failed to download ${TARURL}."
exit 1
fi
tar -zvxf "${TARFILE}"
if [ -n "${CI:-}" ]; then
docker run --privileged --rm tonistiigi/binfmt --install all
docker buildx create \
--name multiarch-multiplatform-builder \
--driver docker-container \
--bootstrap --use
fi

BINARYDIR=${BINARYDIR:-.}
BUILDDIR=${BUILDDIR:-.}

IMAGEDIR=${BUILDDIR}/image-docker

mkdir -p "${IMAGEDIR}"/var/etcd
mkdir -p "${IMAGEDIR}"/var/lib/etcd
cp "${BINARYDIR}"/etcd "${BINARYDIR}"/etcdctl "${BINARYDIR}"/etcdutl "${IMAGEDIR}"

cat ./"${DOCKERFILE}" > "${IMAGEDIR}"/Dockerfile
if [ -z "${REGISTRY:-}" ]; then
docker build --build-arg="VERSION=${VERSION}" \
--build-arg="BUILD_DIR=${BUILD_DIR}" \
--platform="${PLATFORMS}" \
-t "gcr.io/etcd-development/etcd:${VERSION}" \
-t "quay.io/coreos/etcd:${VERSION}" \
.
# we should deprecate publishing tags for specific architectures and use the multi-arch image
for arch in amd64 arm64 ppc64le s390x; do
log_callout "Building ${arch} docker image..."
docker build --build-arg="VERSION=${VERSION}" \
--build-arg="BUILD_DIR=${BUILD_DIR}" \
--platform="linux/${arch}" \
-t "gcr.io/etcd-development/etcd:${VERSION}-${arch}" \
-t "quay.io/coreos/etcd:${VERSION}-${arch}" \
.
done

if [ -z "${TAG:-}" ]; then
# Fix incorrect image "Architecture" using buildkit
# From https://stackoverflow.com/q/72144329/
DOCKER_BUILDKIT=1 docker build --build-arg="ARCH=${ARCH}" -t "gcr.io/etcd-development/etcd:${VERSION}" "${IMAGEDIR}"
DOCKER_BUILDKIT=1 docker build --build-arg="ARCH=${ARCH}" -t "quay.io/coreos/etcd:${VERSION}" "${IMAGEDIR}"
else
docker build -t "${TAG}:${VERSION}" "${IMAGEDIR}"
docker buildx build --build-arg="VERSION=${VERSION}" \
--build-arg="BUILD_DIR=${BUILD_DIR}" \
--platform="${PLATFORMS}" \
-t "${REGISTRY}/etcd:${VERSION}" \
--push \
.
# we should deprecate publishing tags for specific architectures and use the multi-arch image
for arch in amd64 arm64 ppc64le s390x; do
log_callout "Building ${arch} docker image..."
docker buildx build --build-arg="VERSION=${VERSION}" \
--build-arg="BUILD_DIR=${BUILD_DIR}" \
--platform="linux/${arch}" \
-t "${REGISTRY}/etcd:${VERSION}-${arch}" \
--push \
.
done
fi
26 changes: 20 additions & 6 deletions scripts/build-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,37 @@ source ./scripts/test_lib.sh

VERSION=${1:-}
if [ -z "${VERSION}" ]; then
echo "Usage: ${0} VERSION" >> /dev/stderr
exit 255
VERSION=$(git describe --tags --always --dirty)
fi

if ! command -v docker >/dev/null; then
echo "cannot find docker"
exit 1
fi

if [ -n "${CI:-}" ]; then
# there are few things missing in CI that we need to install
# busybox tar doesn't support some of the flags we need for reproducible builds
apk --no-cache add zip tar || true
fi

ETCD_ROOT=$(dirname "${BASH_SOURCE[0]}")/..

VERSION=$(git describe --tags --always --dirty)

pushd "${ETCD_ROOT}" >/dev/null
log_callout "Building etcd binary..."
./scripts/build-binary.sh "${VERSION}"

for TARGET_ARCH in "amd64" "arm64" "ppc64le" "s390x"; do
log_callout "Building ${TARGET_ARCH} docker image..."
GOOS=linux GOARCH=${TARGET_ARCH} BINARYDIR=release/etcd-${VERSION}-linux-${TARGET_ARCH} BUILDDIR=release ./scripts/build-docker.sh "${VERSION}"
done
BUILD_DIR=release ./scripts/build-docker.sh "${VERSION}"
find release -name '*.*' -type f -maxdepth 1 -exec sha256sum {} \; | sed "s~release/~~" > release/SHA256SUMS
if [ -n "${CI:-}" ]; then
# cloudbuild will copy contents of this folder to GCS
echo "Copying release artifacts to release/cloudbuild/${VERSION}"
mkdir -p "release/cloudbuild/${VERSION}"
cp release/SHA256SUMS release/cloudbuild/"${VERSION}"/SHA256SUMS
cp release/*.zip release/cloudbuild/"${VERSION}"/
cp release/*.tar.gz release/cloudbuild/"${VERSION}"/
gcloud storage cp --recursive "release/cloudbuild" "gs://${GCS_LOCATION}"
fi
popd >/dev/null
9 changes: 5 additions & 4 deletions scripts/build_lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ set -euo pipefail
source ./scripts/test_lib.sh

GIT_SHA=$(git rev-parse --short HEAD || echo "GitNotFound")
VERSION_SYMBOL="${ROOT_MODULE}/api/v3/version.GitSHA"
VERSIONSHA_SYMBOL="${ROOT_MODULE}/api/v3/version.GitSHA"
VERSION_SYMBOL="${ROOT_MODULE}/api/v3/version.Version"

# use go env if noset
GOOS=${GOOS:-$(go env GOOS)}
Expand All @@ -30,7 +31,7 @@ CGO_ENABLED="${CGO_ENABLED:-0}"

# Set GO_LDFLAGS="-s" for building without symbols for debugging.
# shellcheck disable=SC2206
GO_LDFLAGS=(${GO_LDFLAGS:-} "-X=${VERSION_SYMBOL}=${GIT_SHA}")
GO_LDFLAGS=(${GO_LDFLAGS:-} "-X=${VERSIONSHA_SYMBOL}=${GIT_SHA}" "-X=${VERSION_SYMBOL}=${VERSION:-"GitNotFound"}")
GO_BUILD_ENV=("CGO_ENABLED=${CGO_ENABLED}" "GO_BUILD_FLAGS=${GO_BUILD_FLAGS}" "GOOS=${GOOS}" "GOARCH=${GOARCH}")

etcd_build() {
Expand Down Expand Up @@ -106,9 +107,9 @@ tools_build() {
run_build() {
echo Running "$1"
if $1; then
log_success "SUCCESS: $1 (GOARCH=${GOARCH})"
log_success "SUCCESS: $1 (GOOS=${GOOS},GOARCH=${GOARCH})"
else
log_error "FAIL: $1 (GOARCH=${GOARCH})"
log_error "FAIL: $1 (GOOS=${GOOS},GOARCH=${GOARCH})"
exit 2
fi
}