@@ -478,16 +478,33 @@ def camelCaseify(s):
478478c .CryptKeeper .keys = get_secret_value ("hub.config.CryptKeeper.keys" ).split (";" )
479479
480480# 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" :
483483 cfg .pop ("proxy_auth_token" , None )
484484 cfg .pop ("cookie_secret" , None )
485485 cfg .pop ("services" , None )
486- elif app == "ConfigurableHTTPProxy" :
486+ elif section == "ConfigurableHTTPProxy" :
487487 cfg .pop ("auth_token" , None )
488- elif app == "CryptKeeper" :
488+ elif section == "CryptKeeper" :
489489 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 )
491508
492509# load /usr/local/etc/jupyterhub/jupyterhub_config.d config files
493510config_dir = "/usr/local/etc/jupyterhub/jupyterhub_config.d"
0 commit comments