-
Notifications
You must be signed in to change notification settings - Fork 3
/
Makefile
247 lines (214 loc) · 10.9 KB
/
Makefile
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
# --- Global Variables ---
DEPLOYMENT_ENVIRONMENT := kind
LOWERCASE_GITHUB_REPOSITORY := $(shell echo ${GITHUB_REPOSITORY} | tr '[:upper:]' '[:lower:]')
REPO_NAME := $(shell echo ${LOWERCASE_GITHUB_REPOSITORY} | awk -F '/' '{print $$2}')
REPO_ORG := $(shell echo ${LOWERCASE_GITHUB_REPOSITORY} | awk -F '/' '{print $$1}')
PULUMI_STACK_IDENTIFIER := ${GITHUB_USER}/${REPO_NAME}/${DEPLOYMENT_ENVIRONMENT}
# Escape special characters in sensitive tokens
ESCAPED_PAT := $(shell echo "${PULUMI_ACCESS_TOKEN}" | sed -e 's/[\/&]/\\&/g')
ESCAPED_GITHUB_TOKEN := $(shell echo "${GITHUB_TOKEN}" | sed -e 's/[\/&]/\\&/g')
# Define file paths for configurations
TALOS_CONFIG_FILE := ${PWD}/.talos/config
KUBE_CONFIG_FILE := ${PWD}/.kube/config
# Check if PULUMI_ACCESS_TOKEN is set
ifeq ($(ESCAPED_PAT),)
$(warning PULUMI_ACCESS_TOKEN is not set)
endif
# Check if GITHUB_TOKEN is set
ifeq ($(ESCAPED_GITHUB_TOKEN),)
$(warning GITHUB_TOKEN is not set)
endif
# --- Targets ---
.PHONY: help detect-arch pulumi-login pulumi-up up talos-gen-config talos-cluster kind-cluster clean clean-all act konductor test-kind test-talos stop
# --- Default Command ---
all: help
# --- Help ---
# Display available commands
help:
@echo "Available commands:"
@echo " help - Display this help message."
@echo " login - Authenticate with Pulumi."
@echo " esc ENV=foobar - Run Pulumi ESC environment. Default: ENV='kubernetes'."
@echo " up - Deploy Pulumi infrastructure."
@echo " pulumi-down - Destroy deployed Pulumi infrastructure."
@echo " talos-cluster - Deploy a Talos Kubernetes cluster."
@echo " talos-config - Generate and validate Talos configuration."
@echo " talos - Create and configure a Talos Kubernetes cluster."
@echo " kind - Create a local Kubernetes cluster using Kind."
@echo " clean - Clean up resources."
@echo " clean-all - Perform 'clean' and remove Docker volumes."
@echo " act - Test GitHub Actions locally."
@echo " konductor - Maintain .github/devcontainer submodule."
@echo " test - Run setup tests."
@echo " stop - Stop Github Codespaces."
# --- Detect Architecture ---
detect-arch:
@echo $(shell uname -m | awk '{ if ($$1 == "x86_64") print "amd64"; else if ($$1 == "aarch64" || $$1 == "arm64") print "arm64"; else print "unknown" }')
# --- Pulumi Login ---
pulumi-login:
@echo "Logging into Pulumi..."
@direnv allow || true
@PULUMI_ACCESS_TOKEN=${PULUMI_ACCESS_TOKEN} pulumi login \
| sed 's/${ESCAPED_PAT}/***PULUMI_ACCESS_TOKEN***/g' || true
@pulumi install || true
@echo "Login successful."
# --- Pulumi Deployment ---
pulumi-up:
@echo "Deploying Pulumi infrastructure..."
@pulumi stack select --create ${PULUMI_STACK_IDENTIFIER} || true
@KUBECONFIG=${KUBE_CONFIG_FILE} PULUMI_ACCESS_TOKEN=${PULUMI_ACCESS_TOKEN} \
pulumi up --yes --skip-preview --refresh --stack ${PULUMI_STACK_IDENTIFIER} \
| sed 's/${ESCAPED_PAT}/***PULUMI_ACCESS_TOKEN***/g'
@echo "Deployment complete."
pulumi-down:
@echo "Deploying Pulumi infrastructure..."
@pulumi stack select --create ${PULUMI_STACK_IDENTIFIER} || true
@KUBECONFIG=${KUBE_CONFIG_FILE} PULUMI_ACCESS_TOKEN=${PULUMI_ACCESS_TOKEN} \
pulumi down --yes --skip-preview --refresh --stack ${PULUMI_STACK_IDENTIFIER} \
| sed 's/${ESCAPED_PAT}/***PULUMI_ACCESS_TOKEN***/g' || \
KUBECONFIG=${KUBE_CONFIG_FILE} PULUMI_ACCESS_TOKEN=${PULUMI_ACCESS_TOKEN} PULUMI_K8S_DELETE_UNREACHABLE=true \
pulumi down --yes --skip-preview --refresh --stack ${PULUMI_STACK_IDENTIFIER} \
| sed 's/${ESCAPED_PAT}/***PULUMI_ACCESS_TOKEN***/g' || true
@echo "Deployment complete."
login: pulumi-login
up: pulumi-login pulumi-up wait-all-pods
down: pulumi-login pulumi-down
# ----------------------------------------------------------------------------------------------
# --- Control Flow ---
# ----------------------------------------------------------------------------------------------
# --- Wait for All Pods Ready ---
wait-all-pods:
@echo "Waiting for all pods in the cluster to be ready..."
@bash -c 'until [ "$$(kubectl get pods --all-namespaces --no-headers | grep -v "Running\|Completed\|Succeeded" | wc -l)" -eq 0 ]; do echo "Waiting for pods to be ready..."; sleep 5; done'
@kubectl get pods --all-namespaces --show-labels --kubeconfig ${KUBE_CONFIG_FILE}
@echo "All pods in the cluster are ready."
# ----------------------------------------------------------------------------------------------
# --- Talos Kubernetes Cluster ---
# ----------------------------------------------------------------------------------------------
# --- Talos Configuration ---
talos-gen-config:
@echo "Generating Talos Config..."
@mkdir -p ${HOME}/.kube .kube .pulumi .talos
@touch ${HOME}/.kube/config ${KUBE_CONFIG_FILE} ${TALOS_CONFIG_FILE}
@chmod 600 ${HOME}/.kube/config ${KUBE_CONFIG_FILE} ${TALOS_CONFIG_FILE}
@sudo talosctl gen config kargo https://10.5.0.2:6443 \
--config-patch @.talos/patch/machine.yaml --force --output .talos/manifest
@sudo talosctl validate --mode container \
--config .talos/manifest/controlplane.yaml
@echo "Talos Config generated."
# --- Talos Cluster in Docker ---
talos-cluster-docker:
@echo "Creating Talos Kubernetes Cluster in Docker..."
@ARCH=$$(uname -m | awk '{ if ($$1 == "x86_64") print "amd64"; else if ($$1 == "aarch64" || $$1 == "arm64") print "arm64"; else print "unknown" }'); \
set -ex; direnv allow; \
talosctl cluster create \
--arch=$$ARCH \
--workers 1 \
--controlplanes 1 \
--provisioner docker; echo "Talos Cluster created."
@pulumi config set kubernetes talos || true
@echo "Talos Cluster provisioning in Docker..."
# --- Talos Cluster in Docker ---
talos-cluster-qemu:
@echo "Creating Talos Kubernetes Cluster in QEMU..."
@ARCH=$$(uname -m | awk '{ if ($$1 == "x86_64") print "amd64"; else if ($$1 == "aarch64" || $$1 == "arm64") print "arm64"; else print "unknown" }'); \
set -ex; direnv allow; \
sudo -E talosctl cluster create \
--arch=$$ARCH \
--workers 1 \
--controlplanes 1 \
--provisioner docker; echo "Talos Cluster created."
@pulumi config set kubernetes talos || true
@echo "Talos Cluster provisioning in QEMU..."
# --- Wait for Talos Cluster Ready ---
talos-ready:
@echo "Waiting for Talos Cluster to be ready..."
@bash -c 'until kubectl --kubeconfig ${KUBE_CONFIG_FILE} wait --for=condition=Ready pod -l k8s-app=kube-scheduler --namespace=kube-system --timeout=180s; do echo "Waiting for kube-scheduler to be ready..."; sleep 5; done'
@bash -c 'until kubectl --kubeconfig ${KUBE_CONFIG_FILE} wait --for=condition=Ready pod -l k8s-app=kube-controller-manager --namespace=kube-system --timeout=180s; do echo "Waiting for kube-controller-manager to be ready..."; sleep 5; done'
@bash -c 'until kubectl --kubeconfig ${KUBE_CONFIG_FILE} wait --for=condition=Ready pod -l k8s-app=kube-apiserver --namespace=kube-system --timeout=180s; do echo "Waiting for kube-apiserver to be ready..."; sleep 5; done'
@echo "Talos Cluster is ready."
# --- Talos Cluster Clenup ---
talos-clean:
@echo "Cleaning up Talos Cluster..."
sudo talosctl cluster destroy --force --cluster talos-default
sudo talosctl config remove --noconfirm talos-default
sudo rm -rf /home/vscode/.talos/clusters
sudo echo > ${TALOS_CONFIG_FILE}
@echo "Talos Cluster cleaned up."
# --- Talos ---
talos: talos-gen-config talos-cluster talos-ready wait-all-pods
@echo "Talos Cluster ready."
# ----------------------------------------------------------------------------------------------
# --- Kind Kubernetes Cluster ---
# ----------------------------------------------------------------------------------------------
# --- Kind Cluster ---
kind-cluster:
@echo "Creating Kind Cluster..."
@direnv allow
@mkdir -p ${HOME}/.kube .kube || true
@touch ${HOME}/.kube/config .kube/config || true
@chmod 600 ${HOME}/.kube/config .kube/config || true
@sudo docker volume create pulumi-worker-n01
@sudo docker volume create pulumi-worker-n02
@sudo docker volume create pulumi-control-plane-n01
@sudo kind create cluster --config=.github/hack/kind.yaml
@sudo kind get clusters
@sudo kind get kubeconfig --name pulumi | tee ${KUBE_CONFIG_FILE} 1>/dev/null
@sudo kind get kubeconfig --name pulumi | tee ${HOME}/.kube/config 1>/dev/null
@sudo chown -R $(id -u):$(id -g) ${KUBE_CONFIG_FILE}
@echo "Created Kind Cluster."
# --- Wait for Kind Cluster Ready ---
kind-ready:
@echo "Waiting for Kind Kubernetes API to be ready..."
@kubectl get all --all-namespaces --show-labels --kubeconfig ${KUBE_CONFIG_FILE} || sleep 5
@bash -c 'until kubectl --kubeconfig ${KUBE_CONFIG_FILE} wait --for=condition=Ready pod -l component=kube-apiserver --namespace=kube-system --timeout=180s; do echo "Waiting for kube-apiserver to be ready..."; sleep 5; done'
@bash -c 'until kubectl --kubeconfig ${KUBE_CONFIG_FILE} wait --for=condition=Ready pod -l component=kube-scheduler --namespace=kube-system --timeout=180s; do echo "Waiting for kube-scheduler to be ready..."; sleep 5; done'
@bash -c 'until kubectl --kubeconfig ${KUBE_CONFIG_FILE} wait --for=condition=Ready pod -l component=kube-controller-manager --namespace=kube-system --timeout=180s; do echo "Waiting for kube-controller-manager to be ready..."; sleep 5; done'
@echo "Kind Cluster is ready."
kind: kind-cluster kind-ready
# ----------------------------------------------------------------------------------------------
# --- Maintenance ---
# ----------------------------------------------------------------------------------------------
# --- Cleanup ---
clean: login down
@echo "Cleaning up resources..."
@sudo kind delete cluster --name pulumi \
|| echo "Kind cluster not found."
@sudo kind delete cluster --name kind \
|| echo "Kind cluster not found."
@sudo talosctl cluster destroy \
|| echo "Talos cluster not found."
@echo "Cleanup complete."
clean-all: clean
@echo "Performing extended cleanup..."
@sudo docker volume rm pulumi-worker-n01 pulumi-worker-n02 pulumi-control-plane-n01 \
|| echo "Docker volumes not found."
@rm -rf Pulumi.*.yaml
@echo "Extended cleanup complete."
# --- GitHub Actions Testing ---
act:
@echo "Testing GitHub Workflows locally..."
@direnv allow
@GITHUB_TOKEN=${GITHUB_TOKEN} PULUMI_ACCESS_TOKEN=${PULUMI_ACCESS_TOKEN} \
act --container-options "--privileged" --rm \
--var GITHUB_TOKEN=${GITHUB_TOKEN} \
--var PULUMI_ACCESS_TOKEN=${PULUMI_ACCESS_TOKEN} \
| sed 's/${ESCAPED_PAT}/***PULUMI_ACCESS_TOKEN***/g'
@echo "GitHub Workflow Test Complete."
# --- Maintain Devcontainer ---
konductor:
@git submodule update --init .github/konductor
@git submodule update --remote --merge .github/konductor
@rsync -av .github/konductor/.devcontainer/* .devcontainer
@docker pull ghcr.io/containercraft/konductor:latest
@echo "Devcontainer updated."
# --- Testing ---
test-kind: kind pulumi-up
@echo "Kind test complete."
test-talos: talos pulumi-up
@echo "Talos test complete."
# --- Stop Codespaces ---
stop: clean
@echo "Stopping Codespaces..."
@gh codespace --codespace ${CODESPACE_NAME} stop
@echo "Codespaces stopped."