linkerd2-proxy/justfile

333 lines
11 KiB
Makefile

# See https://just.systems/man/en
#
# Configuration
#
export RUST_BACKTRACE := env_var_or_default("RUST_BACKTRACE", "short")
# Use the dev environment's version of protoc.
export PROTOC_NO_VENDOR := "1"
# By default we compile in development mode mode because it's faster.
profile := if env_var_or_default("RELEASE", "") == "" { "debug" } else { "release" }
toolchain := ""
features := ""
export LINKERD2_PROXY_VERSION := env_var_or_default("LINKERD2_PROXY_VERSION", "0.0.0-dev" + `git rev-parse --short HEAD`)
export LINKERD2_PROXY_VENDOR := env_var_or_default("LINKERD2_PROXY_VENDOR", `whoami` + "@" + `hostname`)
# The version name to use for packages.
package_version := "v" + LINKERD2_PROXY_VERSION
# Docker image name & tag.
docker-repo := "localhost/linkerd/proxy"
docker-tag := `git rev-parse --abbrev-ref HEAD | sed 's|/|.|g'` + "." + `git rev-parse --short HEAD`
docker-image := docker-repo + ":" + docker-tag
# The architecture name to use for packages. Either 'amd64', 'arm64', or 'arm'.
arch := "amd64"
# The OS name to use for packages. Either 'linux' or 'windows'.
os := "linux"
libc := 'gnu'
# If a `arch` is specified, then we change the default cargo `--target`
# to support cross-compilation. Otherwise, we use `rustup` to find the default.
_target := if os + '-' + arch == "linux-amd64" {
"x86_64-unknown-linux-" + libc
} else if os + '-' + arch == "linux-arm64" {
"aarch64-unknown-linux-" + libc
} else if os + '-' + arch == "linux-arm" {
"armv7-unknown-linux-" + libc + "eabihf"
} else if os + '-' + arch == "windows-amd64" {
"x86_64-pc-windows-" + libc
} else {
error("unsupported: os=" + os + " arch=" + arch + " libc=" + libc)
}
_cargo := 'just-cargo profile=' + profile + ' target=' + _target + ' toolchain=' + toolchain
_target_dir := "target" / _target / profile
_target_bin := _target_dir / "linkerd2-proxy"
_package_name := "linkerd2-proxy-" + package_version + "-" + arch + (if libc == 'musl' { '-static' } else { '' }) + (if os == 'windows' { '.exe' } else { '' })
_package_dir := "target/package" / _package_name
shasum := "shasum -a 256"
_features := if features == "all" {
"--all-features"
} else if features != "" {
"--no-default-features --features=" + features
} else { "" }
wait-timeout := env_var_or_default("WAIT_TIMEOUT", "1m")
export CXX := 'clang++-19'
#
# Recipes
#
rustup:
@{{ _cargo }} _target-installed
# Run all lints
lint: sh-lint md-lint clippy doc action-lint action-dev-check
# Fetch dependencies
fetch:
@{{ _cargo }} fetch --locked
fmt:
@{{ _cargo }} fmt
# Fails if the code does not match the expected format (via rustfmt).
check-fmt:
@{{ _cargo }} fmt -- --check
check *flags:
@{{ _cargo }} check --workspace --all-targets --frozen {{ flags }}
check-crate crate *flags:
@{{ _cargo }} check --package={{ crate }} --all-targets --frozen {{ _features }} {{ flags }}
clippy *flags:
@{{ _cargo }} clippy --workspace --all-targets --frozen {{ _features }} {{ flags }}
clippy-crate crate *flags:
@{{ _cargo }} clippy --package={{ crate }} --all-targets --frozen {{ _features }} {{ flags }}
clippy-dir dir *flags:
cd {{ dir }} && {{ _cargo }} clippy --all-targets --frozen {{ _features }} {{ flags }}
doc *flags:
@{{ _cargo }} doc --no-deps --workspace --frozen {{ _features }} {{ flags }}
doc-crate crate *flags:
@{{ _cargo }} doc --package={{ crate }} --all-targets --frozen {{ _features }} {{ flags }}
# Build all tests
test-build *flags:
@{{ _cargo }} test-build --workspace --frozen {{ _features }} {{ flags }}
# Run all tests
test *flags:
@{{ _cargo }} test --workspace --frozen {{ _features }} {{ flags }}
test-crate crate *flags:
@{{ _cargo }} test --package={{ crate }} --frozen {{ _features }} {{ flags }}
test-dir dir *flags:
cd {{ dir }} && {{ _cargo }} test --frozen {{ _features }} {{ flags }}
# Build the proxy
# XXX(ver) checksec doesn't work when profile=debug, so skip it.
build: _build _strip
# Build the proxy without stripping debug symbols
build-debug: _build
_build:
@rm -f {{ _target_bin }} {{ _target_bin }}.dbg
@{{ _cargo }} build --frozen --package=linkerd2-proxy {{ _features }}
_strip:
{{ _objcopy }} --only-keep-debug {{ _target_bin }} {{ _target_bin }}.dbg
{{ _objcopy }} --strip-unneeded {{ _target_bin }}
{{ _objcopy }} --add-gnu-debuglink={{ _target_bin }}.dbg {{ _target_bin }}
_package_bin := _package_dir / "bin" / "linkerd2-proxy"
# XXX {aarch64,arm}-musl builds do not enable PIE, so we use target-specific
# files to document those differences.
_expected_checksec := '.checksec' / arch + '-' + libc + '.json'
# Check the security properties of the proxy binary.
checksec:
checksec --output=json --file='{{ _target_bin }}' \
| jq '.' | tee /dev/stderr \
| jq -S '.[] | del(."fortify_source") | del(."fortify-able") | del(.fortified) | del(.symbols)' \
| diff -u {{ _expected_checksec }} - >&2
_objcopy := 'llvm-objcopy-' + `just-cargo --evaluate _llvm-version`
# Build a package (i.e. for a release)
package: build
@mkdir -p {{ _package_dir }}/bin
cp LICENSE {{ _package_dir }}/
cp {{ _target_bin }} {{ _target_bin }}.dbg {{ _package_dir }}/
tar -czvf target/package/{{ _package_name }}.tar.gz -C target/package {{ _package_name }} >/dev/null
cd target/package && ({{ shasum }} {{ _package_name }}.tar.gz | tee {{ _package_name }}.txt)
@rm -rf {{ _package_dir }}
@du -h target/package/{{ _package_name }}.tar.gz
@tar tzvf target/package/{{ _package_name }}.tar.gz
# Build all of the fuzzers (SLOW).
fuzzers:
#!/usr/bin/env bash
set -euo pipefail
if [ "{{ toolchain }}" != "nightly" ]; then
echo "fuzzers must be run with nightly" >&2
exit 1
fi
for dir in $(find ./linkerd -type d -name fuzz); do
echo "cd $dir && cargo +nightly fuzz build"
( cd $dir ; cargo +nightly fuzz build \
{{ if profile == "release" { "--release" } else { "" } }} )
done
export DOCKER_BUILDX_CACHE_DIR := env_var_or_default('DOCKER_BUILDX_CACHE_DIR', '')
# Build a docker image (FOR TESTING ONLY)
docker *args='--output=type=docker': && _clean-cache
docker buildx build . \
--pull \
--tag={{ docker-image }} \
--build-arg PROFILE='{{ profile }}' \
--build-arg LINKERD2_PROXY_VENDOR='{{ LINKERD2_PROXY_VENDOR }}' \
--build-arg LINKERD2_PROXY_VERSION='{{ LINKERD2_PROXY_VERSION }}' \
--no-cache-filter=runtime \
{{ if linkerd-tag == '' { '' } else { '--build-arg=RUNTIME_IMAGE=ghcr.io/linkerd/proxy:' + linkerd-tag } }} \
{{ if features != "" { "--build-arg PROXY_FEATURES=" + features } else { "" } }} \
{{ if DOCKER_BUILDX_CACHE_DIR == '' { '' } else { '--cache-from=type=local,src=' + DOCKER_BUILDX_CACHE_DIR + ' --cache-to=type=local,dest=' + DOCKER_BUILDX_CACHE_DIR } }} \
{{ args }}
_clean-cache:
@{{ if DOCKER_BUILDX_CACHE_DIR == '' { 'true' } else { 'just-dev prune-action-cache ' + DOCKER_BUILDX_CACHE_DIR } }}
# Lints all shell scripts in the repo.
sh-lint:
@just-sh
md-lint:
@just-md
# Lints all GitHub Actions workflows
action-lint:
@just-dev lint-actions
action-dev-check:
#!/usr/bin/env bash
# TODO(ver) consolidate this again with just-dev
#@just-dev check-action-images
set -euo pipefail
VERSION=$(j5j .devcontainer/devcontainer.json |jq -r '.build.args["DEV_VERSION"]')
EX=0
while IFS= read filelineimg ; do
# Parse lines in the form `file:line img:tag`
fileline="${filelineimg%% *}"
file="${fileline%%:*}"
line="${fileline##*:}"
img="${filelineimg##* }"
name="${img%%:*}"
# Tag may be in the form of `version[-variant]`
tag="${img##*:}"
version="${tag%%-*}"
if [ "$name" = 'ghcr.io/linkerd/dev' ] && [ "$version" != "$VERSION" ]; then
if [ "${GITHUB_ACTIONS:-}" = "true" ]; then
echo "::error file=${file},line=${line}::Expected image 'ghcr.io/linkerd/dev:$VERSION'; found '${img}'" >&2
else
echo "${file}:${line}: Expected image 'ghcr.io/linkerd/dev:$VERSION'; found '${img}'" >&2
fi
EX=$(( EX+1 ))
fi
done < <( /usr/local/bin/action-images )
exit $EX
##
## Linkerd
##
linkerd-tag := env_var_or_default('LINKERD_TAG', '')
_controller-image := 'ghcr.io/linkerd/controller'
_policy-image := 'ghcr.io/linkerd/policy-controller'
_init-image := 'ghcr.io/linkerd/proxy-init'
_init-tag := 'v2.4.0'
_kubectl := 'just-k3d kubectl'
_linkerd := 'linkerd --context=k3d-$(just-k3d --evaluate K3D_CLUSTER_NAME)'
_tag-set:
#!/usr/bin/env bash
if [ -z '{{ linkerd-tag }}' ]; then
echo "linkerd-tag must be set" >&2
exit 1
fi
_k3d-ready:
@just-k3d ready
k3d-load-linkerd: _tag-set _k3d-ready
for i in \
'{{ _controller-image }}:{{ linkerd-tag }}' \
'{{ _policy-image }}:{{ linkerd-tag }}' \
'{{ _init-image }}:{{ _init-tag }}' \
; do \
docker pull -q "$i" ; \
done
@just-k3d import \
'{{ docker-image }}' \
'{{ _controller-image }}:{{ linkerd-tag }}' \
'{{ _policy-image }}:{{ linkerd-tag }}' \
'{{ _init-image }}:{{ _init-tag }}'
# Install crds on the test cluster.
_linkerd-crds-install: _k3d-ready
{{ _linkerd }} install --crds \
| {{ _kubectl }} apply -f -
{{ _kubectl }} wait crd --for condition=established \
--selector='linkerd.io/control-plane-ns' \
--timeout={{ wait-timeout }}
# Install linkerd on the test cluster using test images.
linkerd-install *args='': _tag-set k3d-load-linkerd _linkerd-crds-install && _linkerd-ready
{{ _linkerd }} install \
--set='imagePullPolicy=Never' \
--set='controllerImage={{ _controller-image }}' \
--set='linkerdVersion={{ linkerd-tag }}' \
--set='policyController.image.name={{ _policy-image }}' \
--set='policyController.image.version={{ linkerd-tag }}' \
--set='proxy.image.name={{ docker-repo }}' \
--set='proxy.image.version={{ docker-tag }}' \
--set='proxy.logLevel=linkerd=debug\,info' \
--set='proxyInit.image.name={{ _init-image }}' \
--set='proxyInit.image.version={{ _init-tag }}' \
{{ args }} \
| {{ _kubectl }} apply -f -
linkerd-uninstall:
{{ _linkerd }} uninstall \
| {{ _kubectl }} delete -f -
linkerd-check-control-plane-proxy:
#!/usr/bin/env bash
set -euo pipefail
check=$(mktemp --tmpdir check-XXXX.json)
{{ _linkerd }} check -o json > "$check"
result=$(jq -r \
'.categories[] | select(.categoryName == "linkerd-control-plane-proxy") | .checks[] | select(.description == "control plane proxies are healthy") | .result' \
"$check")
if [ "$result" != "success" ]; then
jq '.categories[] | .checks[] | select(.result != "success") | select(.hint | contains("-version") | not)' \
"$check" >&2
{{ _kubectl }} describe po -n linkerd >&2
exit 1
fi
rm "$check"
_linkerd-ready:
{{ _kubectl }} wait pod --for=condition=ready \
--namespace=linkerd --selector='linkerd.io/control-plane-component' \
--timeout={{ wait-timeout }}
#
# Dev Container
#
devcontainer-up:
devcontainer.js up --workspace-folder=.
devcontainer-exec container-id *args:
devcontainer.js exec --container-id={{ container-id }} {{ args }}