Commit 748966bf authored by Matt Smiley's avatar Matt Smiley Committed by Jacob Vosmaer

Add Gnu build-id to workhorse go binaries

By default, go binaries currently include only a
Go build-id, but it is also useful to include a
Gnu build-id.

Providing a Gnu build-id in a binary enables more robust
support for Gnu profiling, tracing, and debugging tools.
For example, it prevents an ugly scenario where the wrong
symbols are used when analyzing a profile that was captured
prior to a recent install of that binary.

Like all build-ids, the Gnu build-id must be unique.
Ideally it should also be deterministic, as that supports
repeatable builds, which in turn enable supply chain integrity
validation, equivalency testing, etc.

The Go build-id has both properties: unique and deterministic.
Here we generate a Gnu build-id based on the Go build-id,
inheriting those 2 properties.

We hope to make this an automatic behavior of go build in the
future, reducing overhead and risk.  But for now, this approach
approximates the required certainty of uniqueness (including
differentiating between builds that use the same source code
but different versions of go or statically linked libraries).
parent 7eb3c90b
......@@ -12,7 +12,7 @@ ifdef SOURCE_DATE_EPOCH
else
BUILD_TIME := $(shell date -u "$(DATE_FMT)")
endif
GOBUILD := go build -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)"
GO_BUILD_GENERIC_LDFLAGS := -X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)
GITALY := tmp/tests/gitaly/_build/bin/gitaly
GITALY_PID_FILE := gitaly.pid
EXE_ALL := gitlab-resize-image gitlab-zip-cat gitlab-zip-metadata gitlab-workhorse
......@@ -30,31 +30,35 @@ define message
@echo "### $(1)"
endef
# To compute a unique and deterministic value for GNU build-id, we build the Go binary a second time.
# From the first build, we extract its unique and deterministic Go build-id, and use that to derive
# a comparably unique and deterministic GNU build-id to inject into the final binary.
# If we cannot extract a Go build-id, we punt and fallback to using a random 32-byte hex string.
# This fallback is unique but non-deterministic. Uniqueness is critical, because the GNU build-id
# can be used as a cache key in a build cache. Without the fallback, we risk cache key collisions.
## Skip generation of the GNU build ID if set to speed up builds.
WITHOUT_BUILD_ID ?=
.NOTPARALLEL:
.PHONY: all
all: clean-build $(EXE_ALL)
.PHONY: gitlab-resize-image
gitlab-resize-image:
.PHONY: gitlab-resize-image gitlab-zip-cat gitlab-zip-metadata
gitlab-resize-image gitlab-zip-cat gitlab-zip-metadata:
$(call message,Building $@)
$(GOBUILD) -tags "$(BUILD_TAGS)" -o $(BUILD_DIR)/$@ $(PKG)/cmd/$@
.PHONY: gitlab-zip-cat
gitlab-zip-cat:
$(call message,Building $@)
$(GOBUILD) -tags "$(BUILD_TAGS)" -o $(BUILD_DIR)/$@ $(PKG)/cmd/$@
.PHONY: gitlab-zip-metadata
gitlab-zip-metadata:
$(call message,Building $@)
$(GOBUILD) -tags "$(BUILD_TAGS)" -o $(BUILD_DIR)/$@ $(PKG)/cmd/$@
go build -ldflags "$(GO_BUILD_GENERIC_LDFLAGS)" -tags "$(BUILD_TAGS)" -o $(BUILD_DIR)/$@ $(PKG)/cmd/$@
ifndef WITHOUT_BUILD_ID
go build -ldflags "$(GO_BUILD_GENERIC_LDFLAGS) -B 0x$$(_support/make-gnu-build-id.sh $(BUILD_DIR)/$@)" -tags "$(BUILD_TAGS)" -o $(BUILD_DIR)/$@ $(PKG)/cmd/$@
endif
.PHONY: gitlab-workhorse
gitlab-workhorse:
$(call message,Building $@)
$(GOBUILD) -tags "$(BUILD_TAGS)" -o $(BUILD_DIR)/$@ $(PKG)
go build -ldflags "$(GO_BUILD_GENERIC_LDFLAGS)" -tags "$(BUILD_TAGS)" -o $(BUILD_DIR)/$@ $(PKG)
ifndef WITHOUT_BUILD_ID
go build -ldflags "$(GO_BUILD_GENERIC_LDFLAGS) -B 0x$$(_support/make-gnu-build-id.sh $(BUILD_DIR)/$@)" -tags "$(BUILD_TAGS)" -o $(BUILD_DIR)/$@ $(PKG)
endif
.PHONY: install
install: $(EXE_ALL)
......
#!/bin/sh
main()
{
GO_BINARY=$1
if [ $# -ne 1 ] || [ ! -f $GO_BINARY ] ; then
fail "Usage: $0 [path_to_go_binary]"
fi
GO_BUILD_ID=$( go tool buildid "$GO_BINARY" || openssl rand -hex 32 )
if [ -z "$GO_BUILD_ID" ] ; then
fail "ERROR: Could not extract Go build-id or generate a random hex string."
fi
GNU_BUILD_ID=$( echo $GO_BUILD_ID | sha1sum | cut -d' ' -f1 )
if [ -z "$GNU_BUILD_ID" ] ; then
fail "ERROR: Could not generate a GNU build-id"
fi
echo "$GNU_BUILD_ID"
}
fail()
{
echo "$@" 1>&2
exit 1
}
main "$@"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment