-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathTiltfile
More file actions
281 lines (254 loc) · 11.1 KB
/
Copy pathTiltfile
File metadata and controls
281 lines (254 loc) · 11.1 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
# Load necessary Tilt extensions
load("ext://restart_process", "docker_build_with_restart")
load("ext://helm_resource", "helm_resource", "helm_repo")
load('ext://k8s_attach', 'k8s_attach')
load("ext://configmap", "configmap_create")
# Disable Tilt analytics
# Ref: https://docs.tilt.dev/telemetry_faq.html
analytics_settings(enable=False)
# A list of directories where changes trigger a hot-reload of PATH.
# IMPORTANT_DEV_NOTE: this list needs to be updated each time a new package is added to the repo.
hot_reload_dirs = [
"./local/path/.config.yaml",
"./local/path/.values.yaml",
"./local/guard",
"./local/observability",
"./cmd",
"./config",
"./data",
"./gateway",
"./health",
"./log",
"./message",
"./metrics",
"./network",
"./observation",
"./protocol",
"./proto",
"./qos",
"./relayer",
"./request",
"./router",
"./websockets",
]
# merge_dicts updates the base dictionary with the updates dictionary.
def merge_dicts(base, updates):
for k, v in updates.items():
if k in base and type(base[k]) == "dict" and type(v) == "dict":
# Assume nested dict and merge
for vk, vv in v.items():
base[k][vk] = vv
else:
# Replace or set the value
base[k] = v
# Get the helm charts path from environment variable if set
helm_charts_path = os.getenv("LOCAL_HELM_CHARTS_PATH", "")
# Define configuration values directly
hot_reloading_enabled = True
path_count = 1
delve_enabled = False
observability_enabled = True
grafana_default_dashboards_enabled = False
# Determine whether to use local helm charts based on environment variable
use_local_helm_charts = helm_charts_path and helm_charts_path != ""
local_helm_charts_path = helm_charts_path if use_local_helm_charts else "../helm-charts"
if use_local_helm_charts:
print("Using helm charts from environment variable: {}".format(helm_charts_path))
else:
print("Not using local helm charts (env var empty)")
# Configure helm chart reference.
# If using a local repo, set the path to the local repo; otherwise, use our own helm repo.
helm_repo(
"buildwithgrove",
"https://buildwithgrove.github.io/helm-charts/",
labels=["configuration"],
)
chart_prefix = "buildwithgrove/"
if use_local_helm_charts:
chart_prefix = local_helm_charts_path + "/charts/"
# TODO_TECHDEBT(@okdas): Find a way to make this cleaner & performant w/ selective builds.
local("cd " + chart_prefix + "guard && helm dependency update")
local("cd " + chart_prefix + "path && helm dependency update")
local("cd " + chart_prefix + "watch && helm dependency update")
hot_reload_dirs.append(local_helm_charts_path)
print("Using local helm chart repo {}".format(local_helm_charts_path))
# The folder containing the local configuration files.
LOCAL_DIR = "local"
# The folder containing PATH's local configuration files.
PATH_LOCAL_DIR = LOCAL_DIR + "/path" # ./local/path
# The configuration file for PATH.
PATH_LOCAL_CONFIG_FILE = PATH_LOCAL_DIR + "/.config.yaml" # ./local/path/.config.yaml
# --------------------------------------------------------------------------- #
# Configuration Resources #
# --------------------------------------------------------------------------- #
# 1. PATH Config Updater #
# 2. Patch Envoy Gateway LoadBalancer #
# --------------------------------------------------------------------------- #
# Start a Tilt resource to update the PATH config with the local config file.
local_resource(
'path-config-updater',
'''
kubectl delete secret path-config --ignore-not-found=true && \
kubectl create secret generic path-config --from-file=.config.yaml=./local/path/.config.yaml && \
kubectl get deployment path > /dev/null 2>&1 && \
kubectl rollout restart deployment path || \
echo "Deployment not found - skipping rollout restart"
''',
deps=[PATH_LOCAL_CONFIG_FILE],
labels=["configuration"],
)
# Start a Tilt resource to patch the Envoy Gateway LoadBalancer resource
# to ensure it is reachable from outside the cluster at "localhost:3070".
#
# For more context, see the comments at:
# `./local/scripts/patch_envoy_gateway.sh`.
#
# TODO_TECHDEBT(@okdas): Remove this and the associated script once helm charts are updated.
local_resource(
"patch-envoy-gateway",
"./local/scripts/patch_envoy_gateway.sh",
resource_deps=["path-stack"],
labels=["configuration"],
)
# ----------------------------------------------------------------------------------- #
# PATH Resources #
# ----------------------------------------------------------------------------------- #
# The following resources are installed from the PATH Helm chart. #
# Repo: https://github.com/buildwithgrove/helm-charts/tree/main/charts/path #
# ----------------------------------------------------------------------------------- #
# 1. PATH (PATH API & Toolkit Harness): RPC/API Gateway #
# 2. GUARD (Gateway Utilities for Authentication, Routing & Defense): Envoy Gateway #
# 3. WATCH (Workload Analytics and Telemetry for Comprehensive Health): Observability #
# ----------------------------------------------------------------------------------- #
# TODO_TECHDEBT: Consolidate Dockerfile.local and Dockerfile
# Build the PATH image using Dockerfile.local (which handles CGO_ENABLED=1)
# Include go.mod and go.sum in the build context along with hot_reload_dirs
build_context_files = hot_reload_dirs + ["./go.mod", "./go.sum", "./Dockerfile.local"]
docker_build(
"path-image",
context=".",
dockerfile="Dockerfile.local",
only=build_context_files, # Only rebuild the image when these files/directories change
)
# Tilt will run the Helm Chart with the following flags by default.
#
# For example:
# helm install path buildwithgrove/path \
# --set config.fromSecret.enabled=true \
# --set config.fromSecret.name=path-config \
# --set config.fromSecret.key=.config.yaml
flags = [
# TODO_TECHDEBT: Look for a way to make helm secret size smaller for local development.
# Reduce Helm secret size for local development
# "--skip-crds",
# "--atomic=false",
# Enable GUARD resources.
"--set", "guard.enabled=true",
# Enable PATH to load the config from a secret.
# PATH supports loading the config from either a Secret or a ConfigMap.
# See: https://github.com/buildwithgrove/helm-charts/blob/main/charts/path/values.yaml
"--set", "config.fromSecret.enabled=true",
"--set", "config.fromSecret.name=path-config",
"--set", "config.fromSecret.key=.config.yaml",
# Always use the local image.
"--set", "global.imagePullPolicy=Never",
# TODO_TECHDEBT: Respect local_config["observability"]
# "--set", "observability.enabled=" + str(local_config["observability"]["enabled"]),
# "--set", "grafana.defaultDashboardsEnabled=" + str(local_config["observability"]["grafana"]["defaultDashboardsEnabled"]),
]
# Optional: Use a local values.yaml file to override the default values.
#
# For example, Tilt will append the flags:
# --values ./local/path/.values.yaml --reset-values
# to the Helm command if the file exists.
valuesFile = "./local/path/.values.yaml"
if read_yaml(valuesFile, default=None) != None:
flags.append("--reset-values") # Ensure that values are overridden by the .values.yaml file.
flags.append("--values")
flags.append(valuesFile)
# Run PATH Helm chart, including GUARD & WATCH.
helm_resource(
"path",
chart_prefix + "path",
image_deps=["path-image"],
image_keys=[("image.repository", "image.tag")],
links=[
link(
# Forward port 3003 to Grafana's port 3000.
# Port 3000 is already used by kind cluster's control plane.
"http://localhost:3003/d/relays/path-service-requests?orgId=1",
"Grafana dashboard",
),
],
flags=flags,
resource_deps=["path-config-updater"],
labels=["path"],
)
update_settings(
k8s_upsert_timeout_secs=90,
)
# --------------------------------------------------------------------------- #
# Logs Resources #
# --------------------------------------------------------------------------- #
# 1. PATH Logs #
# 2. GUARD (Envoy Gateway) Logs #
# 3. WATCH (Observability) Logs #
# --------------------------------------------------------------------------- #
# 1.PATH Logs
# Uses a `k8s_resource` to display logs for the `path` pod.
k8s_resource(
workload="path",
new_name="path-stack",
# Port 6060 is exposed to serve pprof data.
# Run the following commands to view the pprof data:
# $ make debug_goroutines
port_forwards=["6060:6060"],
extra_pod_selectors=[{"app.kubernetes.io/name": "path"}],
labels=["path"]
)
# Attach the proper port forwards to Grafana
# TODO_TECHDEBT(@okdas): Remove admin/password requirements.
k8s_attach(
'path-grafana',
'deployment/path-grafana',
namespace='path',
port_forwards="3003:3000",
resource_deps=["path-stack"]
)
# 2. GUARD Logs - Waits for container readiness before following logs
local_resource(
"guard-logs",
cmd="echo 'Preparing to follow GUARD logs when pods are ready...'",
serve_cmd='''
echo "Waiting for GUARD pods to be fully ready..."
until kubectl get pods -l 'app.kubernetes.io/name in (envoy,gateway-helm)' -o jsonpath='{.items[*].status.containerStatuses[*].ready}' 2>/dev/null | grep -q true; do
echo "GUARD pods not ready yet..."; sleep 5
done
echo "GUARD pods ready, stabilizing..."; sleep 10
echo "Following GUARD logs..."
kubectl logs -l 'app.kubernetes.io/name in (envoy,gateway-helm)' --follow
''',
labels=["k8s_logs"],
resource_deps=["path-stack"]
)
# # 3. WATCH Logs - Waits for container readiness before following logs
# local_resource(
# "watch-logs",
# cmd="echo 'Preparing to follow WATCH logs when pods are ready...'",
# serve_cmd='''
# echo "Waiting for WATCH pods to be fully ready..."
# until kubectl get pod -l app.kubernetes.io/name=grafana -o jsonpath='{.items[0].status.phase}' 2>/dev/null | grep -q Running &&
# kubectl get pod -l app.kubernetes.io/name=grafana -o jsonpath='{.items[0].status.containerStatuses[0].ready}' 2>/dev/null | grep -q true; do
# sleep 5
# done
# echo "Checking other components..."
# until kubectl get pods -l 'app.kubernetes.io/name in (kube-state-metrics,prometheus-node-exporter)' -o jsonpath='{.items[*].status.phase}' 2>/dev/null | tr ' ' '\n' | grep -v Running | wc -l | grep -q "^0$"; do
# sleep 5
# done
# echo "All pods ready, stabilizing..."; sleep 20
# echo "Following WATCH logs..."
# kubectl logs -l 'app.kubernetes.io/name in (grafana,kube-state-metrics,prometheus-node-exporter)' --follow
# ''',
# labels=["k8s_logs"],
# resource_deps=["path-stack"]
# )