579579 if _size in PI_SPECS_BY_SIZE and isinstance (_override , dict ):
580580 PI_SPECS_BY_SIZE [_size ].update (_override )
581581
582+ PI_RUN_AS_ROOT = bool (z2jh .get_config ("custom.pi-run-as-root" , False ))
583+
582584code_server_bootstrap_script = textwrap .dedent (
583585 """
584586 set -u
@@ -685,6 +687,43 @@ def _clean_profile(profile):
685687 p ["kubespawner_override" ] = override
686688 return p
687689
690+ def _apply_pi_root_access (override ):
691+ if not PI_RUN_AS_ROOT :
692+ return override
693+
694+ if not isinstance (override , dict ):
695+ override = {}
696+
697+ override ["uid" ] = 0
698+ override ["gid" ] = 0
699+
700+ container_cfg = copy .deepcopy (override .get ("extra_container_config" ) or {})
701+ if not isinstance (container_cfg , dict ):
702+ container_cfg = {}
703+ sec_ctx = copy .deepcopy (container_cfg .get ("securityContext" ) or {})
704+ if not isinstance (sec_ctx , dict ):
705+ sec_ctx = {}
706+ sec_ctx ["runAsUser" ] = 0
707+ sec_ctx ["runAsGroup" ] = 0
708+ sec_ctx ["runAsNonRoot" ] = False
709+ # Keep this true for root shell workflows inside the user pod.
710+ sec_ctx ["allowPrivilegeEscalation" ] = True
711+ container_cfg ["securityContext" ] = sec_ctx
712+ override ["extra_container_config" ] = container_cfg
713+
714+ pod_cfg = copy .deepcopy (override .get ("extra_pod_config" ) or {})
715+ if not isinstance (pod_cfg , dict ):
716+ pod_cfg = {}
717+ pod_sec_ctx = copy .deepcopy (pod_cfg .get ("securityContext" ) or {})
718+ if not isinstance (pod_sec_ctx , dict ):
719+ pod_sec_ctx = {}
720+ pod_sec_ctx ["runAsNonRoot" ] = False
721+ pod_cfg ["securityContext" ] = pod_sec_ctx
722+ override ["extra_pod_config" ] = pod_cfg
723+
724+ return override
725+
726+
688727def _build_pi_profile_from_base (base_profile , size_key ):
689728 spec = PI_SPECS_BY_SIZE .get (size_key ) or {}
690729 p = copy .deepcopy (base_profile )
@@ -701,26 +740,29 @@ def _build_pi_profile_from_base(base_profile, size_key):
701740 override ["cpu_guarantee" ] = spec .get ("cpu_guarantee" )
702741 override ["mem_limit" ] = spec .get ("mem_limit" )
703742 override ["mem_guarantee" ] = spec .get ("mem_guarantee" )
743+ override = _apply_pi_root_access (override )
704744 p ["kubespawner_override" ] = override
705745 return p
706746
707747
708748def _build_pi_profile_minimal (size_key ):
709749 spec = PI_SPECS_BY_SIZE .get (size_key ) or {}
750+ override = {
751+ "environment" : dict (PI_ENV ),
752+ "image" : PI_IMAGE ,
753+ "cmd" : PI_CMD ,
754+ "args" : [],
755+ "cpu_limit" : spec .get ("cpu_limit" ),
756+ "cpu_guarantee" : spec .get ("cpu_guarantee" ),
757+ "mem_limit" : spec .get ("mem_limit" ),
758+ "mem_guarantee" : spec .get ("mem_guarantee" ),
759+ }
760+ override = _apply_pi_root_access (override )
710761 return {
711762 "display_name" : spec .get ("display_name" , f"Pi { size_key .title ()} " ),
712763 "description" : spec .get ("description" , "" ),
713764 "default" : size_key == "small" ,
714- "kubespawner_override" : {
715- "environment" : dict (PI_ENV ),
716- "image" : PI_IMAGE ,
717- "cmd" : PI_CMD ,
718- "args" : [],
719- "cpu_limit" : spec .get ("cpu_limit" ),
720- "cpu_guarantee" : spec .get ("cpu_guarantee" ),
721- "mem_limit" : spec .get ("mem_limit" ),
722- "mem_guarantee" : spec .get ("mem_guarantee" ),
723- },
765+ "kubespawner_override" : override ,
724766 }
725767
726768async def _profile_list_without_nebula_pi_cli (spawner ):
0 commit comments