@@ -113,6 +113,22 @@ COPY --from=tilt-helper /usr/bin/kubectl /usr/bin/kubectl
113113 },
114114}
115115
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+
116132def ensure_clusterctl ():
117133 local ("make clusterctl" )
118134
@@ -128,6 +144,7 @@ def ensure_clusterctl():
128144# ]
129145# }
130146# }
147+
131148def load_provider_tiltfiles ():
132149 provider_repos = settings .get ("provider_repos" , [])
133150
@@ -145,12 +162,31 @@ def load_provider_tiltfiles():
145162 provider_config ["context" ] = repo + "/" + provider_config ["context" ]
146163 else :
147164 provider_config ["context" ] = repo
148- if "kustomize_config" not in provider_config :
149- provider_config ["kustomize_config" ] = True
150165 if "go_main" not in provider_config :
151166 provider_config ["go_main" ] = "main.go"
152167 providers [provider_name ] = provider_config
153168
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+
154190tilt_helper_dockerfile_header = """
155191# Tilt image
156192FROM golang:1.18.3 as tilt-helper
@@ -167,30 +203,12 @@ WORKDIR /
167203COPY --from=tilt-helper /start.sh .
168204COPY --from=tilt-helper /restart.sh .
169205COPY --from=tilt-helper /go/bin/dlv .
170- COPY manager .
206+ COPY $binary_name .
171207"""
172208
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}.
194212 # TODO @randomvariable: Race detector mode only currently works on x86-64 Linux.
195213 # Need to switch to building inside Docker when architecture is mismatched
196214 race_detector_enabled = debug .get ("race_detector" , False )
@@ -205,6 +223,7 @@ def enable_provider(name, debug):
205223 build_options = ""
206224 ldflags = "-extldflags \" -static\" "
207225
226+ debug_port = int (debug .get ("port" , 0 ))
208227 if debug_port != 0 :
209228 # disable optimisations and include line numbers when debugging
210229 gcflags = "all=-N -l"
@@ -215,14 +234,22 @@ def enable_provider(name, debug):
215234 cgo_enabled = cgo_enabled ,
216235 arch = os_arch ,
217236 )
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 (
219239 build_env = build_env ,
220240 build_options = build_options ,
221241 gcflags = gcflags ,
222242 go_main = go_main ,
223243 ldflags = ldflags ,
244+ binary_name = binary_name ,
224245 )
225246
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 )
226253 local_resource (
227254 label .lower () + "_binary" ,
228255 cmd = "cd {context};mkdir -p .tiltbuild/bin;{build_cmd}" .format (
@@ -233,8 +260,8 @@ def enable_provider(name, debug):
233260 labels = [label , "ALL.binaries" ],
234261 )
235262
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 = []
238265
239266 dockerfile_contents = "\n " .join ([
240267 tilt_helper_dockerfile_header ,
@@ -243,9 +270,26 @@ def enable_provider(name, debug):
243270 additional_docker_build_commands ,
244271 ])
245272
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 ):
246289 port_forwards = []
247290 links = []
248291
292+ debug_port = int (debug .get ("port" , 0 ))
249293 if debug_port != 0 :
250294 port_forwards .append (port_forward (debug_port , 30000 ))
251295
@@ -259,22 +303,40 @@ def enable_provider(name, debug):
259303 port_forwards .append (port_forward (profiler_port , 6060 ))
260304 links .append (link ("http://localhost:" + str (profiler_port ) + "/debug/pprof" , "profiler" ))
261305
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 ,
274336 )
275337
276338 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 ))
278340 k8s_yaml (yaml )
279341 objs = decode_yaml_stream (yaml )
280342 k8s_resource (
@@ -287,6 +349,63 @@ def enable_provider(name, debug):
287349 resource_deps = ["provider_crd" ],
288350 )
289351
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+
290409def find_object_name (objs , kind ):
291410 for o in objs :
292411 if o ["kind" ] == kind :
@@ -299,6 +418,15 @@ def find_object_qualified_name(objs, kind):
299418 return "{}:{}:{}" .format (o ["metadata" ]["name" ], kind , o ["metadata" ]["namespace" ])
300419 return ""
301420
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+
302430# Users may define their own Tilt customizations in tilt.d. This directory is excluded from git and these files will
303431# not be checked in to version control.
304432def include_user_tilt_files ():
@@ -503,6 +631,8 @@ include_user_tilt_files()
503631
504632load_provider_tiltfiles ()
505633
634+ load_addon_tiltfiles ()
635+
506636prepare_all ()
507637
508638deploy_provider_crds ()
@@ -511,4 +641,6 @@ deploy_observability()
511641
512642enable_providers ()
513643
644+ enable_addons ()
645+
514646cluster_templates ()
0 commit comments