Files
teleport/Makefile
T
Tiago Silva fb98c980ec Add enum value rendering to CLI docs and remove duplicate descriptions (#66466)
This commit enhances the CLI reference documentation by automatically
displaying valid enum values in the "Default" column of flag tables,
eliminating the need to manually list these values in flag descriptions.
It also adds a CI step to verify that CLI reference docs stay in sync
with source code changes.

The core implementation uses reflection to extract enum values from
kingpin flags and formats them as "(valid: `value1`, `value2`, ...)".
All CLI source files have been updated to remove duplicate enum value
lists from flag help text, as these are now automatically rendered.

A new 'cli-docs-up-to-date' Makefile target and corresponding GitHub
Actions workflow job ensure that any changes to CLI flags are reflected
in the generated documentation.

Example output:
Before: |`--format`|`yaml`|Output format, 'yaml', 'json', or 'text'|
After:  |`--format`|`yaml` (valid: `yaml`, `json`, `text`)|Output format.|

Signed-off-by: Tiago Silva <tiago.silva@goteleport.com>
2026-05-08 13:53:15 +00:00

2122 lines
77 KiB
Makefile

# Make targets:
#
# all : builds all binaries in development mode
# full : builds all binaries for PRODUCTION use
# release: prepares a release tarball
# clean : removes all build artifacts
# test : runs tests
.DEFAULT_GOAL := all
# To update the Teleport version, update VERSION variable:
# Naming convention:
# Stable releases: "1.0.0"
# Pre-releases: "1.0.0-alpha.1", "1.0.0-beta.2", "1.0.0-rc.3"
# Master/dev branch: "1.0.0-dev"
VERSION=19.0.0-prealpha.2
DOCKER_IMAGE ?= teleport
# This directory will be the real path of the directory of the first Makefile in the list.
MAKE_DIR := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))
# If set to 1, webassets are not built.
WEBASSETS_SKIP_BUILD ?= 0
# These are standard autotools variables, don't change them please
ifneq ("$(wildcard /bin/bash)","")
SHELL := /bin/bash -o pipefail
endif
BUILDDIR ?= build
BINDIR ?= /usr/local/bin
DATADIR ?= /usr/local/share/teleport
ADDFLAGS ?=
PWD ?= $(shell pwd)
TELEPORT_DEBUG ?= false
GITTAG=v$(VERSION)
CGOFLAG ?= CGO_ENABLED=1
KUSTOMIZE_NO_DYNAMIC_PLUGIN ?= kustomize_disable_go_plugin_support
KUBECTL_VERSION := $(shell go list -m -f '{{.Version}}' k8s.io/kubectl | sed 's/v0/v1/')
KUBECTL_SETVERSION := -X k8s.io/component-base/version.gitVersion=$(KUBECTL_VERSION)
# RELEASE_DIR is where the release artifacts (tarballs, pacakges, etc) are put. It
# should be an absolute directory as it is used by e/Makefile too, from the e/ directory.
RELEASE_DIR := $(CURDIR)/$(BUILDDIR)/artifacts
GO_LDFLAGS ?= -w -s $(KUBECTL_SETVERSION)
# Appending new conditional settings for community build type
# When TELEPORT_DEBUG is true, set flags to produce
# debugger-friendly builds.
ifeq ("$(TELEPORT_DEBUG)","true")
BUILDFLAGS ?= $(ADDFLAGS) -gcflags=all="-N -l" -buildvcs=false
BUILDFLAGS_TBOT ?= $(ADDFLAGS) -gcflags=all="-N -l" -buildvcs=false
BUILDFLAGS_TELEPORT_UPDATE ?= $(ADDFLAGS) -gcflags=all="-N -l" -buildvcs=false
else
BUILDFLAGS ?= $(ADDFLAGS) -ldflags '$(GO_LDFLAGS)' -trimpath -buildvcs=false
BUILDFLAGS_TBOT ?= $(ADDFLAGS) -ldflags '$(GO_LDFLAGS)' -trimpath -buildvcs=false
BUILDFLAGS_TELEPORT_UPDATE ?= $(ADDFLAGS) -ldflags '$(GO_LDFLAGS)' -trimpath -buildvcs=false
endif
GO_ENV_OS := $(shell go env GOOS)
OS ?= $(GO_ENV_OS)
GO_ENV_ARCH := $(shell go env GOARCH)
ARCH ?= $(GO_ENV_ARCH)
FIPS ?=
RELEASE = teleport-$(GITTAG)-$(OS)-$(ARCH)-bin
RELEASE_TOOLS = teleport-tools-$(GITTAG)-$(OS)-$(ARCH)-bin
RELEASE_UPDATE = teleport-update-$(GITTAG)-$(OS)-$(ARCH)-bin
# If we're building inside the cross-compiling buildbox, include the
# cross compilation definitions so we select the correct compilers and
# libraries.
ifeq ($(BUILDBOX_MODE),cross)
include build.assets/buildbox/cross-compile.mk
endif
# Include common makefile shared between OSS and Ent.
include common.mk
# FIPS support must be requested at build time.
FIPS_MESSAGE := without-FIPS-support
ifneq ("$(FIPS)","")
FIPS_TAG := fips
FIPS_MESSAGE := with-FIPS-support
RELEASE = teleport-$(GITTAG)-$(OS)-$(ARCH)-fips-bin
GOEXPERIMENT = boringcrypto
export GOEXPERIMENT
ifeq ($(BUILDBOX_MODE),cross)
# We need to set CGO_ENABLED=0 when building rdpclient as the build of
# boring-sys builds and runs a Go program as part of its integrity testing.
# (https://github.com/google/boringssl/blob/master/crypto/fipsmodule/FIPS.md#integrity-testing)
# If CGO_ENABLED=1, this fails for odd reasons (it tries to use the cross
# assembler to build ASM for the host).
# It also needs to know the cross-compiler sysroot to properly cross-compile.
RDPCLIENT_ENV = CGO_ENABLED=0 BORING_BSSL_FIPS_SYSROOT=$(CROSSTOOLNG_SYSROOT)
endif
endif
# Look for the PAM header "security/pam_appl.h" to determine if we should
# enable PAM support in teleport. A native build will have it in /usr/include.
# Darwin has it in /usr/local/include (SIP prevents us from modifying/creating
# it in /usr/include), and the ng buildbox has it in one of the
# $(C_INCLUDE_PATH) paths.
PAM_HEADER_CANDIDATES := $(subst :, ,$(C_INCLUDE_PATH)) /usr/local/include /usr/include
PAM_MESSAGE := without-PAM-support
ifneq (,$(wildcard $(addsuffix /security/pam_appl.h,$(PAM_HEADER_CANDIDATES))))
PAM_TAG := pam
PAM_MESSAGE := with-PAM-support
endif
# darwin universal (Intel + Apple Silicon combined) binary support
RELEASE_darwin_arm64 = $(RELEASE_DIR)/teleport-$(GITTAG)-darwin-arm64-bin.tar.gz
RELEASE_darwin_amd64 = $(RELEASE_DIR)/teleport-$(GITTAG)-darwin-amd64-bin.tar.gz
BUILDDIR_arm64 = $(BUILDDIR)/arm64
BUILDDIR_amd64 = $(BUILDDIR)/amd64
# TARBINS is the path of the binaries in the release tarballs
TARBINS = $(addprefix teleport/,$(BINS))
# Check if rust and cargo are installed before compiling
CHECK_CARGO := $(shell cargo --version 2>/dev/null)
CHECK_RUST := $(shell rustc --version 2>/dev/null)
RUST_TARGET_ARCH ?= $(CARGO_TARGET_$(OS)_$(ARCH))
CARGO_TARGET_darwin_amd64 := x86_64-apple-darwin
CARGO_TARGET_darwin_arm64 := aarch64-apple-darwin
CARGO_TARGET_linux_arm := arm-unknown-linux-gnueabihf
CARGO_TARGET_linux_arm64 := aarch64-unknown-linux-gnu
CARGO_TARGET_linux_386 := i686-unknown-linux-gnu
CARGO_TARGET_linux_amd64 := x86_64-unknown-linux-gnu
CARGO_TARGET_windows_amd64 := x86_64-pc-windows-gnu
CARGO_TARGET := --target=$(RUST_TARGET_ARCH)
CARGO_WASM_TARGET := wasm32-unknown-unknown
# If set to 1, then we don't build the desktop access RDP client
# or the RDP decoder for tsh.
RDPCLIENT_SKIP_BUILD ?= 0
# Enable Rust RDP support?
with_rdpclient := no
RDPCLIENT_MESSAGE := without-Windows-RDP-client
ifeq ($(RDPCLIENT_SKIP_BUILD),0)
ifneq ($(CHECK_RUST),)
ifneq ($(CHECK_CARGO),)
is_fips_on_arm64 := no
ifneq ("$(FIPS)","")
ifeq ("$(ARCH)","arm64")
is_fips_on_arm64 := yes
endif
endif
# Do not build RDP client on 32-bit ARM or 386, or for FIPS builds on arm64.
ifneq ("$(ARCH)","arm")
ifneq ("$(ARCH)","386")
ifneq ("$(is_fips_on_arm64)","yes")
with_rdpclient := yes
RDPCLIENT_MESSAGE := with-Windows-RDP-client
RDPCLIENT_TAG := desktop_access_rdp
TSH_RDP_DECODER_TAG := rust_rdp_decoder
endif
endif
endif
endif
endif
endif
# Set C_ARCH for building libfido2 and dependencies. ARCH is the Go
# architecture which uses different names for architectures than C
# uses. Export it for the build.assets/build-fido2-macos.sh script.
C_ARCH_amd64 = x86_64
C_ARCH = $(or $(C_ARCH_$(ARCH)),$(ARCH))
export C_ARCH
# Enable libfido2 for testing?
# Eagerly enable if we detect the package, we want to test as much as possible.
ifeq ("$(shell pkg-config libfido2 2>/dev/null; echo $$?)", "0")
LIBFIDO2_TEST_TAG := libfido2
ifeq ($(FIDO2),)
FIDO2 ?= dynamic
endif
endif
# Build tsh against libfido2?
# FIDO2=yes and FIDO2=static enable static libfido2 builds.
# FIDO2=dynamic enables dynamic libfido2 builds.
LIBFIDO2_MESSAGE := without-libfido2
ifneq (, $(filter $(FIDO2), yes static))
LIBFIDO2_MESSAGE := with-libfido2
LIBFIDO2_BUILD_TAG := libfido2 libfido2static
else ifeq ("$(FIDO2)", "dynamic")
LIBFIDO2_MESSAGE := with-libfido2
LIBFIDO2_BUILD_TAG := libfido2
endif
# Enable Touch ID builds?
# Only build if TOUCHID=yes to avoid issues when cross-compiling to 'darwin'
# from other systems.
TOUCHID_MESSAGE := without-Touch-ID
ifeq ("$(TOUCHID)", "yes")
TOUCHID_MESSAGE := with-Touch-ID
TOUCHID_TAG := touchid
endif
# Enable VNet daemon?
# With VNETDAEMON=yes, tsh uses a Launch Daemon to start VNet.
# This requires a signed and bundled tsh.
VNETDAEMON_MESSAGE := without-VNet-daemon
ifeq ("$(VNETDAEMON)", "yes")
VNETDAEMON_MESSAGE := with-VNet-daemon
VNETDAEMON_TAG := vnetdaemon
endif
# Enable PIV test packages for testing.
# This test tag should never be used for builds/releases, only tests.
PIV_TEST_TAG := pivtest
# enable PIV package for linting.
PIV_LINT_TAG := piv
# Build teleport/api with PIV? This requires the libpcsclite library for linux.
#
# PIV=yes and PIV=static enable static piv builds. This is used by the build
# process to link a static library of libpcsclite for piv-go to connect to.
#
# PIV=dynamic enables dynamic piv builds. This can be used for local
# builds and runs utilizing a dynamic libpcsclite library - `apt get install libpcsclite-dev`
PIV_MESSAGE := without-PIV-support
ifneq (, $(filter $(PIV), yes static dynamic))
PIV_MESSAGE := with-PIV-support
PIV_BUILD_TAG := piv
ifneq ("$(PIV)", "dynamic")
# Link static pcsc libary. By default, piv-go will look for the dynamic library.
# https://github.com/go-piv/piv-go/blob/master/piv/pcsc_unix.go#L23
STATIC_LIBS += -lpcsclite
STATIC_LIBS_TSH += -lpcsclite
endif
endif
SESSIONHELPER_EMBED_TAG :=
SESSIONHELPER_MESSAGE := without-session-helper
ifeq ($(OS),linux)
SESSIONHELPER_EMBED_TAG = sessionhelper_embed
SESSIONHELPER_MESSAGE := with-session-helper
endif
# Reproducible builds are only available on select targets, and only when OS=linux.
REPRODUCIBLE ?=
ifneq ("$(OS)","linux")
REPRODUCIBLE = no
endif
# On Windows only build tsh. On all other platforms build teleport, tctl,
# and tsh.
BINS_default = teleport tctl tsh tbot fdpass-teleport teleport-update
BINS_darwin = teleport tctl tsh tbot fdpass-teleport
BINS_windows = tsh tctl
BINS = $(or $(BINS_$(OS)),$(BINS_default))
BINARIES = $(addprefix $(BUILDDIR)/,$(BINS))
UPDATE_BINARIES = $(addprefix $(BUILDDIR)/,teleport-update)
# Joins elements of the list in arg 2 with the given separator.
# 1. Element separator.
# 2. The list.
EMPTY :=
SPACE := $(EMPTY) $(EMPTY)
join-with = $(subst $(SPACE),$1,$(strip $2))
# Separate TAG messages into comma-separated WITH and WITHOUT lists for readability.
COMMA := ,
MESSAGES := $(PAM_MESSAGE) $(FIPS_MESSAGE) $(BPF_MESSAGE) $(RDPCLIENT_MESSAGE) $(LIBFIDO2_MESSAGE) $(TOUCHID_MESSAGE) $(PIV_MESSAGE) $(VNETDAEMON_MESSAGE) $(SESSIONHELPER_MESSAGE)
WITH := $(subst -," ",$(call join-with,$(COMMA) ,$(subst with-,,$(filter with-%,$(MESSAGES)))))
WITHOUT := $(subst -," ",$(call join-with,$(COMMA) ,$(subst without-,,$(filter without-%,$(MESSAGES)))))
RELEASE_MESSAGE := "Building with GOOS=$(OS) GOARCH=$(ARCH) REPRODUCIBLE=$(REPRODUCIBLE) and with $(WITH) and without $(WITHOUT)."
# On platforms that support reproducible builds, ensure the archive is created in a reproducible manner.
TAR_FLAGS ?=
ifeq ("$(REPRODUCIBLE)","yes")
TAR_FLAGS = --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2015-03-02' --format=gnu
endif
VERSRC = gitref.go api/version.go
KUBECONFIG ?=
TEST_KUBE ?=
export
# This unexport statement is required for make to work with the `-e` flag.
# With -e, the first Makefile sets HELMJANITOR=$$(go tool ...),
# passes HELMJANITOR=$(go tool) to the child make process.
# Because of the `-e` flag it takes precedence over the child's make definition
# of HELMJANITOR and breaks environment variable expansion.
# To avoid breaking other parts of the release pipeline, the easiest fix is to
# unexport HELMJANITOR so the child uses the definition from its Makefile.
unexport HELMJANITOR
export KUBECONFIG
export TEST_KUBE
TEST_LOG_DIR ?= ${abspath ./test-logs}
# Set CGOFLAG and BUILDFLAGS as needed for the OS/ARCH.
ifeq ("$(OS)","linux")
ifeq ("$(ARCH)","arm64")
ifneq ($(BUILDBOX_MODE),cross)
ifeq (,$(IS_NATIVE_BUILD))
CGOFLAG += CC=aarch64-linux-gnu-gcc
endif
endif
else ifeq ("$(ARCH)","arm")
CGOFLAG = CGO_ENABLED=1
# ARM builds need to specify the correct C compiler
ifneq ($(BUILDBOX_MODE),cross)
ifeq (,$(IS_NATIVE_BUILD))
CC=arm-linux-gnueabihf-gcc
endif
endif
# Add -debugtramp=2 to work around 24 bit CALL/JMP instruction offset.
# Add "-extldflags -Wl,--long-plt" to avoid ld assertion failure on large binaries
GO_LDFLAGS += -extldflags=-Wl,--long-plt -debugtramp=2
endif
endif # OS == linux
ifeq ("$(OS)-$(ARCH)","darwin-arm64")
# Temporary link flags due to changes in Apple's linker
# https://github.com/golang/go/issues/67854
GO_LDFLAGS += -extldflags=-ld_classic
endif
# Windows requires extra parameters to cross-compile with CGO.
ifeq ("$(OS)","windows")
ARCH ?= amd64
ifneq ("$(ARCH)","amd64")
$(error "Building for windows requires ARCH=amd64")
endif
CGOFLAG = CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++
BUILDFLAGS = $(ADDFLAGS) -ldflags '-w -s $(KUBECTL_SETVERSION)' -trimpath -buildvcs=false
BUILDFLAGS_TBOT = $(ADDFLAGS) -ldflags '-w -s $(KUBECTL_SETVERSION)' -trimpath -buildvcs=false
BUILDFLAGS_TELEPORT_UPDATE = $(ADDFLAGS) -ldflags '-w -s $(KUBECTL_SETVERSION)' -trimpath -buildvcs=false
endif
ifeq ("$(OS)","darwin")
# Set the minimum version for macOS builds for Go, Rust and Xcode builds.
# (as of Go 1.25 we require macOS 12)
MINIMUM_SUPPORTED_MACOS_VERSION = 12.0
MACOSX_VERSION_MIN_FLAG = -mmacosx-version-min=$(MINIMUM_SUPPORTED_MACOS_VERSION)
# Go
CGOFLAG = CGO_ENABLED=1 CGO_CFLAGS=$(MACOSX_VERSION_MIN_FLAG)
# Xcode and rust and Go linking
MACOSX_DEPLOYMENT_TARGET = $(MINIMUM_SUPPORTED_MACOS_VERSION)
export MACOSX_DEPLOYMENT_TARGET
endif
CGOFLAG_TSH ?= $(CGOFLAG)
# Map ARCH into the architecture flag for electron-builder if they
# are different to the Go $(ARCH) we use as an input.
ELECTRON_BUILDER_ARCH_amd64 = x64
ELECTRON_BUILDER_ARCH = $(or $(ELECTRON_BUILDER_ARCH_$(ARCH)),$(ARCH))
#
# 'make all' builds all 4 executables and places them in the current directory.
#
# NOTE: Works the same as `make`. Left for legacy reasons.
.PHONY: all
all: version
@echo "---> Building OSS binaries."
$(MAKE) $(BINARIES)
#
# make binaries builds all binaries defined in the BINARIES environment variable
#
.PHONY: binaries
binaries: $(BINARIES)
# Appending new conditional settings for community build type for tools.
ifeq ("$(GITHUB_REPOSITORY_OWNER)","gravitational")
# TELEPORT_LDFLAGS and TOOLS_LDFLAGS if appended will overwrite the previous LDFLAGS set in the BUILDFLAGS.
# This is done here to prevent any changes to the (BUI)LDFLAGS passed to the other binaries
TELEPORT_LDFLAGS ?= -ldflags '$(GO_LDFLAGS) -X github.com/gravitational/teleport/lib/modules.teleportBuildType=community'
TOOLS_LDFLAGS ?= -ldflags '$(GO_LDFLAGS) $(KUBECTL_SETVERSION) -X github.com/gravitational/teleport/lib/modules.teleportBuildType=community'
endif
# By making these 3 targets below (tsh, tctl and teleport) PHONY we are solving
# several problems:
# * Build will rely on go build internal caching https://golang.org/doc/go1.10 at all times
# * Manual change detection was broken on a large dependency tree
# If you are considering changing this behavior, please consult with dev team first
#
# NOTE: Any changes to the `tctl` build here must be copied to `build.assets/windows/build.ps1`
# until we can use this Makefile for native Windows builds.
.PHONY: $(BUILDDIR)/tctl
$(BUILDDIR)/tctl:
@if [[ "$(OS)" != "windows" && -z "$(LIBFIDO2_BUILD_TAG)" ]]; then \
echo 'Warning: Building tctl without libfido2. Install libfido2 to have access to MFA.' >&2; \
fi
GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG) go build -tags "grpcnotrace $(PAM_TAG) $(FIPS_TAG) $(LIBFIDO2_BUILD_TAG) $(TOUCHID_TAG) $(PIV_BUILD_TAG) $(KUSTOMIZE_NO_DYNAMIC_PLUGIN)" -o $(BUILDDIR)/tctl $(BUILDFLAGS) $(TOOLS_LDFLAGS) ./tool/tctl
.PHONY: $(BUILDDIR)/teleport
$(BUILDDIR)/teleport: ensure-webassets rdpclient session/reexec/embed/sessionhelper
GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG) go build -tags "grpcnotrace webassets_embed $(PAM_TAG) $(FIPS_TAG) $(BPF_TAG) $(SESSIONHELPER_EMBED_TAG) $(WEBASSETS_TAG) $(RDPCLIENT_TAG) $(PIV_BUILD_TAG) $(KUSTOMIZE_NO_DYNAMIC_PLUGIN)" -o $(BUILDDIR)/teleport $(BUILDFLAGS) $(TELEPORT_LDFLAGS) ./tool/teleport
.PHONY: $(BUILDDIR)/sessionhelper
$(BUILDDIR)/sessionhelper:
ifneq ($(SESSIONHELPER_EMBED_TAG),)
GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG) go -C session build -buildvcs=false -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG) gravitational_trace.nocrypto" -o '$(abspath $(BUILDDIR)/sessionhelper)' $(BUILDFLAGS) ./cmd/sessionhelper
endif
.PHONY: session/reexec/embed/sessionhelper
session/reexec/embed/sessionhelper: $(BUILDDIR)/sessionhelper
ifneq ($(SESSIONHELPER_EMBED_TAG),)
mkdir -p session/reexec/embed
gzip -9 -n < '$(BUILDDIR)/sessionhelper' > 'session/reexec/embed/sessionhelper_$(OS)_$(ARCH).gz'
endif
# NOTE: Any changes to the `tsh` build here must be copied to `build.assets/windows/build.ps1`
# until we can use this Makefile for native Windows builds.
.PHONY: $(BUILDDIR)/tsh
$(BUILDDIR)/tsh: rdpdecoder
@if [[ "$(OS)" != "windows" && -z "$(LIBFIDO2_BUILD_TAG)" ]]; then \
echo 'Warning: Building tsh without libfido2. Install libfido2 to have access to MFA.' >&2; \
fi
GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG_TSH) go build -tags "grpcnotrace $(FIPS_TAG) $(LIBFIDO2_BUILD_TAG) $(TOUCHID_TAG) $(PIV_BUILD_TAG) $(VNETDAEMON_TAG) $(TSH_RDP_DECODER_TAG) $(KUSTOMIZE_NO_DYNAMIC_PLUGIN)" -o $(BUILDDIR)/tsh $(BUILDFLAGS) $(TOOLS_LDFLAGS) ./tool/tsh
.PHONY: $(BUILDDIR)/tbot
# tbot is CGO-less by default except on Windows because lib/client/terminal/ wants CGO on this OS
# We force cgo to be disabled, else the compiler might decide to enable it.
$(BUILDDIR)/tbot: TBOT_CGO_FLAGS ?= $(if $(filter windows,$(OS)),$(CGOFLAG),CGO_ENABLED=0)
$(BUILDDIR)/tbot:
GOOS=$(OS) GOARCH=$(ARCH) $(TBOT_CGO_FLAGS) go build -tags "grpcnotrace $(FIPS_TAG) $(KUSTOMIZE_NO_DYNAMIC_PLUGIN)" -o $(BUILDDIR)/tbot $(BUILDFLAGS_TBOT) $(TOOLS_LDFLAGS) ./tool/tbot
.PHONY: $(BUILDDIR)/teleport-update
$(BUILDDIR)/teleport-update:
GOOS=$(OS) GOARCH=$(ARCH) CGO_ENABLED=0 go build -tags "grpcnotrace" -o $(BUILDDIR)/teleport-update $(BUILDFLAGS_TELEPORT_UPDATE) $(TOOLS_LDFLAGS) ./tool/teleport-update
TELEPORT_ARGS ?= start
.PHONY: teleport-hot-reload
teleport-hot-reload:
CompileDaemon \
--graceful-kill=true \
--exclude-dir=".git" \
--exclude-dir="build" \
--exclude-dir="e/build" \
--exclude-dir="e/web/*/node_modules" \
--exclude-dir="node_modules" \
--exclude-dir="target" \
--exclude-dir="web/packages/*/node_modules" \
--color \
--log-prefix=false \
--build="make $(BUILDDIR)/teleport" \
--command="$(BUILDDIR)/teleport $(TELEPORT_ARGS)"
.PHONY: $(BUILDDIR)/fdpass-teleport
$(BUILDDIR)/fdpass-teleport:
cd tool/fdpass-teleport && cargo build --release --locked $(CARGO_TARGET)
install tool/fdpass-teleport/target/$(RUST_TARGET_ARCH)/release/fdpass-teleport $(BUILDDIR)/
.PHONY: tsh-app
tsh-app: TSH_APP_BUNDLE = $(BUILDDIR)/tsh.app
tsh-app: TSH_APP_ENTITLEMENTS = build.assets/macos/$(TSH_SKELETON)/$(TSH_SKELETON).entitlements
tsh-app:
cp -rf "build.assets/macos/$(TSH_SKELETON)/tsh.app/" "$(TSH_APP_BUNDLE)/"
mkdir -p "$(TSH_APP_BUNDLE)/Contents/MacOS/"
cp "$(BUILDDIR)/tsh" "$(TSH_APP_BUNDLE)/Contents/MacOS/."
$(NOTARIZE_TSH_APP)
.PHONY: tctl-app
tctl-app: TCTL_APP_BUNDLE = $(BUILDDIR)/tctl.app
tctl-app: TCTL_APP_ENTITLEMENTS = build.assets/macos/$(TCTL_SKELETON)/$(TCTL_SKELETON).entitlements
tctl-app:
cp -rf "build.assets/macos/$(TCTL_SKELETON)/tctl.app/" "$(TCTL_APP_BUNDLE)/"
mkdir -p "$(TCTL_APP_BUNDLE)/Contents/MacOS/"
cp "$(BUILDDIR)/tctl" "$(TCTL_APP_BUNDLE)/Contents/MacOS/."
$(NOTARIZE_TCTL_APP)
# BPF tests will not work in a docker container and so should not be
# run in CI for now.
.PHONY: test-bpf
test-bpf:
mkdir -p _test
gcc ./lib/srv/testdata/bpf_rodata_args.c -o _test/bpf_rodata_args
go test -c -tags bpf,pam -o _test/libsrv.test ./lib/srv
# ignore non bpf-related tests
sudo TELEPORT_BPF_TEST=1 _test/libsrv.test -test.run=TestBPF
# BPF support (IF ENABLED)
# Requires clang 14+
#
# Enable target only if /usr/include/linux/bpf.h exists and clang is installed.
# This is a requirement for building BPF bytecode.
.PHONY: bpf-bytecode
bpf-bytecode:
@if [ ! -f /usr/include/linux/bpf.h -o ! -f /usr/include/bpf/bpf_helpers.h ]; then \
echo "libbpf-dev is required to build BPF bytecode"; \
exit 1; \
fi
@if ! command clang --version >/dev/null 2>&1; then \
echo "clang is required to build BPF bytecode"; \
exit 1; \
fi
go generate ./lib/bpf/
# bpf-up-to-date checks if the generated BPF bytecode is up to date.
.PHONY: bpf-up-to-date
bpf-up-to-date: must-start-clean/host bpf-bytecode
@if ! git diff --quiet; then \
./build.assets/please-run.sh "bpf bytecode" "make -C build.assets bpf-bytecode"; \
exit 1; \
fi
# Generate vmlinux.h based on the installed kernel
.PHONY: update-vmlinux-h
update-vmlinux-h:
bpftool btf dump file /sys/kernel/btf/vmlinux format c >bpf/vmlinux.h
RDPCLIENT_SKIP_CARGO ?= 0
.PHONY: rdpclient
rdpclient: rustup-toolchain-warning
ifeq ("$(with_rdpclient)", "yes")
ifneq ($(RDPCLIENT_SKIP_CARGO),1)
$(RDPCLIENT_ENV) \
cargo build -p rdp-client $(if $(FIPS),--features=fips) --release --locked $(CARGO_TARGET)
else
@echo "Skipping rdp-client cargo build (RDPCLIENT_SKIP_CARGO=1)"
endif
endif
.PHONY: rdpdecoder
rdpdecoder: rustup-toolchain-warning
ifeq ("$(with_rdpclient)", "yes")
$(RDPCLIENT_ENV) \
cargo build -p rdp-decoder --release --locked $(CARGO_TARGET)
endif
define ironrdp_package_json
{
"name": "ironrdp",
"version": "0.1.0",
"module": "ironrdp.js",
"types": "ironrdp.d.ts",
"files": ["ironrdp_bg.wasm","ironrdp.js","ironrdp.d.ts"],
"sideEffects": ["./snippets/*"]
}
endef
export ironrdp_package_json
IRONRDP_SKIP_BUILD ?= 0
.PHONY: build-ironrdp-wasm
build-ironrdp-wasm: ironrdp = web/packages/shared/libs/ironrdp
ifeq ($(IRONRDP_SKIP_BUILD),1)
build-ironrdp-wasm:
@echo "Skipping ironrdp WASM build (IRONRDP_SKIP_BUILD=1)"
else
build-ironrdp-wasm: ensure-wasm-deps
RUSTFLAGS='--cfg getrandom_backend="wasm_js"' cargo build --package ironrdp --lib --target $(CARGO_WASM_TARGET) --release
wasm-opt target/$(CARGO_WASM_TARGET)/release/ironrdp.wasm -o target/$(CARGO_WASM_TARGET)/release/ironrdp.wasm -O
wasm-bindgen target/$(CARGO_WASM_TARGET)/release/ironrdp.wasm --out-dir $(ironrdp)/pkg --typescript --target web
printenv ironrdp_package_json > $(ironrdp)/pkg/package.json
endif
# Build libfido2 and dependencies for MacOS. Uses exported C_ARCH variable defined earlier.
.PHONY: build-fido2
build-fido2:
./build.assets/build-fido2-macos.sh build
.PHONY: print-fido2-pkg-path
print-fido2-pkg-path:
@./build.assets/build-fido2-macos.sh pkg_config_path
#
# make full - Builds Teleport binaries with the built-in web assets and
# places them into $(BUILDDIR). On Windows, this target is skipped because
# only tsh and tctl are built.
#
.PHONY:full
full: WEBASSETS_SKIP_BUILD = 0
full: ensure-webassets
ifneq ("$(OS)", "windows")
export WEBASSETS_SKIP_BUILD=0
$(MAKE) all
endif
#
# make full-ent - Builds Teleport enterprise binaries
#
.PHONY: full-ent
full-ent: ensure-webassets-e
ifneq ("$(OS)", "windows")
@if [ -f e/Makefile ]; then $(MAKE) -C e full; fi
endif
#
# make clean - Removes all build artifacts.
#
.PHONY: clean
clean: clean-ui clean-build
.PHONY: clean-build
clean-build:
@echo "---> Cleaning up OSS build artifacts."
rm -rf $(BUILDDIR)
rm -rf ./session/reexec/embed
-cargo clean
-go clean -cache
rm -f *.gz
rm -f *.zip
rm -f gitref.go
rm -rf build.assets/tooling/bin
# Clean up wasm build artifacts
rm -rf web/packages/shared/libs/ironrdp/pkg/
.PHONY: clean-ui
clean-ui:
rm -rf webassets/*
rm -rf build.assets/.cache/ts
rm -rf web/packages/teleterm/build
find . -type d -name node_modules -prune -exec rm -rf {} \;
.PHONY: clean-ent
clean-ent:
$(MAKE) -C e clean
# RELEASE_DIR is where release artifact files are put, such as tarballs, packages, etc.
$(RELEASE_DIR):
mkdir -p $@
#
# make release - Produces a binary release tarball.
#
.PHONY: release
release:
@echo "---> OSS $(RELEASE_MESSAGE)"
ifeq ("$(OS)", "windows")
$(MAKE) --no-print-directory release-windows
else ifeq ("$(OS)", "darwin")
$(MAKE) --no-print-directory release-darwin
else
$(MAKE) --no-print-directory release-unix
endif
.PHONY: release-ent
release-ent:
$(MAKE) -C e release
# These are aliases used to make build commands uniform.
.PHONY: release-amd64
release-amd64:
$(MAKE) release ARCH=amd64
.PHONY: release-386
release-386:
$(MAKE) release ARCH=386
.PHONY: release-arm
release-arm:
$(MAKE) release ARCH=arm
.PHONY: release-arm64
release-arm64:
$(MAKE) release ARCH=arm64
#
# make build-archive - Packages the results of a build into a release tarball
#
.PHONY: build-archive
ifeq ("$(OS)","darwin")
build-archive: INSTALL_SCRIPT=build.assets/macos/install
else
build-archive: INSTALL_SCRIPT=build.assets/install
endif
build-archive: | $(RELEASE_DIR)
@echo "---> Creating OSS release archive."
mkdir teleport
cp -rf $(BINARIES) \
examples \
"$(INSTALL_SCRIPT)" \
README.md \
CHANGELOG.md \
build.assets/LICENSE-community \
teleport/
# add SELinux install script for Linux archives
$(if $(filter linux,$(OS)), \
cp assets/install-scripts/install-selinux.sh teleport/ \
)
echo $(GITTAG) > teleport/VERSION
tar $(TAR_FLAGS) -c teleport | gzip -n > $(RELEASE).tar.gz
cp $(RELEASE).tar.gz $(RELEASE_DIR)
# linux-amd64 generates a centos7-compatible archive. Make a copy with the -centos7 label,
# for the releases page. We should probably drop that at some point.
$(if $(filter linux-amd64,$(OS)-$(ARCH)), \
cp $(RELEASE).tar.gz $(RELEASE_DIR)/$(subst amd64,amd64-centos7,$(RELEASE)).tar.gz \
)
rm -rf teleport
@echo "---> Created $(RELEASE).tar.gz."
.PHONY: build-update-archive
build-update-archive: | $(RELEASE_DIR)
@echo "---> Creating OSS update release archive."
mkdir -p teleport
cp -rf $(UPDATE_BINARIES) \
CHANGELOG.md \
build.assets/LICENSE-community \
teleport/
echo $(GITTAG) > teleport/VERSION
tar $(TAR_FLAGS) -c teleport | gzip -n > $(RELEASE_UPDATE).tar.gz
cp $(RELEASE_UPDATE).tar.gz $(RELEASE_DIR)
# linux-amd64 generates a centos7-compatible archive. Make a copy with the -centos7 label,
# for the releases page. We should probably drop that at some point.
$(if $(filter linux-amd64,$(OS)-$(ARCH)), \
cp $(RELEASE_UPDATE).tar.gz $(RELEASE_DIR)/$(subst amd64,amd64-centos7,$(RELEASE_UPDATE)).tar.gz \
)
rm -rf teleport
@echo "---> Created $(RELEASE_UPDATE).tar.gz."
#
# make release-unix - Produces binary release tarballs for both OSS and
# Enterprise editions, containing teleport, tctl, tbot and tsh.
#
.PHONY: release-unix
release-unix: clean full build-archive build-update-archive
@if [ -f e/Makefile ]; then $(MAKE) -C e release; fi
# release-unix-preserving-webassets cleans just the build and not the UI
# allowing webassets to be built in a prior step before building the release.
.PHONY: release-unix-preserving-webassets
release-unix-preserving-webassets: clean-build full build-archive build-update-archive
@if [ -f e/Makefile ]; then $(MAKE) -C e release; fi
include darwin-signing.mk
.PHONY: release-darwin-unsigned
release-darwin-unsigned: RELEASE:=$(RELEASE)-unsigned
release-darwin-unsigned: full build-archive
SIGNED_BINARIES := $(BINARIES:%tsh=%tsh.app)
SIGNED_BINARIES := $(SIGNED_BINARIES:%tctl=%tctl.app)
.PHONY: release-darwin
ifneq ($(ARCH),universal)
release-darwin: release-darwin-unsigned
$(NOTARIZE_BINARIES)
$(MAKE) tsh-app tctl-app
$(MAKE) build-archive BINARIES="$(SIGNED_BINARIES)"
@if [ -f e/Makefile ]; then $(MAKE) -C e release; fi
else
# release-darwin for ARCH == universal does not build binaries, but instead
# combines previously-built binaries. For this, it depends on the ARM64 and
# AMD64 signed tarballs being built into $(RELEASE_DIR). The dependencies
# expressed here will not make that happen as this is typically done on CI
# where these two tarballs are built in separate pipelines, and copied in for
# the universal build.
#
# For local manual runs, create these tarballs with:
# make ARCH=arm64 release-darwin
# make ARCH=amd64 release-darwin
# Ensure you have the rust toolchains for these installed by running
# make ARCH=arm64 rustup-install-target-toolchain
# make ARCH=amd64 rustup-install-target-toolchain
release-darwin: TARBINS := $(TARBINS:%tsh=%tsh.app)
release-darwin: TARBINS := $(TARBINS:%tctl=%tctl.app)
release-darwin: $(RELEASE_darwin_arm64) $(RELEASE_darwin_amd64)
mkdir -p $(BUILDDIR_arm64) $(BUILDDIR_amd64)
tar -C $(BUILDDIR_arm64) -xzf $(RELEASE_darwin_arm64) --strip-components=1 $(TARBINS)
tar -C $(BUILDDIR_amd64) -xzf $(RELEASE_darwin_amd64) --strip-components=1 $(TARBINS)
lipo -create -output $(BUILDDIR)/teleport $(BUILDDIR_arm64)/teleport $(BUILDDIR_amd64)/teleport
lipo -create -output $(BUILDDIR)/tbot $(BUILDDIR_arm64)/tbot $(BUILDDIR_amd64)/tbot
lipo -create -output $(BUILDDIR)/fdpass-teleport $(BUILDDIR_arm64)/fdpass-teleport $(BUILDDIR_amd64)/fdpass-teleport
lipo -create -output $(BUILDDIR)/tsh \
$(BUILDDIR_arm64)/tsh.app/Contents/MacOS/tsh \
$(BUILDDIR_amd64)/tsh.app/Contents/MacOS/tsh
lipo -create -output $(BUILDDIR)/tctl \
$(BUILDDIR_arm64)/tctl.app/Contents/MacOS/tctl \
$(BUILDDIR_amd64)/tctl.app/Contents/MacOS/tctl
$(NOTARIZE_BINARIES)
$(MAKE) tsh-app tctl-app
$(MAKE) ARCH=universal build-archive BINARIES="$(SIGNED_BINARIES)"
@if [ -f e/Makefile ]; then $(MAKE) -C e release; fi
endif
#
# make release-windows-unsigned - Produces a binary release archive containing tsh and tctl.
#
.PHONY: release-windows-unsigned
release-windows-unsigned: clean all
@echo "---> Creating OSS release archive."
mkdir teleport
cp -rf $(BUILDDIR)/* \
README.md \
CHANGELOG.md \
teleport/
mv teleport/tsh teleport/tsh-unsigned.exe
mv teleport/tctl teleport/tctl-unsigned.exe
echo $(GITTAG) > teleport/VERSION
zip -9 -y -r -q $(RELEASE)-unsigned.zip teleport/
rm -rf teleport/
@echo "---> Created $(RELEASE)-unsigned.zip."
#
# make release-windows - Produces an archive containing a signed release of
# tsh.exe and tctl.exe
#
.PHONY: release-windows
release-windows: release-windows-unsigned
@if [ ! -f "windows-signing-cert.pfx" ]; then \
echo "windows-signing-cert.pfx is missing or invalid, cannot create signed archive."; \
exit 1; \
fi
rm -rf teleport
@echo "---> Extracting $(RELEASE)-unsigned.zip"
unzip $(RELEASE)-unsigned.zip
@echo "---> Signing Windows tsh binary."
@osslsigncode sign \
-pkcs12 "windows-signing-cert.pfx" \
-n "Teleport" \
-i https://goteleport.com \
-t http://timestamp.digicert.com \
-h sha2 \
-in teleport/tsh-unsigned.exe \
-out teleport/tsh.exe; \
success=$$?; \
rm -f teleport/tsh-unsigned.exe; \
if [ "$${success}" -ne 0 ]; then \
echo "Failed to sign tsh.exe, aborting."; \
exit 1; \
fi
echo "---> Signing Windows tctl binary."
@osslsigncode sign \
-pkcs12 "windows-signing-cert.pfx" \
-n "Teleport" \
-i https://goteleport.com \
-t http://timestamp.digicert.com \
-h sha2 \
-in teleport/tctl-unsigned.exe \
-out teleport/tctl.exe; \
success=$$?; \
rm -f teleport/tctl-unsigned.exe; \
if [ "$${success}" -ne 0 ]; then \
echo "Failed to sign tctl.exe, aborting."; \
exit 1; \
fi
zip -9 -y -r -q $(RELEASE).zip teleport/
rm -rf teleport/
@echo "---> Created $(RELEASE).zip."
#
# make release-connect produces a release package of Teleport Connect.
# It is used only for MacOS releases. Windows releases do not use this
# Makefile. Linux uses the `teleterm` target in build.assets/Makefile.
#
# Either CONNECT_TSH_BIN_PATH or CONNECT_TSH_APP_PATH environment variable
# should be defined for the `pnpm package-term` command to succeed. CI sets
# this appropriately depending on whether a push build is running, or a
# proper release (a proper release needs the APP_PATH as that points to
# the complete signed package). See web/packages/teleterm/README.md for
# details.
.PHONY: release-connect
release-connect: | $(RELEASE_DIR)
pnpm install --frozen-lockfile
pnpm build-term
pnpm package-term -c.extraMetadata.version=$(VERSION) --$(ELECTRON_BUILDER_ARCH)
# Only copy proper builds with tsh.app to $(RELEASE_DIR)
# Drop -universal "arch" from dmg and zip name when copying to $(RELEASE_DIR)
if [ -n "$$CONNECT_TSH_APP_PATH" ]; then \
DMG_TARGET_NAME="Teleport Connect-$(VERSION)-$(ARCH).dmg"; \
ZIP_TARGET_NAME="Teleport Connect-$(VERSION)-$(ARCH)-mac.zip"; \
if [ "$(ARCH)" = 'universal' ]; then \
DMG_TARGET_NAME="$${DMG_TARGET_NAME/-universal/}"; \
ZIP_TARGET_NAME="$${ZIP_TARGET_NAME/-universal/}"; \
fi; \
cp web/packages/teleterm/build/release/"Teleport Connect-$(VERSION)-$(ELECTRON_BUILDER_ARCH).dmg" "$(RELEASE_DIR)/$${DMG_TARGET_NAME}"; \
cp web/packages/teleterm/build/release/"Teleport Connect-$(VERSION)-$(ELECTRON_BUILDER_ARCH)-mac.zip" "$(RELEASE_DIR)/$${ZIP_TARGET_NAME}"; \
fi
#
# Remove trailing whitespace in all markdown files under docs/.
#
# Note: this runs in a busybox container to avoid incompatibilities between
# linux and macos CLI tools.
#
.PHONY: docs-fix-whitespace
docs-fix-whitespace:
docker run --rm -v $(PWD):/teleport busybox \
find /teleport/docs/ -type f -name '*.md' -exec sed -E -i 's/\s+$$//g' '{}' \;
#
# Test docs for trailing whitespace and broken links
#
.PHONY: docs-test
docs-test: docs-test-whitespace
#
# Check for trailing whitespace in all markdown files under docs/
#
.PHONY: docs-test-whitespace
docs-test-whitespace:
if find docs/ -type f -name '*.md' | xargs grep -E '\s+$$'; then \
echo "trailing whitespace found in docs/ (see above)"; \
echo "run 'make docs-fix-whitespace' to fix it"; \
exit 1; \
fi
#
# Builds some tooling for filtering and displaying test progress/output/etc
#
# Deprecated: Use gotestsum instead.
TOOLINGDIR := ${abspath ./build.assets/tooling}
RENDER_TESTS := $(TOOLINGDIR)/bin/render-tests
$(RENDER_TESTS): $(wildcard $(TOOLINGDIR)/cmd/render-tests/*.go)
cd $(TOOLINGDIR) && go build -o "$@" ./cmd/render-tests
DIFF_TEST := $(TOOLINGDIR)/bin/difftest
$(DIFF_TEST): $(wildcard $(TOOLINGDIR)/cmd/difftest/*.go)
cd $(TOOLINGDIR) && go build -o "$@" ./cmd/difftest
BENCHFIND := $(TOOLINGDIR)/bin/benchfind
$(BENCHFIND): $(wildcard $(TOOLINGDIR)/cmd/benchfind/*.go)
cd $(TOOLINGDIR) && go build -o "$@" ./cmd/benchfind
RERUN := $(TOOLINGDIR)/bin/rerun
$(RERUN): $(wildcard $(TOOLINGDIR)/cmd/rerun/*.go)
cd $(TOOLINGDIR) && go build -o "$@" ./cmd/rerun
#
# Runs all Go/shell tests, called by CI/CD.
#
.PHONY: test
test: test-helm test-sh test-api test-go test-rust test-operator test-terraform-provider
$(TEST_LOG_DIR):
mkdir -p $(TEST_LOG_DIR)
.PHONY: helmunit/installed
helmunit/installed:
@if ! helm unittest -h >/dev/null; then \
echo 'Helm unittest plugin is required to test Helm charts. Run `helm plugin install https://github.com/quintush/helm-unittest --version 0.2.11` to install it'; \
exit 1; \
fi
# The CI environment is responsible for setting HELM_PLUGINS to a directory where
# quintish/helm-unittest is installed.
#
# Github Actions build uses /workspace as homedir and Helm can't pick up plugins by default there,
# so override the plugin location via environemnt variable when running in CI. Github Actions provide CI=true
# environment variable.
.PHONY: test-helm
test-helm: helmunit/installed
$(HELMJANITOR) test
.PHONY: test-helm-update-snapshots
test-helm-update-snapshots: helmunit/installed
$(HELMJANITOR) test --update-snapshots
#
# Runs all Go tests except integration, called by CI/CD.
#
.PHONY: test-go
test-go: test-go-unit test-go-touch-id test-go-vnet-daemon test-go-tsh test-go-chaos
#
# Runs a test to ensure no environment variable leak into build binaries.
# This is typically done as part of the bloat test in CI, but this
# target exists for local testing.
#
.PHONY: test-env-leakage
test-env-leakage:
$(eval export BUILD_SECRET=FAKE_SECRET)
$(MAKE) full
failed=0; \
for binary in $(BINARIES); do \
if strings $$binary | grep -q 'FAKE_SECRET'; then \
echo "Error: $$binary contains FAKE_SECRET"; \
failed=1; \
fi; \
done; \
if [ $$failed -eq 1 ]; then \
echo "Environment leak failure"; \
exit 1; \
else \
echo "No environment leak, PASS"; \
fi
# Runs test prepare steps
.PHONY: test-go-prepare
test-go-prepare: ensure-webassets rdpclient $(VERSRC) | $(TEST_LOG_DIR)
# Runs base unit tests
.PHONY: test-go-unit
test-go-unit: rdpclient
test-go-unit: FLAGS ?= -race -shuffle on
test-go-unit: SUBJECT ?= $(shell go list ./... | grep -vE 'teleport/(e2e|integration|tool/tsh|integrations/operator|integrations/access|integrations/lib)')
test-go-unit: test-go-prepare | $(TEST_LOG_DIR)
$(CGOFLAG) go test -json -tags "$(PAM_TAG) $(RDPCLIENT_TAG) $(FIPS_TAG) $(BPF_TAG) $(LIBFIDO2_TEST_TAG) $(TOUCHID_TAG) $(PIV_TEST_TAG) $(VNETDAEMON_TAG) $(ADDTAGS)" $(PACKAGES) $(SUBJECT) $(FLAGS) $(ADDFLAGS) \
| $(GOTESTSUM) --junitfile $(TEST_LOG_DIR)/unit-tests.xml --jsonfile $(TEST_LOG_DIR)/unit-tests.json --raw-command -- cat
# Runs tbot unit tests
.PHONY: test-go-unit-tbot
test-go-unit-tbot: FLAGS ?= -race -shuffle on
test-go-unit-tbot: | $(TEST_LOG_DIR)
$(CGOFLAG) go test -json $(FLAGS) $(ADDFLAGS) ./tool/tbot/... ./lib/tbot/... \
| $(GOTESTSUM) --junitfile $(TEST_LOG_DIR)/unit-tests-tbot.xml --jsonfile $(TEST_LOG_DIR)/unit-tests-tbot.json --raw-command -- cat
# Make sure untagged touchid code build/tests.
.PHONY: test-go-touch-id
test-go-touch-id: FLAGS ?= -race -shuffle on
test-go-touch-id: SUBJECT ?= ./lib/auth/touchid/...
test-go-touch-id: test-go-prepare | $(TEST_LOG_DIR)
ifneq ("$(TOUCHID_TAG)", "")
$(CGOFLAG) go test -json $(PACKAGES) $(SUBJECT) $(FLAGS) $(ADDFLAGS) \
| $(GOTESTSUM) --junitfile $(TEST_LOG_DIR)/unit-tests-touchid.xml --jsonfile $(TEST_LOG_DIR)/unit-tests-touchid.json --raw-command -- cat
endif
# By default, the parameters run each benchmark only once.
# This is intended to run in CI during unit testing to make sure benchmarks don't break.
# To limit noise and improve speed this will only run on packages that have benchmarks.
# Race detection is not enabled because it significantly slows down benchmarks.
# todo: Use gotestsum when it is compatible with benchmark output. Currently will consider all benchmarks failed.
.PHONY: test-go-bench
test-go-bench: BENCHMARK_SKIP_PATTERN = "^BenchmarkRoot"
test-go-bench: BENCH_OUTPUT ?= $(TEST_LOG_DIR)/bench.txt
test-go-bench: BENCH_ARGS ?=
test-go-bench: BENCH_TIME ?= "1x"
test-go-bench: BENCH_COUNT ?= 1
test-go-bench: $(BENCHFIND) | $(TEST_LOG_DIR)
@PKGS=$$($(BENCHFIND) --tags=$(BUILD_TAGS)) ; \
if [ -z "$$PKGS" ]; then \
echo "No benchmark packages found"; \
exit 1; \
fi ; \
go test -run ^$$ -bench . -skip $(BENCHMARK_SKIP_PATTERN) -count $(BENCH_COUNT) -benchtime $(BENCH_TIME) $(BENCH_ARGS) $$PKGS \
| tee $(BENCH_OUTPUT)
.PHONY: test-go-bench-root
test-go-bench-root: BENCHMARK_PATTERN = "^BenchmarkRoot"
test-go-bench-root: BENCHMARK_SKIP_PATTERN = ""
test-go-bench-root: BENCH_OUTPUT ?= $(TEST_LOG_DIR)/bench.txt
test-go-bench-root: BENCH_ARGS ?=
test-go-bench-root: BENCH_TIME ?= "1x"
test-go-bench-root: BENCH_COUNT ?= 1
test-go-bench-root: $(BENCHFIND) | $(TEST_LOG_DIR)
@PKGS=$$($(BENCHFIND) --tags=$(BUILD_TAGS)) ; \
if [ -z "$$PKGS" ]; then \
echo "No benchmark packages found"; \
exit 1; \
fi ; \
go test -run ^$$ -bench $(BENCHMARK_PATTERN) -skip $(BENCHMARK_SKIP_PATTERN) -count $(BENCH_COUNT) -benchtime $(BENCH_TIME) $(BENCH_ARGS) $$PKGS \
| tee $(BENCH_OUTPUT)
# Make sure untagged vnetdaemon code build/tests.
.PHONY: test-go-vnet-daemon
test-go-vnet-daemon: FLAGS ?= -race -shuffle on
test-go-vnet-daemon: SUBJECT ?= ./lib/vnet/daemon/...
test-go-vnet-daemon: test-go-prepare | $(TEST_LOG_DIR)
ifneq ("$(VNETDAEMON_TAG)", "")
$(CGOFLAG) go test -json $(PACKAGES) $(SUBJECT) $(FLAGS) $(ADDFLAGS) \
| $(GOTESTSUM) --junitfile $(TEST_LOG_DIR)/unit-tests-vnet.xml --jsonfile $(TEST_LOG_DIR)/unit-tests-vnet.json --raw-command -- cat
endif
# Runs ci tsh tests
.PHONY: test-go-tsh
test-go-tsh: FLAGS ?= -race -shuffle on
test-go-tsh: SUBJECT ?= github.com/gravitational/teleport/tool/tsh/...
test-go-tsh: test-go-prepare | $(TEST_LOG_DIR)
$(CGOFLAG_TSH) go test -json -tags "$(PAM_TAG) $(FIPS_TAG) $(LIBFIDO2_TEST_TAG) $(TOUCHID_TAG) $(PIV_TEST_TAG) $(VNETDAEMON_TAG)" $(PACKAGES) $(SUBJECT) $(FLAGS) $(ADDFLAGS) \
| $(GOTESTSUM) --junitfile $(TEST_LOG_DIR)/unit-tests-tsh.xml --jsonfile $(TEST_LOG_DIR)/unit-tests-tsh.json --raw-command -- cat
# Chaos tests have high concurrency, run without race detector and have TestChaos prefix.
.PHONY: test-go-chaos
test-go-chaos: CHAOS_FOLDERS = $(shell find . -type f -name '*chaos*.go' | xargs dirname | uniq)
test-go-chaos: test-go-prepare | $(TEST_LOG_DIR)
$(CGOFLAG) go test -json -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG)" -test.run=TestChaos $(CHAOS_FOLDERS) \
| $(GOTESTSUM) --junitfile $(TEST_LOG_DIR)/unit-tests-chaos.xml --jsonfile $(TEST_LOG_DIR)/unit-tests-chaos.json --raw-command -- cat
#
# Runs all Go tests except integration, end-to-end, and chaos, called by CI/CD.
#
UNIT_ROOT_REGEX := ^TestRoot
.PHONY: test-go-root
test-go-root: ensure-webassets rdpclient | $(TEST_LOG_DIR)
test-go-root: FLAGS ?= -race -shuffle on
test-go-root: PACKAGES = $(shell go list $(ADDFLAGS) ./... | grep -v -e e2e -e integration -e integrations/operator)
test-go-root: $(VERSRC)
$(CGOFLAG) go test -json -run "$(UNIT_ROOT_REGEX)" -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG)" $(PACKAGES) $(FLAGS) $(ADDFLAGS) \
| $(GOTESTSUM) --junitfile $(TEST_LOG_DIR)/unit-tests-root.xml --jsonfile $(TEST_LOG_DIR)/unit-tests-root.json --raw-command -- cat
#
# Runs Go tests on the api module. These have to be run separately as the package name is different.
#
.PHONY: test-api
test-api: $(VERSRC) | $(TEST_LOG_DIR)
test-api: FLAGS ?= -race -shuffle on
test-api: SUBJECT ?= $(shell cd api && go list ./...)
test-api:
cd api && $(CGOFLAG) go test -json -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG)" $(PACKAGES) $(SUBJECT) $(FLAGS) $(ADDFLAGS) \
| $(GOTESTSUM) --junitfile $(TEST_LOG_DIR)/unit-tests-api.xml --jsonfile $(TEST_LOG_DIR)/unit-tests-api.json --raw-command -- cat
#
# Runs Teleport Operator tests.
# We have to run them using the makefile to ensure the installation of the k8s test tools (envtest)
#
.PHONY: test-operator
test-operator:
$(MAKE) -C integrations/operator test TEST_LOG_DIR=$(TEST_LOG_DIR)
#
# Runs Teleport Terraform provider tests.
#
.PHONY: test-terraform-provider
test-terraform-provider:
$(MAKE) -C integrations test-terraform-provider TEST_LOG_DIR=$(TEST_LOG_DIR)
#
# Runs Teleport MWI Terraform provider tests.
#
.PHONY: test-terraform-provider-mwi
test-terraform-provider-mwi:
$(MAKE) -C integrations test-terraform-provider-mwi TEST_LOG_DIR=$(TEST_LOG_DIR)
#
# Runs Go tests on the integrations/kube-agent-updater module. These have to be run separately as the package name is different.
#
.PHONY: test-kube-agent-updater
test-kube-agent-updater: $(VERSRC) | $(TEST_LOG_DIR)
test-kube-agent-updater: FLAGS ?= -race -shuffle on
test-kube-agent-updater: SUBJECT ?= $(shell cd integrations/kube-agent-updater && go list ./...)
test-kube-agent-updater:
cd integrations/kube-agent-updater && $(CGOFLAG) go test -json -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG)" $(PACKAGES) $(SUBJECT) $(FLAGS) $(ADDFLAGS) \
| $(GOTESTSUM) --junitfile $(TEST_LOG_DIR)/unit-tests-kube-agent-updater.xml --jsonfile $(TEST_LOG_DIR)/unit-tests-kube-agent-updater.json --raw-command -- cat
.PHONY: test-access-integrations
test-access-integrations:
$(MAKE) -C integrations test-access
.PHONY: test-event-handler-integrations
test-event-handler-integrations:
$(MAKE) -C integrations test-event-handler
.PHONY: test-integrations-lib
test-integrations-lib:
$(MAKE) -C integrations test-lib
#
# Runs Go tests on the examples/teleport-usage module. These have to be run separately as the package name is different.
#
.PHONY: test-teleport-usage
test-teleport-usage: $(VERSRC) | $(TEST_LOG_DIR)
test-teleport-usage: FLAGS ?= -race -shuffle on
test-teleport-usage: SUBJECT ?= $(shell cd examples/teleport-usage && go list ./...)
test-teleport-usage:
cd examples/teleport-usage && $(CGOFLAG) go test -json -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG)" $(PACKAGES) $(SUBJECT) $(FLAGS) $(ADDFLAGS) \
| $(GOTESTSUM) --junitfile $(TEST_LOG_DIR)/unit-tests-teleport-usage.xml --jsonfile $(TEST_LOG_DIR)/unit-tests-teleport-usage.json --raw-command -- cat
#
# Flaky test detection. Usually run from CI nightly, overriding these default parameters
# This runs the same tests as test-go-unit but repeatedly to try to detect flaky tests.
#
# TODO(jakule): Migrate to gotestsum
.PHONY: test-go-flaky
FLAKY_RUNS ?= 3
FLAKY_TIMEOUT ?= 1h
FLAKY_TOP_N ?= 20
FLAKY_SUMMARY_FILE ?= /tmp/flaky-report.txt
test-go-flaky: rdpclient
test-go-flaky: FLAGS ?= -race -shuffle on
test-go-flaky: SUBJECT ?= $(shell go list ./... | grep -v -e e2e -e integration -e tool/tsh -e integrations/operator -e integrations/access -e integrations/lib )
test-go-flaky: GO_BUILD_TAGS ?= $(PAM_TAG) $(FIPS_TAG) $(RDPCLIENT_TAG) $(BPF_TAG) $(TOUCHID_TAG) $(PIV_TEST_TAG) $(LIBFIDO2_TEST_TAG) $(VNETDAEMON_TAG)
test-go-flaky: RENDER_FLAGS ?= -report-by flakiness -summary-file $(FLAKY_SUMMARY_FILE) -top $(FLAKY_TOP_N)
test-go-flaky: test-go-prepare $(RENDER_TESTS) $(RERUN)
$(CGOFLAG) $(RERUN) -n $(FLAKY_RUNS) -t $(FLAKY_TIMEOUT) \
go test -count=1 -json -tags "$(GO_BUILD_TAGS)" $(SUBJECT) $(FLAGS) $(ADDFLAGS) \
| $(RENDER_TESTS) $(RENDER_FLAGS)
#
# Runs cargo test on our Rust modules.
# (a no-op if cargo and rustc are not installed)
#
ifneq ($(CHECK_RUST),)
ifneq ($(CHECK_CARGO),)
.PHONY: test-rust
test-rust:
cargo test
else
.PHONY: test-rust
test-rust:
endif
endif
# Run all shell script unit tests (using https://github.com/bats-core/bats-core)
.PHONY: test-sh
test-sh:
@if ! type bats 2>&1 >/dev/null; then \
echo "Not running 'test-sh' target as 'bats' is not installed."; \
if [ "$${CI}" = "true" ]; then echo "This is a failure when running in CI." && exit 1; fi; \
exit 0; \
fi; \
bats $(BATSFLAGS) ./assets/aws/files/tests
.PHONY: run-etcd
run-etcd:
docker build -f .github/services/Dockerfile.etcd -t etcdbox --build-arg=ETCD_VERSION=3.5.9 .
docker run -it --rm -p'2379:2379' etcdbox
#
# Integration tests. Need a TTY to work.
# Any tests which need to run as root must be skipped during regular integration testing.
#
.PHONY: integration
integration: FLAGS ?= -v -race
integration: PACKAGES = $(shell go list ./... | grep 'integration\([^s]\|$$\)' | grep -v integrations/lib/testing/integration )
integration: session/reexec/embed/sessionhelper | $(TEST_LOG_DIR)
@echo KUBECONFIG is: $(KUBECONFIG), TEST_KUBE: $(TEST_KUBE)
$(CGOFLAG) go test -timeout 30m -json -tags "$(PAM_TAG) $(FIPS_TAG) $(BPF_TAG) $(SESSIONHELPER_EMBED_TAG)" $(PACKAGES) $(FLAGS) \
| $(GOTESTSUM) --junitfile $(TEST_LOG_DIR)/unit-tests-integration.xml --jsonfile $(TEST_LOG_DIR)/unit-tests-integration.json --raw-command -- cat
#
# Integration tests that run Kubernetes tests in order to complete successfully
# are run separately to all other integration tests.
#
INTEGRATION_KUBE_REGEX := TestKube.*
.PHONY: integration-kube
integration-kube: FLAGS ?= -v -race
integration-kube: PACKAGES = $(shell go list ./... | grep 'integration\([^s]\|$$\)' | grep -v 'integration/autoupdate')
integration-kube: | $(TEST_LOG_DIR)
@echo KUBECONFIG is: $(KUBECONFIG), TEST_KUBE: $(TEST_KUBE)
$(CGOFLAG) go test -json -run "$(INTEGRATION_KUBE_REGEX)" $(PACKAGES) $(FLAGS) \
| $(GOTESTSUM) --junitfile $(TEST_LOG_DIR)/unit-tests-integration-kube.xml --jsonfile $(TEST_LOG_DIR)/unit-tests-integration-kube.json --raw-command -- cat
#
# Integration tests which need to be run as root in order to complete successfully
# are run separately to all other integration tests. Need a TTY to work.
#
INTEGRATION_ROOT_REGEX := ^TestRoot
.PHONY: integration-root
integration-root: FLAGS ?= -v -race
integration-root: PACKAGES = $(shell go list ./... | grep 'integration\([^s]\|$$\)')
integration-root: session/reexec/embed/sessionhelper | $(TEST_LOG_DIR)
$(CGOFLAG) go test -json -tags '$(SESSIONHELPER_EMBED_TAG)' -run "$(INTEGRATION_ROOT_REGEX)" $(PACKAGES) $(FLAGS) \
| $(GOTESTSUM) --junitfile $(TEST_LOG_DIR)/unit-tests-integration-root.xml --jsonfile $(TEST_LOG_DIR)/unit-tests-integration-root.json --raw-command -- cat
.PHONY: e2e-aws
e2e-aws: FLAGS ?= -v -race
e2e-aws: PACKAGES = $(shell go list ./... | grep 'e2e/aws')
e2e-aws: | $(TEST_LOG_DIR)
@echo TEST_KUBE: $(TEST_KUBE) TEST_AWS_DB: $(TEST_AWS_DB)
$(CGOFLAG) go test -json $(PACKAGES) $(FLAGS) $(ADDFLAGS)\
| $(GOTESTSUM) --junitfile $(TEST_LOG_DIR)/unit-tests-e2e-aws.xml --jsonfile $(TEST_LOG_DIR)/unit-tests-e2e-aws.json --raw-command -- cat
# e2e-binaries builds teleport, tctl, and tsh (with webauthnmock) in parallel
# for use in e2e tests.
.PHONY: e2e-binaries
e2e-binaries:
build.assets/build-e2e-binaries.sh
#
# Lint the source code.
# By default lint scans the entire repo. Pass GO_LINT_FLAGS='--new' to only scan local
# changes (or last commit).
#
.PHONY: lint
lint: lint-api lint-go lint-kube-agent-updater lint-tools lint-protos lint-no-actions
#
# Runs linters without dedicated GitHub Actions.
#
.PHONY: lint-no-actions
lint-no-actions: lint-sh lint-license
.PHONY: lint-tools
lint-tools: lint-build-tooling lint-backport
#
# Checks that testing symbols and the testify library is not included in binaries.
#
#
.PHONY: lint-test-symbols
lint-test-symbols:
@testing_count=`$(GODA) tree "reach(github.com/gravitational/teleport/tool/...:all, testing)" | tee /dev/stderr | wc -l | tr -d ' '`; \
if [ "$$testing_count" -gt 0 ]; then \
echo ""; \
echo "FAIL: \"testing\" is included in binaries"; \
fi; \
testify_count=`$(GODA) tree "reach(github.com/gravitational/teleport/tool/...:all, github.com/stretchr/testify/...)" | tee /dev/stderr | wc -l | tr -d ' '`; \
if [ "$$testify_count" -gt 0 ]; then \
echo ""; \
echo "FAIL: \"github.com/stretchr/testify\" is included in binaries"; \
fi; \
if [ "$$testing_count" -gt 0 ] || [ "$$testify_count" -gt 0 ]; then \
exit 1; \
fi
#
# Runs the clippy linter and rustfmt on our rust modules
# (a no-op if cargo and rustc are not installed)
#
ifneq ($(CHECK_RUST),)
ifneq ($(CHECK_CARGO),)
.PHONY: lint-rust
lint-rust:
cargo clippy --locked --all-targets -- -D warnings \
&& cargo fmt -- --check
else
.PHONY: lint-rust
lint-rust:
endif
endif
.PHONY: lint-go
lint-go: GO_LINT_FLAGS ?=
lint-go:
golangci-lint run -c .golangci.yml --build-tags='$(LIBFIDO2_TEST_TAG) $(TOUCHID_TAG) $(PIV_LINT_TAG) $(VNETDAEMON_TAG)' $(GO_LINT_FLAGS)
$(MAKE) -C integrations/terraform lint
$(MAKE) -C integrations/event-handler lint
.PHONY: fix-imports
fix-imports:
$(MAKE) -C build.assets fix-imports
.PHONY: fix-imports/host
fix-imports/host:
$(GCI) write -s standard -s default -s 'prefix(github.com/gravitational/teleport)' -s 'prefix(github.com/gravitational/teleport/integrations/terraform,github.com/gravitational/teleport/integrations/event-handler)' --skip-generated .
lint-build-tooling: GO_LINT_FLAGS ?=
lint-build-tooling:
cd build.assets/tooling && golangci-lint run -c ../../.golangci.yml $(GO_LINT_FLAGS)
.PHONY: lint-backport
lint-backport: GO_LINT_FLAGS ?=
lint-backport:
cd assets/backport && golangci-lint run -c ../../.golangci.yml $(GO_LINT_FLAGS)
# api is no longer part of the teleport package, so golangci-lint skips it by default
.PHONY: lint-api
lint-api: GO_LINT_API_FLAGS ?=
lint-api:
cd api && golangci-lint run -c ../.golangci.yml --build-tags='$(PIV_LINT_TAG)' $(GO_LINT_API_FLAGS)
.PHONY: lint-kube-agent-updater
lint-kube-agent-updater: GO_LINT_API_FLAGS ?=
lint-kube-agent-updater:
cd integrations/kube-agent-updater && golangci-lint run -c ../../.golangci.yml $(GO_LINT_API_FLAGS)
# TODO(awly): remove the `--exclude` flag after cleaning up existing scripts
.PHONY: lint-sh
lint-sh: SH_LINT_FLAGS ?=
lint-sh:
find . -type f \( -name '*.sh' -or -name '*.sh.tmpl' \) -not -path "*/node_modules/*" | xargs \
shellcheck \
--exclude=SC2086 \
--exclude=SC1091 \
$(SH_LINT_FLAGS)
# lint AWS AMI scripts
# SC1091 prints errors when "source" directives are not followed
find assets/aws/files/bin -type f | xargs \
shellcheck \
--exclude=SC2086 \
--exclude=SC1091 \
--exclude=SC2129 \
$(SH_LINT_FLAGS)
# Lints all the Helm charts found in directories under examples/chart and exits on failure
# If there is a .lint directory inside, the chart gets linted once for each .yaml file in that directory
# We inherit yamllint's 'relaxed' configuration as it's more compatible with Helm output and will only error on
# show-stopping issues. Kubernetes' YAML parser is not particularly fussy.
# If errors are found, the file is printed with line numbers to aid in debugging.
.PHONY: lint-helm
lint-helm:
$(HELMJANITOR) reference -check
$(HELMJANITOR) lint
ADDLICENSE_COMMON_ARGS := -c 'Gravitational, Inc.' \
-ignore '**/*.c' \
-ignore '**/*.h' \
-ignore '**/*.html' \
-ignore '**/*.js' \
-ignore '**/*.py' \
-ignore '**/*.sh' \
-ignore '**/*.sql' \
-ignore '**/*.tf' \
-ignore '**/*.tftest.hcl' \
-ignore '**/*.yaml' \
-ignore '**/*.yml' \
-ignore '**/.terraform.lock.hcl' \
-ignore '**/Dockerfile' \
-ignore '**/node_modules/**' \
-ignore 'api/version.go' \
-ignore 'build.assets/.cache/**' \
-ignore 'docs/pages/includes/**/*.go' \
-ignore 'e/**' \
-ignore 'gen/**' \
-ignore 'gitref.go' \
-ignore 'lib/limiter/internal/ratelimit/**' \
-ignore 'lib/srv/desktop/rdp/decoder/target/**' \
-ignore 'lib/srv/desktop/rdp/rdpclient/target/**' \
-ignore 'lib/web/build/**' \
-ignore 'target/**' \
-ignore 'web/packages/design/src/assets/icomoon/style.css' \
-ignore 'web/packages/shared/libs/ironrdp/**' \
-ignore 'web/packages/teleterm/build/**' \
-ignore 'webassets/**'
ADDLICENSE_AGPL3_ARGS := $(ADDLICENSE_COMMON_ARGS) \
-ignore 'api/**' \
-f $(CURDIR)/build.assets/LICENSE.header
ADDLICENSE_APACHE2_ARGS := $(ADDLICENSE_COMMON_ARGS) \
-l apache
ADDLICENSE = go run github.com/google/addlicense@v1.0.0
.PHONY: lint-license
lint-license:
$(ADDLICENSE) $(ADDLICENSE_AGPL3_ARGS) -check * 2>/dev/null
$(ADDLICENSE) $(ADDLICENSE_APACHE2_ARGS) -check api/* 2>/dev/null
.PHONY: fix-license
fix-license:
$(ADDLICENSE) $(ADDLICENSE_AGPL3_ARGS) * 2>/dev/null
$(ADDLICENSE) $(ADDLICENSE_APACHE2_ARGS) api/* 2>/dev/null
# This rule updates version files and Helm snapshots based on the Makefile
# VERSION variable.
#
# Used prior to a release by bumping VERSION in this Makefile and then
# running "make update-version".
.PHONY: update-version
update-version: version test-helm-update-snapshots
# This rule triggers re-generation of version files if Makefile changes.
.PHONY: version
version: $(VERSRC)
# This rule triggers re-generation of version files specified if Makefile changes.
$(VERSRC) &: Makefile version.mk
VERSION=$(VERSION) $(MAKE) -f version.mk setver
# Pushes GITTAG and api/GITTAG to GitHub.
#
# Before running `make update-tag`, do:
#
# 1. Commit your changes
# 2. Bump VERSION variable (eg, "vMAJOR.(MINOR+1).0-dev-$USER.1")
# 3. Run `make update-version`
# 4. Commit version changes to git
# 5. Make sure it all builds (`make release` or equivalent)
# 6. Run `make update-tag` to tag repos with $(VERSION)
# 7. Run `make tag-build` to build the tag on GitHub Actions
# 8. Run `make tag-publish` after `make tag-build` tag has completed to
# publish the built artifacts.
#
# GHA tag builds: https://github.com/gravitational/teleport.e/actions/workflows/tag-build.yaml
# GHA tag publish: https://github.com/gravitational/teleport.e/actions/workflows/tag-publish.yaml
.PHONY: update-tag
update-tag: TAG_REMOTE ?= origin
update-tag:
@test $(VERSION)
cd build.assets/tooling && GOWORK=off CGO_ENABLED=0 go run ./cmd/check -check valid -tag $(GITTAG)
git tag $(GITTAG)
git tag api/$(GITTAG)
(cd e && git tag $(GITTAG) && git push origin $(GITTAG))
git push $(TAG_REMOTE) $(GITTAG) && git push $(TAG_REMOTE) api/$(GITTAG)
# find-any evaluates to non-empty (true) if any of the strings in $(1) are contained in $(2)
# e.g.
# $(call find-any,-cloud -dev,1.2.3-dev.1) == true
# $(call find-any,-cloud -dev,1.2.3-cloud.1) == true
# $(call find-any,-cloud -dev,1.2.3) == false
find-any = $(strip $(foreach str,$(1),$(findstring $(str),$(2))))
# IS_CLOUD_SEMVER is non-empty if $(VERSION) contains a cloud-only pre-release tag,
# and is empty if not.
CLOUD_VERSIONS = -cloud. -dev.cloud.
IS_CLOUD_SEMVER = $(call find-any,$(CLOUD_VERSIONS),$(VERSION))
# IS_PROD_SEMVER is non-empty if $(VERSION) does not contains a pre-release component, or
# if it does, it is -cloud.
PROD_VERSIONS = -cloud.
IS_PROD_SEMVER = $(if $(findstring -,$(VERSION)),$(call find-any,$(PROD_VERSIONS),$(VERSION)),true)
# Builds a tag build on GitHub Actions.
# Starts a tag publish run using e/.github/workflows/tag-build.yaml
# for the tag v$(VERSION).
# If the $(VERSION) variable contains a cloud pre-release component, -cloud. or
# -dev.cloud., then the tag-build workflow is run with `cloud-only=true`. This can be
# specified explicitly with `make tag-build CLOUD_ONLY=<true|false>`.
.PHONY: tag-build
tag-build: CLOUD_ONLY = $(if $(IS_CLOUD_SEMVER),true,false)
tag-build: ENVIRONMENT = $(if $(IS_PROD_SEMVER),prod/build,stage/build)
tag-build:
@which gh >/dev/null 2>&1 || { echo 'gh command needed. https://github.com/cli/cli'; exit 1; }
gh workflow run tag-build.yaml \
--repo gravitational/teleport.e \
--ref "v$(VERSION)" \
-f "oss-teleport-repo=$(shell gh repo view --json nameWithOwner --jq .nameWithOwner)" \
-f "oss-teleport-ref=v$(VERSION)" \
-f "cloud-only=$(CLOUD_ONLY)" \
-f "environment=$(ENVIRONMENT)"
@echo See runs at: https://github.com/gravitational/teleport.e/actions/workflows/tag-build.yaml
# Publishes a tag build.
# Starts a tag publish run using e/.github/workflows/tag-publish.yaml
# for the tag v$(VERSION).
# If the $(VERSION) variable contains a cloud pre-release component, -cloud. or
# -dev.cloud., then the tag-publish workflow is run with `cloud-only=true`. This can be
# specified explicitly with `make tag-publish CLOUD_ONLY=<true|false>`.
.PHONY: tag-publish
tag-publish: CLOUD_ONLY = $(if $(IS_CLOUD_SEMVER),true,false)
tag-publish: ENVIRONMENT = $(if $(IS_PROD_SEMVER),prod/publish,stage/publish)
tag-publish:
@which gh >/dev/null 2>&1 || { echo 'gh command needed. https://github.com/cli/cli'; exit 1; }
gh workflow run tag-publish.yaml \
--repo gravitational/teleport.e \
--ref "v$(VERSION)" \
-f "oss-teleport-repo=$(shell gh repo view --json nameWithOwner --jq .nameWithOwner)" \
-f "oss-teleport-ref=v$(VERSION)" \
-f "cloud-only=$(CLOUD_ONLY)" \
-f "environment=$(ENVIRONMENT)"
@echo See runs at: https://github.com/gravitational/teleport.e/actions/workflows/tag-publish.yaml
.PHONY: profile
profile:
go tool pprof http://localhost:6060/debug/pprof/profile
.PHONY: sloccount
sloccount:
find . -name "*.go" -print0 | xargs -0 wc -l
#
# print-go-version outputs Go version as a semver without "go" prefix
#
.PHONY: print-go-version
print-go-version:
@$(MAKE) -C build.assets print-go-version | sed "s/go//"
# Dockerized build: useful for making Linux releases on macOS
.PHONY: docker
docker:
$(MAKE) -C build.assets build
# Dockerized build: useful for making Linux binaries on macOS
.PHONY: docker-binaries
docker-binaries: clean
$(MAKE) -C build.assets build-binaries PIV=$(PIV)
# Interactively enters a Docker container (which you can build and run Teleport inside of)
.PHONY: enter
enter:
$(MAKE) -C build.assets enter
# Interactively enters a Docker container, as root (which you can build and run Teleport inside of)
.PHONY: enter-root
enter-root:
$(MAKE) -C build.assets enter-root
# Interactively enters a Docker container (which you can build and run Teleport inside of).
# Similar to `enter`, but uses the centos7 container.
.PHONY: enter/centos7
enter/centos7:
$(MAKE) -C build.assets enter/centos7
.PHONY: enter/centos7-fips
enter/centos7-fips:
$(MAKE) -C build.assets enter/centos7-fips
.PHONY: enter/grpcbox
enter/grpcbox:
$(MAKE) -C build.assets enter/grpcbox
.PHONY:enter/node
enter/node:
$(MAKE) -C build.assets enter/node
.PHONY: enter/arm
enter/arm:
$(MAKE) -C build.assets enter/arm
BUF := buf
#
# Install buf to lint, format and generate code from protobuf files.
#
.PHONY: ensure-buf
ensure-buf: NEED_VERSION = $(shell $(MAKE) --no-print-directory -s -C build.assets print-buf-version)
ensure-buf:
# Install buf if it's not already installed.
ifeq (, $(shell command -v $(BUF)))
go install github.com/bufbuild/buf/cmd/buf@$(NEED_VERSION)
endif
# protos/all runs build, lint and format on all protos.
# Use `make grpc` to regenerate protos inside buildbox.
.PHONY: protos/all
protos/all: protos/build protos/lint protos/format
.PHONY: protos/build
protos/build: ensure-buf
$(BUF) build
.PHONY: protos/format
protos/format: ensure-buf
$(BUF) format -w
.PHONY: protos/lint
protos/lint: ensure-buf
$(BUF) lint
$(BUF) lint --config=buf-legacy.yaml api/proto
.PHONY: protos/breaking
protos/breaking: BASE=origin/master
protos/breaking: ensure-buf
@echo Checking compatibility against BASE=$(BASE)
buf breaking . --against '.git#branch=$(BASE)'
.PHONY: lint-protos
lint-protos: protos/lint
.PHONY: lint-breaking
lint-breaking: protos/breaking
GODERIVE := $(TOOLINGDIR)/bin/goderive
# derive will generate derived functions for our API.
# we need to build goderive first otherwise it will not be able to resolve dependencies
# in the api/types/discoveryconfig package
.PHONY: derive
derive:
cd $(TOOLINGDIR) && go build -o $(GODERIVE) ./cmd/goderive/main.go
$(GODERIVE) ./api/types ./api/types/discoveryconfig ./api/types/accesslist ./api/types/userloginstate
# derive-up-to-date checks if the generated derived functions are up to date.
.PHONY: derive-up-to-date
derive-up-to-date: must-start-clean/host derive
@if ! git diff --quiet; then \
./build.assets/please-run.sh "derived functions" "make derive"; \
exit 1; \
fi
# grpc generates gRPC stubs from service definitions.
# This target runs in the buildbox container.
.PHONY: grpc
grpc:
$(MAKE) -C build.assets grpc
# grpc/host generates gRPC stubs.
# Unlike grpc, this target runs locally.
.PHONY: grpc/host
grpc/host: protos/all
@build.assets/genproto.sh
# protos-up-to-date checks if the generated gRPC stubs are up to date.
# This target runs in the buildbox container.
.PHONY: protos-up-to-date
protos-up-to-date:
$(MAKE) -C build.assets protos-up-to-date
# protos-up-to-date/host checks if the generated gRPC stubs are up to date.
# Unlike protos-up-to-date, this target runs locally.
.PHONY: protos-up-to-date/host
protos-up-to-date/host: must-start-clean/host grpc/host
@if ! git diff --quiet; then \
./build.assets/please-run.sh "protos gRPC" "make grpc"; \
exit 1; \
fi
.PHONY: must-start-clean/host
must-start-clean/host:
@if ! git diff --quiet; then \
echo 'This must be run from a repo with no unstaged commits.'; \
git diff; \
exit 1; \
fi
# crds-up-to-date checks if the generated CRDs from the protobuf stubs are up to date.
.PHONY: crds-up-to-date
crds-up-to-date: must-start-clean/host
$(MAKE) -C integrations/operator crd-manifests
@if ! git diff --quiet; then \
./build.assets/please-run.sh "operator CRD manifests" "make -C integrations/operator crd"; \
exit 1; \
fi
$(MAKE) -C integrations/operator crd-docs
@if ! git diff --quiet; then \
./build.assets/please-run.sh "operator CRD docs" "make -C integrations/operator crd"; \
exit 1; \
fi
# tfdocs-up-to-date checks if the generated Terraform types and documentation from the protobuf stubs are up to date.
.PHONY: terraform-resources-up-to-date
terraform-resources-up-to-date: must-start-clean/host
$(MAKE) -C integrations/terraform docs
@if ! git diff --quiet; then \
./build.assets/please-run.sh "TF provider docs" "make -C integrations/terraform docs"; \
exit 1; \
fi
# terraform-module-docs-up-to-date checks if the generated Terraform module documentation is up to date.
.PHONY: terraform-module-docs-up-to-date
terraform-module-docs-up-to-date: must-start-clean/host
$(MAKE) -C integrations/terraform-modules docs
@if ! git diff --quiet; then \
./build.assets/please-run.sh "TF module docs" "make -C integrations/terraform-modules docs"; \
exit 1; \
fi
# icons-up-to-date checks if icons were pre-processed before being added to the repo.
.PHONY: icons-up-to-date
icons-up-to-date: must-start-clean/host
pnpm process-icons
@if ! git diff --quiet; then \
./build.assets/please-run.sh "icons (see web/packages/design/src/Icon/README.md)" "pnpm process-icons"; \
exit 1; \
fi
# go-generate will execute `go generate` and generate go code.
.PHONY: go-generate
go-generate:
go generate ./lib/...
# go-generate-up-to-date checks if the generated code is up to date.
.PHONY: go-generate-up-to-date
go-generate-up-to-date: must-start-clean/host go-generate
@if ! git diff --quiet; then \
./build.assets/please-run.sh "go generate lib" "make go-generate"; \
exit 1; \
fi
.PHONY: print/env
print/env:
env
# make install will installs system-wide teleport
.PHONY: install
install: build
@echo "\n** Make sure to run 'make install' as root! **\n"
cp -f $(BUILDDIR)/tctl $(BINDIR)/
cp -f $(BUILDDIR)/tsh $(BINDIR)/
cp -f $(BUILDDIR)/tbot $(BINDIR)/
cp -f $(BUILDDIR)/teleport $(BINDIR)/
cp -f $(BUILDDIR)/teleport-update $(BINDIR)/
mkdir -p $(DATADIR)
# Docker image build. Always build the binaries themselves within docker (see
# the "docker" rule) to avoid dependencies on the host libc version.
.PHONY: image
image: OS=linux
image: TARBALL_PATH_SECTION:=-s "$(shell pwd)"
image: clean docker-binaries build-archive oss-deb
cp ./build.assets/charts/Dockerfile $(BUILDDIR)/
cd $(BUILDDIR) && docker build --no-cache . -t $(DOCKER_IMAGE):$(VERSION)-$(ARCH) --target teleport \
--build-arg DEB_PATH="./teleport_$(VERSION)_$(ARCH).deb"
if [ -f e/Makefile ]; then $(MAKE) -C e image PIV=$(PIV); fi
.PHONY: print-version
print-version:
@echo $(VERSION)
.PHONY: chart-ent
chart-ent:
$(MAKE) -C e chart
RUNTIME_SECTION ?=
TARBALL_PATH_SECTION ?=
ifneq ("$(RUNTIME)", "")
RUNTIME_SECTION := -r $(RUNTIME)
endif
ifneq ("$(OSS_TARBALL_PATH)", "")
TARBALL_PATH_SECTION := -s $(OSS_TARBALL_PATH)
endif
# build .pkg
# builds two package files: tsh-$VERSION.pkg and teleport-bin-$VERSION.pkg
# combines the two package files into one teleport-$VERSION.pkg
.PHONY: pkg
pkg: TELEPORT_PKG_UNSIGNED = $(BUILDDIR)/teleport-$(VERSION).unsigned.pkg
pkg: TELEPORT_PKG_SIGNED = $(RELEASE_DIR)/teleport-$(VERSION).pkg
pkg: TELEPORT_TOOLS_PKG_UNSIGNED = $(BUILDDIR)/teleport-tools-$(VERSION).unsigned.pkg
pkg: TELEPORT_TOOLS_PKG_SIGNED = $(RELEASE_DIR)/teleport-tools-$(VERSION).pkg
pkg: | $(RELEASE_DIR)
mkdir -p $(BUILDDIR)/
@echo Building tsh-$(VERSION).pkg
./build.assets/build-pkg-app.sh -t oss -v $(VERSION) -b $(TSH_BUNDLEID) -a $(ARCH) $(TARBALL_PATH_SECTION)
mv tsh*.pkg* $(BUILDDIR)/
@echo Building tctl-$(VERSION).pkg
./build.assets/build-pkg-app.sh -p tctl -t oss -v $(VERSION) -b $(TCTL_BUNDLEID) -a $(ARCH) $(TARBALL_PATH_SECTION)
mv tctl*.pkg* $(BUILDDIR)/
@echo Building teleport-bin-$(VERSION).pkg
cp ./build.assets/build-package.sh ./build.assets/build-common.sh $(BUILDDIR)/
chmod +x $(BUILDDIR)/build-package.sh
# runtime is currently ignored on OS X
# we pass it through for consistency - it will be dropped by the build script
cd $(BUILDDIR) && ./build-package.sh -t oss -v $(VERSION) -p pkg -b $(TELEPORT_BUNDLEID) -a $(ARCH) $(RUNTIME_SECTION) $(TARBALL_PATH_SECTION)
@echo Combining teleport-bin-$(VERSION).pkg and tsh-$(VERSION).pkg into teleport-$(VERSION).pkg
productbuild --package $(BUILDDIR)/tsh*.pkg --package $(BUILDDIR)/tctl*.pkg --package $(BUILDDIR)/teleport-bin*.pkg $(TELEPORT_PKG_UNSIGNED)
$(NOTARIZE_TELEPORT_PKG)
@echo Combining tsh-$(VERSION).pkg and tctl-$(VERSION).pkg into teleport-tools-$(VERSION).pkg
productbuild --package $(BUILDDIR)/tsh*.pkg --package $(BUILDDIR)/tctl*.pkg $(TELEPORT_TOOLS_PKG_UNSIGNED)
$(NOTARIZE_TELEPORT_TOOLS_PKG)
if [ -f e/Makefile ]; then $(MAKE) -C e pkg; fi
# build .rpm
.PHONY: rpm
rpm:
mkdir -p $(BUILDDIR)/
cp ./build.assets/build-package.sh ./build.assets/build-common.sh $(BUILDDIR)/
chmod +x $(BUILDDIR)/build-package.sh
cp -a ./build.assets/rpm $(BUILDDIR)/
cp -a ./build.assets/rpm-sign $(BUILDDIR)/
cd $(BUILDDIR) && ./build-package.sh -t oss -v $(VERSION) -p rpm -a $(ARCH) $(RUNTIME_SECTION) $(TARBALL_PATH_SECTION)
if [ -f e/Makefile ]; then $(MAKE) -C e rpm; fi
# build unsigned .rpm (for testing)
.PHONY: rpm-unsigned
rpm-unsigned:
$(MAKE) UNSIGNED_RPM=true rpm
# build open source .deb only
.PHONY: oss-deb
oss-deb:
mkdir -p $(BUILDDIR)/
cp ./build.assets/build-package.sh ./build.assets/build-common.sh $(BUILDDIR)/
chmod +x $(BUILDDIR)/build-package.sh
cd $(BUILDDIR) && ./build-package.sh -t oss -v $(VERSION) -p deb -a $(ARCH) $(RUNTIME_SECTION) $(TARBALL_PATH_SECTION)
# build .deb
.PHONY: deb
deb: oss-deb
if [ -f e/Makefile ]; then $(MAKE) -C e deb; fi
# check binary compatibility with different OSes
.PHONY: test-compat
test-compat:
./build.assets/build-test-compat.sh
.PHONY: ensure-webassets
ensure-webassets:
@if [[ "${WEBASSETS_SKIP_BUILD}" -eq 1 ]]; then mkdir -p webassets/teleport && mkdir -p webassets/teleport/app && cp web/packages/teleport/index.html webassets/teleport/index.html; \
else MAKE="$(MAKE)" "$(MAKE_DIR)/build.assets/build-webassets-if-changed.sh" OSS webassets/oss-sha build-ui web; fi
.PHONY: ensure-webassets-e
ensure-webassets-e:
@if [[ "${WEBASSETS_SKIP_BUILD}" -eq 1 ]]; then mkdir -p webassets/teleport && mkdir -p webassets/e/teleport/app && cp web/packages/teleport/index.html webassets/e/teleport/index.html; \
else MAKE="$(MAKE)" "$(MAKE_DIR)/build.assets/build-webassets-if-changed.sh" Enterprise webassets/e/e-sha build-ui-e web e/web; fi
# Enables the pnpm package manager if it is not already enabled and Corepack
# is available.
# We check if pnpm is enabled, as the user may not have permission to
# enable it, but it may already be available.
# Enabling it merely installs a shim which then needs to be downloaded before first use.
# Corepack typically prompts before downloading a package manager. We work around that
# by issuing a bogus pnpm call with an env var that skips the prompt.
.PHONY: ensure-js-package-manager
ensure-js-package-manager:
@if [ -z "$$(COREPACK_ENABLE_DOWNLOAD_PROMPT=0 pnpm -v 2>/dev/null)" ]; then \
if [ -n "$$(corepack --version 2>/dev/null)" ]; then \
echo 'Info: pnpm is not enabled via Corepack. Enabling pnpm…'; \
corepack enable pnpm; \
echo "pnpm $$(COREPACK_ENABLE_DOWNLOAD_PROMPT=0 pnpm -v)"; \
else \
echo 'Error: Corepack is not installed, cannot enable pnpm. See the installation guide https://pnpm.io/installation#using-corepack'; \
exit 1; \
fi; \
fi
.PHONY: init-submodules-e
init-submodules-e:
git submodule init e
git submodule update
# backport will automatically create backports for a given PR as long as you have the "gh" tool
# installed locally. To backport, type "make backport PR=1234 TO=branch/1,branch/2".
.PHONY: backport
backport:
(cd ./assets/backport && go run main.go -pr=$(PR) -to=$(TO))
.PHONY: ensure-js-deps
ensure-js-deps:
@if [[ "${WEBASSETS_SKIP_BUILD}" -eq 1 ]]; then mkdir -p webassets/teleport && touch webassets/teleport/index.html; \
else $(MAKE) ensure-js-package-manager && pnpm install --frozen-lockfile; fi
.PHONY: ensure-wasm-deps
ifeq ($(WEBASSETS_SKIP_BUILD),1)
ensure-wasm-deps:
else
ensure-wasm-deps: rustup-toolchain-warning ensure-wasm-bindgen ensure-wasm-opt
WASM_BINDGEN_VERSION = $(shell awk ' \
$$1 == "name" && $$3 == "\"wasm-bindgen\"" { in_pkg=1; next } \
in_pkg && $$1 == "version" { gsub(/"/, "", $$3); print $$3; exit } \
' Cargo.lock)
.PHONY: print-wasm-bindgen-version
print-wasm-bindgen-version:
@echo $(WASM_BINDGEN_VERSION)
RUST_TOOLCHAIN_VERSION = $(shell awk '$$1 == "channel" && $$2 == "=" { gsub(/"/, "", $$3); print $$3 }' rust-toolchain.toml )
.PHONY: print-rust-toolchain-version
print-rust-toolchain-version:
@echo $(RUST_TOOLCHAIN_VERSION)
ensure-wasm-bindgen: NEED_VERSION = $(WASM_BINDGEN_VERSION)
ensure-wasm-bindgen: INSTALLED_VERSION = $(word 2,$(shell wasm-bindgen --version 2>/dev/null))
ensure-wasm-bindgen:
@: $(or $(NEED_VERSION),$(error Unknown wasm-bindgen version. Is it in Cargo.lock?))
$(if $(filter-out $(INSTALLED_VERSION),$(NEED_VERSION)),\
cargo install wasm-bindgen-cli --force --locked --version "$(NEED_VERSION)", \
@echo wasm-bindgen-cli up-to-date: $(INSTALLED_VERSION) \
)
endif
.PHONY: ensure-wasm-opt
ensure-wasm-opt: WASM_OPT_VERSION := $(shell $(MAKE) --no-print-directory -C build.assets print-wasm-opt-version)
ensure-wasm-opt:
cargo install --locked wasm-opt@$(WASM_OPT_VERSION)
.PHONY: build-ui
build-ui: ensure-js-deps ensure-wasm-deps
@[ "${WEBASSETS_SKIP_BUILD}" -eq 1 ] || pnpm build-ui-oss
.PHONY: build-ui-e
build-ui-e: ensure-js-deps ensure-wasm-deps
@[ "${WEBASSETS_SKIP_BUILD}" -eq 1 ] || pnpm build-ui-e
.PHONY: docker-ui
docker-ui:
$(MAKE) -C build.assets ui
# TODO(rhammonds): Remove this target once all references to it have
# been removed from e submodule and e ref is updated.
.PHONY: rustup-set-version
rustup-set-version: ; # obsoleted by toolchain file
# rustup-install-target-toolchain ensures the required rust compiler is
# installed to build for $(ARCH)/$(OS) for the version of rust we use, as
# defined in build.assets/Makefile. It assumes that `rustup` is already
# installed for managing the rust toolchain.
.PHONY: rustup-install-target-toolchain
rustup-install-target-toolchain:
rustup target add $(RUST_TARGET_ARCH)
define rust_toolchain_warning
The active Rust toolchain version does not match the toolchain required
to build Teleport. This is likely caused by a directory override. You
can inspect your current overrides with 'rustup show active-toolchain'
and clear directory overrides with 'rustup override unset'
endef
export rust_toolchain_warning
# inspect the current active toolchain and display a warning if it doesn't
# match the version defined in our toolchain file.
.PHONY: rustup-toolchain-warning
rustup-toolchain-warning: EXPECTED = $(shell $(MAKE) print-rust-toolchain-version)
rustup-toolchain-warning:
@if [ "$(shell rustup show active-toolchain | cut -d'-' -f1)" != "$(EXPECTED)" ]; then \
echo -en "\033[31m";\
echo "$$rust_toolchain_warning";\
echo -en "\033[0m";\
fi
# changelog generates PR changelog between the provided base tag and the tip of
# the specified branch.
#
# usage: make changelog
# usage: make changelog BASE_BRANCH=branch/v13 BASE_TAG=v13.2.0
# usage: BASE_BRANCH=branch/v13 BASE_TAG=v13.2.0 make changelog
#
# BASE_BRANCH and BASE_TAG will be automatically determined if not specified.
.PHONY: changelog
changelog:
@go run github.com/gravitational/shared-workflows/tools/changelog@latest \
--base-branch="$(BASE_BRANCH)" --base-tag="$(BASE_TAG)" ./
# create-github-release will generate release notes from the CHANGELOG.md and will
# create release notes from them.
#
# usage: make create-github-release
# usage: make create-github-release LATEST=true
#
# If it detects that the first version in CHANGELOG.md
# does not match version set it will fail to create a release. If tag doesn't exist it
# will also fail to create a release.
#
# For more information on release notes generation see:
# https://github.com/gravitational/shared-workflows/tree/gus/release-notes/tools/release-notes#readme
.PHONY: create-github-release
create-github-release: LATEST = false
create-github-release: GITHUB_RELEASE_LABELS = ""
create-github-release:
@NOTES=$$( \
go run github.com/gravitational/shared-workflows/tools/release-notes@latest \
--labels=$(GITHUB_RELEASE_LABELS) $(VERSION) CHANGELOG.md \
) && gh release create v$(VERSION) \
-t "Teleport $(VERSION)" \
--latest=$(LATEST) \
--verify-tag \
-F - <<< "$$NOTES"
.PHONY: go-mod-tidy-all
go-mod-tidy-all:
find . -type "f" -name "go.mod" -execdir go mod tidy \;
.PHONY: dump-preset-roles
dump-preset-roles:
GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG) go run ./build.assets/dump-preset-roles/main.go
pnpm test web/packages/teleport/src/Roles/RoleEditor/StandardEditor/standardmodel.test.ts
cli-docs: cli-docs-tsh cli-docs-tbot cli-docs-teleport cli-docs-tctl
.PHONY: cli-docs-tsh
cli-docs-tsh:
# Executing go build instead of go run since we don't want to redirect
# irrelevant output along with the docs page content.
go build -o $(BUILDDIR)/tshdocs -tags docs ./tool/tsh && \
$(BUILDDIR)/tshdocs help >docs/pages/reference/cli/tsh.mdx && \
rm $(BUILDDIR)/tshdocs
.PHONY: cli-docs-tbot
cli-docs-tbot:
# Executing go build instead of go run since we don't want to redirect
# irrelevant output along with the docs page content.
go build -o $(BUILDDIR)/tbotdocs -tags docs ./tool/tbot && \
$(BUILDDIR)/tbotdocs help >docs/pages/reference/cli/tbot.mdx && \
rm $(BUILDDIR)/tbotdocs
.PHONY: cli-docs-teleport
cli-docs-teleport:
# Executing go build instead of go run since we don't want to redirect
# irrelevant output along with the docs page content.
go build -o $(BUILDDIR)/teleportdocs -tags docs ./tool/teleport && \
$(BUILDDIR)/teleportdocs help >docs/pages/reference/cli/teleport.mdx && \
rm $(BUILDDIR)/teleportdocs
.PHONY: cli-docs-tctl
cli-docs-tctl:
# Executing go build instead of go run since we don't want to redirect
# irrelevant output along with the docs page content.
go build -o $(BUILDDIR)/tctldocs -tags docs ./tool/tctl && \
$(BUILDDIR)/tctldocs help >docs/pages/reference/cli/tctl.mdx && \
rm $(BUILDDIR)/tctldocs
# cli-docs-up-to-date checks if the generated CLI reference docs are up to date.
.PHONY: cli-docs-up-to-date
cli-docs-up-to-date: must-start-clean/host cli-docs
@if ! git diff --quiet -- docs/pages/reference/cli/; then \
echo ""; \
echo "CLI reference documentation is out of date."; \
echo "Please run 'make cli-docs' and commit the changes."; \
echo ""; \
git diff --stat -- docs/pages/reference/cli/; \
exit 1; \
fi
# audit-event-reference generates audit event reference docs using the Web UI
# source.
.PHONY: audit-event-reference
audit-event-reference:
pnpm run -C ./web/packages/teleport event-reference
# audit-event-reference-up-to-date ensures the audit event reference
# documentation reflects the Web UI source.
.PHONY: audit-event-reference-up-to-date
audit-event-reference-up-to-date: must-start-clean/host audit-event-reference
@if ! git diff --quiet; then \
./build.assets/please-run.sh "audit event reference docs" "make audit-event-reference"; \
exit 1; \
fi
.PHONY: access-monitoring-reference
access-monitoring-reference:
cd ./build.assets/tooling/cmd/gen-athena-docs && go run main.go > ../../../../docs/pages/includes/access-monitoring-events.mdx
.PHONY: access-monitoring-reference-up-to-date
access-monitoring-reference-up-to-date: access-monitoring-reference
@if ! git diff --quiet; then \
./build.assets/please-run.sh "Access Monitoring event reference docs" "make access-monitoring-reference"; \
exit 1; \
fi
.PHONY: gen-docs
gen-docs: gen-resource-docs audit-event-reference
$(MAKE) -C integrations/terraform docs
$(MAKE) -C integrations/operator crd-docs
$(MAKE) -C examples/chart render-chart-ref
.PHONY: gen-resource-docs
gen-resource-docs:
cd build.assets/tooling/cmd/resource-ref-generator && go run . -config config.yaml
.PHONY: resource-docs-up-to-date
resource-docs-up-to-date: must-start-clean/host gen-resource-docs
@if ! git diff --quiet; then \
./build.assets/please-run.sh "tctl resource reference docs" "make gen-resource-docs"; \
exit 1; \
fi
.PHONY: benchstat
benchstat:
ifndef BENCH_FILES
$(error "Please provide BENCH_FILES=<file1> <file2> ...")
endif
@$(BENCHSTAT) $(BENCH_FILES) | tee test-logs/benchstat.txt