@@ -478,16 +478,33 @@ def camelCaseify(s):
478
478
c .CryptKeeper .keys = get_secret_value ("hub.config.CryptKeeper.keys" ).split (";" )
479
479
480
480
# load hub.config values, except potentially seeded secrets already loaded
481
- for app , cfg in get_config ("hub.config" , {}).items ():
482
- if app == "JupyterHub" :
481
+ for section , cfg in get_config ("hub.config" , {}).items ():
482
+ if section == "JupyterHub" :
483
483
cfg .pop ("proxy_auth_token" , None )
484
484
cfg .pop ("cookie_secret" , None )
485
485
cfg .pop ("services" , None )
486
- elif app == "ConfigurableHTTPProxy" :
486
+ elif section == "ConfigurableHTTPProxy" :
487
487
cfg .pop ("auth_token" , None )
488
- elif app == "CryptKeeper" :
488
+ elif section == "CryptKeeper" :
489
489
cfg .pop ("keys" , None )
490
- c [app ].update (cfg )
490
+
491
+ if not section [:1 ].isupper ():
492
+ # traitlets config sections are Configurable class names
493
+ # that MUST start with upper-case
494
+ # if it starts with lowercase, it must be a mistake
495
+ # (e.g. putting `hub.loadRoles` under `hub.config.loadRoles`),
496
+ # and will have no effect, so warn or raise here
497
+ print (
498
+ f"FATAL: Invalid hub.config section name: { section } ."
499
+ " hub.config sections must be Configurable class names (e.g. JupyterHub)."
500
+ " Maybe misplaced or misspelled config?" ,
501
+ file = sys .stderr ,
502
+ )
503
+ # make this fatal:
504
+ sys .exit (1 )
505
+
506
+ print (f"Loading pass-through config section hub.config.{ section } " )
507
+ c [section ].update (cfg )
491
508
492
509
# load /usr/local/etc/jupyterhub/jupyterhub_config.d config files
493
510
config_dir = "/usr/local/etc/jupyterhub/jupyterhub_config.d"
0 commit comments