@@ -113,6 +113,22 @@ COPY --from=tilt-helper /usr/bin/kubectl /usr/bin/kubectl
113
113
},
114
114
}
115
115
116
+ # Create a data structure to hold information about addons.
117
+ addons = {
118
+ "test-extension" : {
119
+ "context" : "./test/extension" ,
120
+ "image" : "gcr.io/k8s-staging-cluster-api/test-extension" ,
121
+ "container_name" : "extension" ,
122
+ "live_reload_deps" : ["main.go" , "handlers" ],
123
+ "label" : "test-extension" ,
124
+ "resource_deps" : ["capi_controller" ],
125
+ "additional_resources" : [
126
+ "config/tilt/extensionconfig.yaml" ,
127
+ "config/tilt/hookresponses-configmap.yaml" ,
128
+ ],
129
+ },
130
+ }
131
+
116
132
def ensure_clusterctl ():
117
133
local ("make clusterctl" )
118
134
@@ -128,6 +144,7 @@ def ensure_clusterctl():
128
144
# ]
129
145
# }
130
146
# }
147
+
131
148
def load_provider_tiltfiles ():
132
149
provider_repos = settings .get ("provider_repos" , [])
133
150
@@ -145,12 +162,31 @@ def load_provider_tiltfiles():
145
162
provider_config ["context" ] = repo + "/" + provider_config ["context" ]
146
163
else :
147
164
provider_config ["context" ] = repo
148
- if "kustomize_config" not in provider_config :
149
- provider_config ["kustomize_config" ] = True
150
165
if "go_main" not in provider_config :
151
166
provider_config ["go_main" ] = "main.go"
152
167
providers [provider_name ] = provider_config
153
168
169
+ # load_addon_tiltfiles looks for tilt-addon.[yaml|json] files in the repositories listed in "addon_repos" in tilt settings and loads their config.
170
+ def load_addon_tiltfiles ():
171
+ addon_repos = settings .get ("addon_repos" , [])
172
+ for repo in addon_repos :
173
+ file = repo + "/tilt-addon.yaml" if os .path .exists (repo + "/tilt-addon.yaml" ) else repo + "/tilt-addon.json"
174
+ if not os .path .exists (file ):
175
+ fail ("Failed to load provider. No tilt-addon.{yaml|json} file found in " + repo )
176
+ addon_details = read_yaml (file , default = {})
177
+ if type (addon_details ) != type ([]):
178
+ addon_details = [addon_details ]
179
+ for item in addon_details :
180
+ addon_name = item ["name" ]
181
+ addon_config = item ["config" ]
182
+ if "context" in addon_config :
183
+ addon_config ["context" ] = repo + "/" + addon_config ["context" ]
184
+ else :
185
+ addon_config ["context" ] = repo
186
+ if "go_main" not in addon_config :
187
+ addon_config ["go_main" ] = "main.go"
188
+ addons [addon_name ] = addon_config
189
+
154
190
tilt_helper_dockerfile_header = """
155
191
# Tilt image
156
192
FROM golang:1.18.3 as tilt-helper
@@ -167,30 +203,12 @@ WORKDIR /
167
203
COPY --from=tilt-helper /start.sh .
168
204
COPY --from=tilt-helper /restart.sh .
169
205
COPY --from=tilt-helper /go/bin/dlv .
170
- COPY manager .
206
+ COPY $binary_name .
171
207
"""
172
208
173
- # Configures a provider by doing the following:
174
- #
175
- # 1. Enables a local_resource go build of the provider's manager binary
176
- # 2. Configures a docker build for the provider, with live updating of the manager binary
177
- # 3. Runs kustomize for the provider's config/default and applies it
178
- def enable_provider (name , debug ):
179
- p = providers .get (name )
180
- context = p .get ("context" )
181
- go_main = p .get ("go_main" , "main.go" )
182
- label = p .get ("label" , name )
183
- debug_port = int (debug .get ("port" , 0 ))
184
-
185
- # Prefix each live reload dependency with context. For example, for if the context is
186
- # test/infra/docker and main.go is listed as a dep, the result is test/infra/docker/main.go. This adjustment is
187
- # needed so Tilt can watch the correct paths for changes.
188
- live_reload_deps = []
189
- for d in p .get ("live_reload_deps" , []):
190
- live_reload_deps .append (context + "/" + d )
191
-
192
- # Set up a local_resource build of the provider's manager binary. The provider is expected to have a main.go in
193
- # manager_build_path or the main.go must be provided via go_main option. The binary is written to .tiltbuild/bin/manager.
209
+ def build_go_binary (context , reload_deps , debug , go_main , binary_name , label ):
210
+ # Set up a local_resource build of a go binary. The target repo is expected to have a main.go in
211
+ # the context path or the main.go must be provided via go_main option. The binary is written to .tiltbuild/bin/{$binary_name}.
194
212
# TODO @randomvariable: Race detector mode only currently works on x86-64 Linux.
195
213
# Need to switch to building inside Docker when architecture is mismatched
196
214
race_detector_enabled = debug .get ("race_detector" , False )
@@ -205,6 +223,7 @@ def enable_provider(name, debug):
205
223
build_options = ""
206
224
ldflags = "-extldflags \" -static\" "
207
225
226
+ debug_port = int (debug .get ("port" , 0 ))
208
227
if debug_port != 0 :
209
228
# disable optimisations and include line numbers when debugging
210
229
gcflags = "all=-N -l"
@@ -215,14 +234,22 @@ def enable_provider(name, debug):
215
234
cgo_enabled = cgo_enabled ,
216
235
arch = os_arch ,
217
236
)
218
- build_cmd = "{build_env} go build {build_options} -gcflags '{gcflags}' -ldflags '{ldflags}' -o .tiltbuild/bin/manager {go_main}" .format (
237
+
238
+ build_cmd = "{build_env} go build {build_options} -gcflags '{gcflags}' -ldflags '{ldflags}' -o .tiltbuild/bin/{binary_name} {go_main}" .format (
219
239
build_env = build_env ,
220
240
build_options = build_options ,
221
241
gcflags = gcflags ,
222
242
go_main = go_main ,
223
243
ldflags = ldflags ,
244
+ binary_name = binary_name ,
224
245
)
225
246
247
+ # Prefix each live reload dependency with context. For example, for if the context is
248
+ # test/infra/docker and main.go is listed as a dep, the result is test/infra/docker/main.go. This adjustment is
249
+ # needed so Tilt can watch the correct paths for changes.
250
+ live_reload_deps = []
251
+ for d in reload_deps :
252
+ live_reload_deps .append (context + "/" + d )
226
253
local_resource (
227
254
label .lower () + "_binary" ,
228
255
cmd = "cd {context};mkdir -p .tiltbuild/bin;{build_cmd}" .format (
@@ -233,8 +260,8 @@ def enable_provider(name, debug):
233
260
labels = [label , "ALL.binaries" ],
234
261
)
235
262
236
- additional_docker_helper_commands = p . get ( " additional_docker_helper_commands" , "" )
237
- additional_docker_build_commands = p . get ( "additional_docker_build_commands" , "" )
263
+ def build_docker_image ( image , context , binary_name , additional_docker_build_commands , additional_docker_helper_commands , port_forwards ):
264
+ links = []
238
265
239
266
dockerfile_contents = "\n " .join ([
240
267
tilt_helper_dockerfile_header ,
@@ -243,9 +270,26 @@ def enable_provider(name, debug):
243
270
additional_docker_build_commands ,
244
271
])
245
272
273
+ # Set up an image build for the provider. The live update configuration syncs the output from the local_resource
274
+ # build into the container.
275
+ docker_build (
276
+ ref = image ,
277
+ context = context + "/.tiltbuild/bin/" ,
278
+ dockerfile_contents = dockerfile_contents ,
279
+ build_args = {"binary_name" : binary_name },
280
+ target = "tilt" ,
281
+ only = binary_name ,
282
+ live_update = [
283
+ sync (context + "/.tiltbuild/bin/" + binary_name , "/" + binary_name ),
284
+ run ("sh /restart.sh" ),
285
+ ],
286
+ )
287
+
288
+ def get_port_forwards (debug ):
246
289
port_forwards = []
247
290
links = []
248
291
292
+ debug_port = int (debug .get ("port" , 0 ))
249
293
if debug_port != 0 :
250
294
port_forwards .append (port_forward (debug_port , 30000 ))
251
295
@@ -259,22 +303,40 @@ def enable_provider(name, debug):
259
303
port_forwards .append (port_forward (profiler_port , 6060 ))
260
304
links .append (link ("http://localhost:" + str (profiler_port ) + "/debug/pprof" , "profiler" ))
261
305
262
- # Set up an image build for the provider. The live update configuration syncs the output from the local_resource
263
- # build into the container.
264
- docker_build (
265
- ref = p .get ("image" ),
266
- context = context + "/.tiltbuild/bin/" ,
267
- dockerfile_contents = dockerfile_contents ,
268
- target = "tilt" ,
269
- only = "manager" ,
270
- live_update = [
271
- sync (context + "/.tiltbuild/bin/manager" , "/manager" ),
272
- run ("sh /restart.sh" ),
273
- ],
306
+ return port_forwards , links
307
+
308
+ # Configures a provider by doing the following:
309
+ #
310
+ # 1. Enables a local_resource go build of the provider's manager binary
311
+ # 2. Configures a docker build for the provider, with live updating of the manager binary
312
+ # 3. Runs kustomize for the provider's config/default and applies it
313
+ def enable_provider (name , debug ):
314
+ deployment_kind = "provider"
315
+ p = providers .get (name )
316
+ label = p .get ("label" )
317
+
318
+ port_forwards , links = get_port_forwards (debug )
319
+
320
+ build_go_binary (
321
+ context = p .get ("context" ),
322
+ reload_deps = p .get ("live_reload_deps" ),
323
+ debug = debug ,
324
+ go_main = p .get ("go_main" , "main.go" ),
325
+ binary_name = "manager" ,
326
+ label = label ,
327
+ )
328
+
329
+ build_docker_image (
330
+ image = p .get ("image" ),
331
+ context = p .get ("context" ),
332
+ binary_name = "manager" ,
333
+ additional_docker_helper_commands = p .get ("additional_docker_helper_commands" , "" ),
334
+ additional_docker_build_commands = p .get ("additional_docker_build_commands" , "" ),
335
+ port_forwards = port_forwards ,
274
336
)
275
337
276
338
if p .get ("kustomize_config" , True ):
277
- yaml = read_file ("./.tiltbuild/yaml/{}.provider .yaml" .format (name ))
339
+ yaml = read_file ("./.tiltbuild/yaml/{}.{} .yaml" .format (name , deployment_kind ))
278
340
k8s_yaml (yaml )
279
341
objs = decode_yaml_stream (yaml )
280
342
k8s_resource (
@@ -287,6 +349,63 @@ def enable_provider(name, debug):
287
349
resource_deps = ["provider_crd" ],
288
350
)
289
351
352
+ # Configures an addon by doing the following:
353
+ #
354
+ # 1. Enables a local_resource go build of the addon's manager binary
355
+ # 2. Configures a docker build for the addon, with live updating of the binary
356
+ # 3. Runs kustomize for the addons's config/default and applies it
357
+ def enable_addon (name , debug ):
358
+ addon = addons .get (name )
359
+ deployment_kind = "addon"
360
+ label = addon .get ("label" )
361
+ port_forwards , links = get_port_forwards (debug )
362
+
363
+ build_go_binary (
364
+ context = addon .get ("context" ),
365
+ reload_deps = addon .get ("live_reload_deps" ),
366
+ debug = debug ,
367
+ go_main = addon .get ("go_main" , "main.go" ),
368
+ binary_name = "extension" ,
369
+ label = label ,
370
+ )
371
+
372
+ build_docker_image (
373
+ image = addon .get ("image" ),
374
+ context = addon .get ("context" ),
375
+ binary_name = "extension" ,
376
+ additional_docker_helper_commands = addon .get ("additional_docker_helper_commands" , "" ),
377
+ additional_docker_build_commands = addon .get ("additional_docker_build_commands" , "" ),
378
+ port_forwards = port_forwards ,
379
+ )
380
+
381
+ additional_objs = []
382
+ addon_resources = addon .get ("additional_resources" , [])
383
+ for resource in addon_resources :
384
+ k8s_yaml (addon .get ("context" ) + "/" + resource )
385
+ additional_objs = additional_objs + decode_yaml_stream (read_file (addon .get ("context" ) + "/" + resource ))
386
+
387
+ if addon .get ("kustomize_config" , True ):
388
+ yaml = read_file ("./.tiltbuild/yaml/{}.{}.yaml" .format (name , deployment_kind ))
389
+ objs = decode_yaml_stream (yaml )
390
+ k8s_yaml (yaml )
391
+ k8s_resource (
392
+ workload = find_object_name (objs , "Deployment" ),
393
+ new_name = label .lower () + "_addon" ,
394
+ labels = [label , "ALL.addons" ],
395
+ port_forwards = port_forwards ,
396
+ links = links ,
397
+ objects = find_all_objects_names (additional_objs ),
398
+ resource_deps = addon .get ("resource_deps" , {}),
399
+ )
400
+
401
+ def enable_addons ():
402
+ for name in get_addons ():
403
+ enable_addon (name , settings .get ("debug" ).get (name , {}))
404
+
405
+ def get_addons ():
406
+ user_enable_addons = settings .get ("enable_addons" , [])
407
+ return {k : "" for k in user_enable_addons }.keys ()
408
+
290
409
def find_object_name (objs , kind ):
291
410
for o in objs :
292
411
if o ["kind" ] == kind :
@@ -299,6 +418,15 @@ def find_object_qualified_name(objs, kind):
299
418
return "{}:{}:{}" .format (o ["metadata" ]["name" ], kind , o ["metadata" ]["namespace" ])
300
419
return ""
301
420
421
+ def find_all_objects_names (objs ):
422
+ qualified_names = []
423
+ for o in objs :
424
+ if "namespace" in o ["metadata" ] and o ["metadata" ]["namespace" ] != "" :
425
+ qualified_names = qualified_names + ["{}:{}:{}" .format (o ["metadata" ]["name" ], o ["kind" ], o ["metadata" ]["namespace" ])]
426
+ else :
427
+ qualified_names = qualified_names + ["{}:{}" .format (o ["metadata" ]["name" ], o ["kind" ])]
428
+ return qualified_names
429
+
302
430
# Users may define their own Tilt customizations in tilt.d. This directory is excluded from git and these files will
303
431
# not be checked in to version control.
304
432
def include_user_tilt_files ():
@@ -503,6 +631,8 @@ include_user_tilt_files()
503
631
504
632
load_provider_tiltfiles ()
505
633
634
+ load_addon_tiltfiles ()
635
+
506
636
prepare_all ()
507
637
508
638
deploy_provider_crds ()
@@ -511,4 +641,6 @@ deploy_observability()
511
641
512
642
enable_providers ()
513
643
644
+ enable_addons ()
645
+
514
646
cluster_templates ()
0 commit comments