88import os
99import re
1010import secrets
11+ import warnings
1112from binascii import a2b_hex
1213from concurrent .futures import ThreadPoolExecutor
1314from glob import glob
4142from traitlets .config import Application
4243
4344from .base import AboutHandler , Custom404 , VersionHandler
44- from .build import Build , BuildExecutor , KubernetesBuildExecutor
45+ from .build import BuildExecutor , KubernetesBuildExecutor , KubernetesCleaner
4546from .builder import BuildHandler
4647from .config import ConfigHandler
4748from .events import EventLog
@@ -229,6 +230,8 @@ def _valid_badge_base_url(self, proposal):
229230
230231 appendix = Unicode (
231232 help = """
233+ DEPRECATED: Use c.BuildExecutor.appendix
234+
232235 Appendix to pass to repo2docker
233236
234237 A multi-line string of Docker directives to run.
@@ -248,6 +251,8 @@ def _valid_badge_base_url(self, proposal):
248251 sticky_builds = Bool (
249252 False ,
250253 help = """
254+ DEPRECATED: Use c.KubernetesBuildExecutor.sticky_builds
255+
251256 Attempt to assign builds for the same repository to the same node.
252257
253258 In order to speed up re-builds of a repository all its builds will
@@ -270,7 +275,7 @@ def _valid_badge_base_url(self, proposal):
270275 )
271276
272277 build_class = Type (
273- Build ,
278+ KubernetesBuildExecutor ,
274279 klass = BuildExecutor ,
275280 help = """
276281 The class used to build repo2docker images.
@@ -280,6 +285,15 @@ def _valid_badge_base_url(self, proposal):
280285 config = True ,
281286 )
282287
288+ build_cleaner_class = Type (
289+ KubernetesCleaner ,
290+ allow_none = True ,
291+ help = """
292+ The class used to cleanup builders.
293+ """ ,
294+ config = True ,
295+ )
296+
283297 registry_class = Type (
284298 DockerRegistry ,
285299 help = """
@@ -369,6 +383,8 @@ def _pod_quota_deprecated(self, change):
369383 log_tail_lines = Integer (
370384 100 ,
371385 help = """
386+ DEPRECATED: Use c.KubernetesBuildExecutor.log_tail_lines
387+
372388 Limit number of log lines to show when connecting to an already running build.
373389 """ ,
374390 config = True ,
@@ -378,6 +394,8 @@ def _pod_quota_deprecated(self, change):
378394 "binder-build-docker-config" ,
379395 allow_none = True ,
380396 help = """
397+ DEPRECATED: Use c.BuildExecutor.push_secret
398+
381399 A kubernetes secret object that provides credentials for pushing built images.
382400 """ ,
383401 config = True ,
@@ -401,6 +419,8 @@ def _pod_quota_deprecated(self, change):
401419 build_memory_request = ByteSpecification (
402420 0 ,
403421 help = """
422+ DEPRECATED: Use c.KubernetesBuildExecutor.memory_request
423+
404424 Amount of memory to request when scheduling a build
405425
406426 0 reserves no memory.
@@ -416,6 +436,8 @@ def _pod_quota_deprecated(self, change):
416436 build_memory_limit = ByteSpecification (
417437 0 ,
418438 help = """
439+ DEPRECATED: Use c.BuildExecutor.memory_limit
440+
419441 Max amount of memory allocated for each image build process.
420442
421443 0 sets no limit.
@@ -440,6 +462,8 @@ def _pod_quota_deprecated(self, change):
440462 "/var/run/docker.sock" ,
441463 config = True ,
442464 help = """
465+ DEPRECATED: Use c.KubernetesBuildExecutor.docker_host
466+
443467 The docker URL repo2docker should use to build the images.
444468
445469 Currently, only paths are supported, and they are expected to be available on
@@ -518,6 +542,8 @@ def _add_slash(self, proposal):
518542
519543 build_namespace = Unicode (
520544 help = """
545+ DEPRECATED: Use c.KubernetesBuildExecutor.namespace
546+
521547 Kubernetes namespace to spawn build pods in.
522548
523549 Note that the push_secret must refer to a secret in this namespace.
@@ -532,6 +558,8 @@ def _default_build_namespace(self):
532558 build_image = Unicode (
533559 "quay.io/jupyterhub/repo2docker:2022.10.0" ,
534560 help = """
561+ DEPRECATED: Use c.KubernetesBuildExecutor.build_image
562+
535563 The repo2docker image to be used for doing builds
536564 """ ,
537565 config = True ,
@@ -541,6 +569,8 @@ def _default_build_namespace(self):
541569 {},
542570 config = True ,
543571 help = """
572+ DEPRECATED: Use c.KubernetesBuildExecutor.node_selector
573+
544574 Select the node where build pod runs on.
545575 """ ,
546576 )
@@ -737,6 +767,27 @@ def _template_path_default(self):
737767 help = "Origin to use when emitting events. Defaults to hostname of request when empty" ,
738768 )
739769
770+ _build_config_deprecated_map = {
771+ "appendix" : ("BuildExecutor" , "appendix" ),
772+ "push_secret" : ("BuildExecutor" , "push_secret" ),
773+ "build_memory_limit" : ("BuildExecutor" , "memory_limit" ),
774+ "sticky_builds" : ("KubernetesBuildExecutor" , "sticky_builds" ),
775+ "log_tail_lines" : ("KubernetesBuildExecutor" , "log_tail_lines" ),
776+ "build_memory_request" : ("KubernetesBuildExecutor" , "memory_request" ),
777+ "build_docker_host" : ("KubernetesBuildExecutor" , "docker_host" ),
778+ "build_namespace" : ("KubernetesBuildExecutor" , "namespace" ),
779+ "build_image" : ("KubernetesBuildExecutor" , "build_image" ),
780+ "build_node_selector" : ("KubernetesBuildExecutor" , "node_selector" ),
781+ }
782+
783+ @observe (* _build_config_deprecated_map )
784+ def _build_config_deprecated (self , change ):
785+ dest_cls , dest_name = self ._build_config_deprecated_map [change .name ]
786+ self .log .warning (
787+ "BinderHub.%s is deprecated, use %s.%s" , change .name , dest_cls , dest_name
788+ )
789+ self .config [dest_cls ][dest_name ] = change .new
790+
740791 @staticmethod
741792 def add_url_prefix (prefix , handlers ):
742793 """add a url prefix to handlers"""
@@ -830,25 +881,22 @@ def initialize(self, *args, **kwargs):
830881
831882 launch_quota = self .launch_quota_class (parent = self , executor = self .executor )
832883
884+ # Construct a Builder so that we can extract parameters such as the
885+ # configuration or the version string to pass to /version and /health handlers
886+ example_builder = self .build_class (parent = self )
833887 self .tornado_settings .update (
834888 {
835889 "log_function" : log_request ,
836- "push_secret" : self .push_secret ,
837890 "image_prefix" : self .image_prefix ,
838891 "debug" : self .debug ,
839892 "launcher" : self .launcher ,
840- "appendix" : self .appendix ,
841893 "ban_networks" : self .ban_networks ,
842894 "ban_networks_min_prefix_len" : self .ban_networks_min_prefix_len ,
843- "build_namespace" : self .build_namespace ,
844- "build_image" : self .build_image ,
845- "build_node_selector" : self .build_node_selector ,
846895 "build_pool" : self .build_pool ,
847896 "build_token_check_origin" : self .build_token_check_origin ,
848897 "build_token_secret" : self .build_token_secret ,
849898 "build_token_expires_seconds" : self .build_token_expires_seconds ,
850- "sticky_builds" : self .sticky_builds ,
851- "log_tail_lines" : self .log_tail_lines ,
899+ "example_builder" : example_builder ,
852900 "pod_quota" : self .pod_quota ,
853901 "per_repo_quota" : self .per_repo_quota ,
854902 "per_repo_quota_higher" : self .per_repo_quota_higher ,
@@ -866,9 +914,6 @@ def initialize(self, *args, **kwargs):
866914 "banner_message" : self .banner_message ,
867915 "extra_footer_scripts" : self .extra_footer_scripts ,
868916 "jinja2_env" : jinja_env ,
869- "build_memory_limit" : self .build_memory_limit ,
870- "build_memory_request" : self .build_memory_request ,
871- "build_docker_host" : self .build_docker_host ,
872917 "build_docker_config" : self .build_docker_config ,
873918 "base_url" : self .base_url ,
874919 "badge_base_url" : self .badge_base_url ,
@@ -969,25 +1014,21 @@ def stop(self):
9691014 self .build_pool .shutdown ()
9701015
9711016 async def watch_build_pods (self ):
972- """Watch build pods
1017+ warnings .warn (
1018+ "watch_build_pods() is deprecated, use watch_builders()" , DeprecationWarning
1019+ )
1020+ await self .watch_builders ()
9731021
974- Every build_cleanup_interval :
975- - delete stopped build pods
976- - delete running build pods older than build_max_age
1022+ async def watch_builders ( self ) :
1023+ """
1024+ Watch builders, run a cleanup function every build_cleanup_interval
9771025 """
978- while True :
1026+ while self .build_cleaner_class :
1027+ cleaner = self .build_cleaner_class ()
9791028 try :
980- await asyncio .wrap_future (
981- self .executor .submit (
982- lambda : Build .cleanup_builds (
983- self .kube_client ,
984- self .build_namespace ,
985- self .build_max_age ,
986- )
987- )
988- )
1029+ await asyncio .wrap_future (self .executor .submit (cleaner .cleanup ))
9891030 except Exception :
990- app_log .exception ("Failed to cleanup build pods " )
1031+ app_log .exception ("Failed to cleanup builders " )
9911032 await asyncio .sleep (self .build_cleanup_interval )
9921033
9931034 def start (self , run_loop = True ):
@@ -998,7 +1039,7 @@ def start(self, run_loop=True):
9981039 )
9991040 self .http_server .listen (self .port )
10001041 if self .builder_required :
1001- asyncio .ensure_future (self .watch_build_pods ())
1042+ asyncio .ensure_future (self .watch_builders ())
10021043 if run_loop :
10031044 tornado .ioloop .IOLoop .current ().start ()
10041045
0 commit comments