Skip to content

Commit 78b5fb7

Browse files
committed
Add configurable Pi root-mode for named server profiles
1 parent aa73c68 commit 78b5fb7

2 files changed

Lines changed: 56 additions & 10 deletions

File tree

config/jupyterhub/08-pi-home-and-spawn-fixes.py

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,8 @@
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+
582584
code_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+
688727
def _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

708748
def _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

726768
async def _profile_list_without_nebula_pi_cli(spawner):

values.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ jupyterhub:
209209
pi-proxy-url: http://proxy-public
210210
pi-coding-agent-dir: /tmp/pi-agent
211211
pi-m4-tools-service-name: pi-m4-tools
212+
# If true, Pi named-server pods run as root inside the container.
213+
# This grants full in-container filesystem permissions for that user's pod.
214+
# User isolation is still provided by per-user pods/PVCs.
215+
pi-run-as-root: false
212216
pi-profiles:
213217
small:
214218
display_name: Pi Small

0 commit comments

Comments
 (0)