-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathMakefile
More file actions
325 lines (285 loc) · 14.7 KB
/
Copy pathMakefile
File metadata and controls
325 lines (285 loc) · 14.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# RHDH Must-Gather Tool Makefile
# Variables
VERSION ?= 2.1.0
GIT_SHA := $(shell git describe --no-match --always --abbrev=9 --dirty --broken 2>/dev/null || echo unknown)
RHDH_MUST_GATHER_VERSION := $(VERSION)-$(GIT_SHA)
SCRIPT ?=
REGISTRY ?= quay.io
IMAGE_NAME ?= rhdh-community/rhdh-must-gather
IMAGE_TAG ?= latest
FULL_IMAGE_NAME ?= $(REGISTRY)/$(IMAGE_NAME):$(IMAGE_TAG)
LOG_LEVEL ?= info
OPTS ?= ## Additional options to pass to must-gather (e.g., --with-heap-dumps --with-secrets)
NAMESPACE ?= ## Namespace for deploy-k8s/deploy-openshift (default: random for k8s, auto for openshift)
HELM_SET ?= ## Additional Helm --set flags for deploy-k8s (e.g., "gather.logLevel=debug")
OUTPUT_FILE ?= ## Output file for deploy-k8s (default: rhdh-must-gather-output.k8s.<timestamp>.tar.gz)
HELM_TIMEOUT ?= ## Timeout for Helm install/upgrade in deploy-k8s (default: 60m)
CONTAINER_TOOL ?= podman
BUILD_ARGS ?=
LABELS ?=
TOOLS_DIR ?= ./bin
BASE_COLLECTION_PATH ?= ./out
# Test configuration
BATS_VERSION := 1.13.0
BATS_CORE_URL := https://github.com/bats-core/bats-core/archive/refs/tags/v$(BATS_VERSION).tar.gz
BATS_BIN := $(TOOLS_DIR)/bats-core-$(BATS_VERSION)/bin/bats
TEST_RESULTS_DIR ?= ./test-results
TESTS_OPTIONS ?= --timing --print-output-on-failure --report-formatter junit --output "$(TEST_RESULTS_DIR)"
TESTS_DIR := ./tests
# Local tools configuration
# renovate: datasource=pypi depName=yq
YQ_VERSION := 3.4.3
YQ_VENV := $(TOOLS_DIR)/yq-venv
YQ_BIN := $(YQ_VENV)/bin/yq
# Host platform (must be defined before HELM_ARCHIVE_DIR / WEBSOCAT_ARCH)
OS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
ARCH := $(shell uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/')
# latest at https://github.com/helm/helm/releases
# if version set below is available as a binary in CGW, update the helm-lockfile via: make helm-lockfile-update
# if version set below is not available as a binary in CGW, vendor the helm source via: make vendor-update VENDOR_NAME=helm VENDOR_VERSION=v<NEW>
HELM_VERSION := 4.2.3
HELM_ARCHIVE_DIR := $(TOOLS_DIR)/helm-$(HELM_VERSION)-$(OS)-$(ARCH)
HELM_BIN_DL := $(HELM_ARCHIVE_DIR)/helm
HELM_BIN := $(TOOLS_DIR)/helm
WEBSOCAT_VERSION := 1.14.1
WEBSOCAT_ARCHIVE_DIR := $(TOOLS_DIR)/websocat-$(WEBSOCAT_VERSION)
WEBSOCAT_BIN_DL := $(WEBSOCAT_ARCHIVE_DIR)/websocat
WEBSOCAT_BIN := $(TOOLS_DIR)/websocat
# websocat uses different naming: x86_64-unknown-linux-musl, x86_64-apple-darwin, aarch64-apple-darwin
# Note: Apple Silicon returns 'arm64' but websocat uses 'aarch64'
WEBSOCAT_ARCH := $(shell uname -m | sed 's/arm64/aarch64/')-$(if $(filter darwin,$(OS)),apple-darwin,unknown-linux-musl)
default: run-local
##@ Development
.PHONY: local-output
local-output:
@mkdir -p ./out
.PHONY: local-setup
local-setup: $(YQ_BIN) $(HELM_BIN_DL) $(WEBSOCAT_BIN_DL) ## Download and setup required local tools (yq, helm, websocat)
.PHONY: run-local
run-local: local-output local-setup ## Test the script locally (requires jq, kubectl, oc and cluster access)
@echo "Testing must-gather script locally..."
@if ! command -v kubectl >/dev/null 2>&1; then \
echo "Error: kubectl not found. Please install kubectl to test."; \
exit 1; \
fi
@echo "Running local test (requires cluster access)..."
PATH="$(abspath $(YQ_VENV)/bin):$(abspath $(TOOLS_DIR)):$$PATH" \
BASE_COLLECTION_PATH=$(BASE_COLLECTION_PATH) \
LOG_LEVEL=$(LOG_LEVEL) \
RHDH_MUST_GATHER_VERSION=$(RHDH_MUST_GATHER_VERSION) \
./collection-scripts/must_gather $(OPTS)
.PHONY: run-script
run-script: local-output local-setup ## Test the specified gather-<SCRIPT> script (set the SCRIPT var)
@if [ -z "$(SCRIPT)" ]; then \
echo "Error: SCRIPT variable is not set. Please set the SCRIPT variable to the name of the script to test. It will then run ./collection-scripts/gather_<SCRIPT>"; \
exit 1; \
fi
@echo "Testing gather-${SCRIPT} must-gather script locally..."
@echo "Running local test (requires cluster access)..."
PATH="$(abspath $(YQ_VENV)/bin):$(abspath $(TOOLS_DIR)):$$PATH" \
BASE_COLLECTION_PATH=./out \
LOG_LEVEL=$(LOG_LEVEL)\
RHDH_MUST_GATHER_VERSION=$(RHDH_MUST_GATHER_VERSION) \
./collection-scripts/gather_${SCRIPT} $(OPTS)
# TODO(asoro): Consider adding this back. It currently fails due to permission issues inside the container.
# .PHONY: run-container
# run-container: image-build local-output ## Test using container (requires podman)
# @echo "Testing must-gather in container..."
# podman run --rm \
# -v $(HOME)/.kube:/home/must-gather/.kube:ro \
# -v $(PWD)/out:/must-gather \
# -e LOG_LEVEL=$(LOG_LEVEL) \
# $(IMAGE_NAME):$(IMAGE_TAG) \
# $(OPTS)
.PHONY: test-results
test-results:
@mkdir -p $(TEST_RESULTS_DIR)
.PHONY: test-setup
test-setup: test-results ## Download and setup the unit testing framework (BATS)
@echo "Setting up BATS testing framework..."
@if [ ! -d "$(TOOLS_DIR)/bats-core-$(BATS_VERSION)" ]; then \
echo "Downloading BATS v$(BATS_VERSION)..."; \
mkdir -p "$(TOOLS_DIR)/bats-core-$(BATS_VERSION)"; \
curl -sL $(BATS_CORE_URL) | tar xz -C "$(TOOLS_DIR)/bats-core-$(BATS_VERSION)" --strip-components=1; \
echo "BATS installed successfully"; \
else \
echo "BATS $(BATS_VERSION) already installed: $(TOOLS_DIR)/bats-core-$(BATS_VERSION)"; \
fi
.PHONY: test
test: test-setup ## Run all unit tests
@echo "Running BATS unit tests..."
@$(BATS_BIN) $(TESTS_OPTIONS) $(TESTS_DIR)/*.bats
LOCAL ?= true ## Set to 'false' to run E2E tests with container image instead of local mode
WITH_HEAP_DUMPS ?= ## Set to 'true' to enable heap dump collection and validation in E2E tests
HEAP_DUMP_METHOD ?= ## Heap dump method: 'inspector' (default) or 'sigusr2'
.PHONY: test-e2e
test-e2e: local-setup ## Run E2E tests against a K8s cluster (requires Kind or similar)
ifneq ($(LOCAL),false)
@echo "Running E2E tests in local mode..."
@PATH="$(abspath $(YQ_VENV)/bin):$(abspath $(TOOLS_DIR)):$$PATH" \
./tests/e2e/run-e2e-tests.sh --local \
$(if $(filter true,$(WITH_HEAP_DUMPS)),--with-heap-dumps) \
$(if $(HEAP_DUMP_METHOD),--heap-dump-method "$(HEAP_DUMP_METHOD)") \
$(if $(HELM_TIMEOUT),--helm-timeout "$(HELM_TIMEOUT)")
else
@echo "Running E2E tests with image: $(FULL_IMAGE_NAME)..."
@PATH="$(abspath $(YQ_VENV)/bin):$(abspath $(TOOLS_DIR)):$$PATH" \
./tests/e2e/run-e2e-tests.sh --image "$(FULL_IMAGE_NAME)" \
$(if $(TARGET_BRANCH),--target-branch "$(TARGET_BRANCH)") \
$(if $(OPERATOR_BRANCH),--operator-branch "$(OPERATOR_BRANCH)") \
$(if $(HELM_CHART_VERSION),--helm-chart-version "$(HELM_CHART_VERSION)") \
$(if $(HELM_VALUES_FILE),--helm-values-file "$(HELM_VALUES_FILE)") \
$(if $(filter true,$(WITH_HEAP_DUMPS)),--with-heap-dumps) \
$(if $(HEAP_DUMP_METHOD),--heap-dump-method "$(HEAP_DUMP_METHOD)") \
$(if $(HELM_TIMEOUT),--helm-timeout "$(HELM_TIMEOUT)")
endif
.PHONY: $(TOOLS_DIR)
$(TOOLS_DIR):
@mkdir -p "$(TOOLS_DIR)"
$(YQ_BIN): $(TOOLS_DIR)
@if [ ! -f "$(YQ_BIN)" ]; then \
echo "Installing yq (kislyuk/yq) via pip..."; \
python3 -m venv "$(YQ_VENV)"; \
"$(YQ_VENV)/bin/pip" install --quiet "yq==$(YQ_VERSION)"; \
echo "yq installed successfully: $$($(YQ_BIN) --version)"; \
else \
echo "yq already installed: $(YQ_BIN)"; \
fi
.PHONY: $(HELM_BIN_DL)
$(HELM_BIN_DL): $(TOOLS_DIR)
@mkdir -p "$(HELM_ARCHIVE_DIR)"
@if [ ! -f "$(HELM_BIN_DL)" ]; then \
./hack/install-helm-local.sh "$(HELM_VERSION)" "$(HELM_BIN_DL)" "$(OS)" "$(ARCH)"; \
else \
echo "helm $(HELM_VERSION) already installed: $(HELM_BIN_DL)"; \
fi
@ln -sf "$(shell echo $(HELM_BIN_DL) | sed 's|$(TOOLS_DIR)/||')" "$(HELM_BIN)"
@"$(HELM_BIN)" version --short
.PHONY: $(WEBSOCAT_BIN_DL)
$(WEBSOCAT_BIN_DL): $(TOOLS_DIR)
@mkdir -p "$(WEBSOCAT_ARCHIVE_DIR)"
@if [ ! -f "$(WEBSOCAT_BIN_DL)" ]; then \
echo "Downloading websocat v$(WEBSOCAT_VERSION) for $(WEBSOCAT_ARCH)..."; \
curl -sSL "https://github.com/vi/websocat/releases/download/v$(WEBSOCAT_VERSION)/websocat.$(WEBSOCAT_ARCH)" -o "$(WEBSOCAT_BIN_DL)"; \
chmod +x "$(WEBSOCAT_BIN_DL)"; \
echo "websocat installed successfully: $$($(WEBSOCAT_BIN_DL) --version)"; \
else \
echo "websocat $(WEBSOCAT_VERSION) already installed: $(WEBSOCAT_BIN_DL)"; \
fi
@ln -sf "$(shell echo $(WEBSOCAT_BIN_DL) | sed 's|$(TOOLS_DIR)/||')" "$(WEBSOCAT_BIN)"
@"$(WEBSOCAT_BIN)" --version
VENDOR_NAME ?= ## Vendor name for vendor-update (e.g., websocat)
VENDOR_VERSION ?= ## Vendor version for vendor-update (e.g., v1.14.1)
.PHONY: vendor
vendor: ## Sync vendored sources; refresh Helm CGW lockfile or vendor helm source
@if ./hack/check-helm-binary-available.sh "$(HELM_VERSION)"; then \
./hack/update-helm-lockfile.sh "v$(HELM_VERSION)"; \
else \
echo "CGW mirror has no helm v$(HELM_VERSION) binaries; vendoring helm source instead..."; \
./hack/update-vendor.sh helm "v$(HELM_VERSION)"; \
fi
./hack/update-vendor.sh websocat "v$(WEBSOCAT_VERSION)"
.PHONY: helm-lockfile-update
helm-lockfile-update: ## Refresh artifacts.lock.yaml for Helm CGW binaries (HELM_VERSION from Makefile)
./hack/update-helm-lockfile.sh "v$(HELM_VERSION)"
.PHONY: vendor-update
vendor-update: ## Sync a single vendored subtree to a specific version (VENDOR_NAME, VENDOR_VERSION required)
@if [ -z "$(VENDOR_NAME)" ] || [ -z "$(VENDOR_VERSION)" ]; then \
echo "Error: VENDOR_NAME and VENDOR_VERSION are required."; \
echo "Usage: make vendor-update VENDOR_NAME=websocat VENDOR_VERSION=v1.14.1"; \
echo " make vendor-update VENDOR_NAME=helm VENDOR_VERSION=v4.2.3"; \
exit 1; \
fi
./hack/update-vendor.sh "$(VENDOR_NAME)" "$(VENDOR_VERSION)"
##@ Build
.PHONY: image-build
image-build: ## Build the must-gather container image
@echo "Building must-gather image..."
$(CONTAINER_TOOL) build $(BUILD_ARGS) $(if $(LABELS),$(LABELS)) --build-arg RHDH_MUST_GATHER_VERSION=$(RHDH_MUST_GATHER_VERSION) -t $(IMAGE_NAME):$(IMAGE_TAG) .
@echo "Image built: $(IMAGE_NAME):$(IMAGE_TAG)"
.PHONY: image-push
image-push: image-build ## Build and push the image to registry
@echo "Tagging image for registry..."
$(CONTAINER_TOOL) tag $(IMAGE_NAME):$(IMAGE_TAG) $(FULL_IMAGE_NAME)
@echo "Pushing image to registry..."
$(CONTAINER_TOOL) push $(FULL_IMAGE_NAME)
@echo "Image pushed: $(FULL_IMAGE_NAME)"
##@ Deployment
.PHONY: deploy-openshift
deploy-openshift: ## Deploy the must-gather image using the 'oc adm must-gather' command
@echo "Deploying the must-gather image with oc adm must-gather..."
@if ! command -v oc >/dev/null 2>&1; then \
echo "Error: oc command not found. Please install OpenShift CLI."; \
exit 1; \
fi
oc adm must-gather --image=$(FULL_IMAGE_NAME) $(if $(NAMESPACE),--run-namespace=$(NAMESPACE)) $(if $(OPTS),-- /usr/bin/gather $(OPTS))
.PHONY: deploy-k8s
deploy-k8s: ## Deploy the must-gather image on a non-OCP K8s cluster (uses Helm chart)
@if ! command -v kubectl >/dev/null 2>&1; then \
echo "Error: kubectl command not found. Please install kubectl."; \
exit 1; \
fi
@if ! command -v helm >/dev/null 2>&1; then \
echo "Error: helm command not found. Please install Helm."; \
exit 1; \
fi
@./hack/deploy-k8s.sh --image "$(FULL_IMAGE_NAME)" $(if $(NAMESPACE),--namespace "$(NAMESPACE)") $(if $(OPTS),--opts "$(OPTS)") $(if $(HELM_SET),--helm-set "$(HELM_SET)") $(if $(OUTPUT_FILE),--output "$(OUTPUT_FILE)") $(if $(HELM_TIMEOUT),--timeout "$(HELM_TIMEOUT)")
##@ Cleanup
.PHONY: clean-out
clean-out: ## Remove the local output directory
-rm -rf ./out
@echo "Local output directory cleaned"
.PHONY: clean
clean: clean-out ## Remove built images and test output
@echo "Cleaning up..."
-podman rmi $(IMAGE_NAME):$(IMAGE_TAG) 2>/dev/null || true
-podman rmi $(FULL_IMAGE_NAME) 2>/dev/null || true
-rm -rf "$(TOOLS_DIR)"
-rm -rf "$(TEST_RESULTS_DIR)"
@echo "Cleanup complete"
##@ General
# The help target prints out all targets with their descriptions organized
# beneath their categories. The categories are represented by '##@' and the
# target descriptions by '##'. The awk command is responsible for reading the
# entire set of makefiles included in this invocation, looking for lines of the
# file as xyz: ## something, and then pretty-format the target and help. Then,
# if there's a line with ##@ something, that gets pretty-printed as a category.
# More info on the usage of ANSI control characters for terminal formatting:
# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
# More info on the awk command:
# http://linuxcommand.org/lc3_adv_awk.php
.PHONY: help
help: ## Display this help.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
@echo ""
@echo "Variables:"
@echo " VERSION - Must-gather version (default: $(VERSION))"
@echo " RHDH_MUST_GATHER_VERSION - Full version with git SHA (computed: $(RHDH_MUST_GATHER_VERSION))"
@echo " REGISTRY - Container registry (default: $(REGISTRY))"
@echo " IMAGE_NAME - Container image name (default: $(IMAGE_NAME))"
@echo " IMAGE_TAG - Container image tag (default: $(IMAGE_TAG))"
@echo " LOG_LEVEL - Log level (default: $(LOG_LEVEL))"
@echo " OPTS - Additional must-gather options (e.g., --with-heap-dumps --with-secrets)"
@echo " NAMESPACE - Namespace for deploy-k8s/deploy-openshift (default: random for k8s, auto for openshift)"
@echo " HELM_SET - Additional Helm --set flags for deploy-k8s (e.g., \"gather.logLevel=debug\")"
@echo " OUTPUT_FILE - Output file for deploy-k8s (default: rhdh-must-gather-output.k8s.<timestamp>.tar.gz)"
@echo " HELM_TIMEOUT - Timeout for Helm install/upgrade in deploy-k8s (default: 60m)"
@echo " TARGET_BRANCH - Target branch for test-e2e defaults (default: main)"
@echo " OPERATOR_BRANCH - Override RHDH operator branch for test-e2e"
@echo " HELM_CHART_VERSION - Override Helm chart version for test-e2e"
@echo " HELM_VALUES_FILE - Override Helm values file for test-e2e"
@echo " LOCAL - Set to 'false' to run test-e2e with container image (default: true, local mode)"
@echo " SCRIPT - Script name for run-script"
@echo " TOOLS_DIR - Directory for local tools like websocat and yq (default: $(TOOLS_DIR))"
@echo " VENDOR_NAME - Vendor name for vendor-update (e.g., websocat)"
@echo " VENDOR_VERSION - Vendor version for vendor-update (e.g., v1.14.1)"
@echo ""
@echo "Examples:"
@echo " make test # Run all unit tests"
@echo " make test-e2e # Run E2E tests in local mode (default)"
@echo " make test-e2e LOCAL=false FULL_IMAGE_NAME=quay.io/org/img:tag # Run E2E tests with container image"
@echo " make deploy-k8s OPTS=\"--with-heap-dumps\" # Run deploy-k8s with heap dumps"
@echo " make deploy-k8s NAMESPACE=my-ns # Run deploy-k8s in a specific namespace"
@echo " make run-local OPTS=\"--with-heap-dumps\""
# @echo " make run-container OPTS=\"--with-secrets --with-heap-dumps\""
@echo " make deploy-openshift OPTS=\"--with-heap-dumps --namespaces my-ns\""