@@ -8,188 +8,94 @@ Helm chart that extends Nebari's data-science JupyterHub stack with a Pi coding-
88- Pi named-server profiles (` pi-small ` , ` pi-medium ` , ` pi-large ` )
99- Pi home/quick-access UI customizations
1010- Optional Pi session sharing RBAC + handlers
11- - Optional shared-skills distribution via PVC-subpath synced from immutable URL artifacts
1211- Optional relay subsystem (core + dummy/slack/whatsapp adapters)
12+ - Shared skills delivered from the Pi runtime image (no PVC sync job)
1313
14- ## Architecture (high level)
14+ ## Architecture
1515
16- - JupyterHub remains control plane.
16+ - JupyterHub remains the control plane.
1717- User requests Pi via launcher.
1818- JupyterHub spawns/controls named server ` pi ` per user.
1919- Pi pod serves browser terminal via ` jhsingle_native_proxy ` + ` ttyd ` + ` pi ` CLI.
20- - Pi image also includes ` nebari_app_* ` wrappers ( ` deploy/status/logs/stop/delete/doctor ` ) for jhub-app lifecycle operations .
20+ - Pi startup includes ` --skill /opt/nebari/baked-skills/shared-skills ` .
2121
2222## Install
2323
2424``` bash
25- helm dependency update PACKS/nebari-pi-pack
26- helm upgrade --install data-science-pack PACKS/nebari-pi-pack \
25+ helm dependency update .
26+ helm upgrade --install data-science-pack . \
2727 --namespace data-science \
28- --set nebariapp.hostname=jupyter.nebari.local \
2928 --wait --timeout 40m
3029```
3130
32- For RECREATE.md local flow, use ready-made examples:
31+ ### Example values
3332
3433``` bash
35- # Pi core (no relay)
36- helm upgrade --install data-science-pack PACKS/nebari-pi-pack \
34+ # Local baseline
35+ helm upgrade --install data-science-pack . \
3736 --namespace data-science \
38- -f PACKS/nebari-pi-pack/ examples/values-local.yaml \
37+ -f examples/values-local.yaml \
3938 --wait --timeout 40m
4039
41- # Pi + relay
42- helm upgrade --install data-science-pack PACKS/nebari-pi-pack \
40+ # Local reliable
41+ helm upgrade --install data-science-pack . \
4342 --namespace data-science \
44- -f PACKS/nebari-pi-pack/ examples/values-relay .yaml \
45- --wait --timeout 50m
43+ -f examples/values-local-reliable .yaml \
44+ --wait --timeout 45m
4645
47- # Pi + pvc-subpath shared-skills with release rotation sync job
48- helm upgrade --install data-science-pack PACKS/nebari-pi-pack \
46+ # Relay profile
47+ helm upgrade --install data-science-pack . \
4948 --namespace data-science \
50- -f PACKS/nebari-pi-pack/ examples/values-pvc-shared-skills-sync .yaml \
49+ -f examples/values-relay .yaml \
5150 --wait --timeout 50m
52- ```
53-
54- ### Reliable local Pi testing profile (recommended)
55-
56- Use ` examples/values-local-reliable.yaml ` for more deterministic local behavior:
57- - registry-backed Pi image (no ` k3d image import ` race)
58- - immutable Pi image ref (` @sha256:... ` )
59- - prePullers disabled (lower disk churn)
60- - Pi user pods pinned to one node in local multi-node clusters
6151
62- ``` bash
63- helm upgrade --install data-science-pack PACKS/nebari-pi-pack \
52+ # Production-style baked skills profile
53+ helm upgrade --install data-science-pack . \
6454 --namespace data-science \
65- -f PACKS/nebari-pi-pack/ examples/values-local-reliable .yaml \
55+ -f examples/values-baked-skills .yaml \
6656 --wait --timeout 45m
6757```
6858
69- If you rebuild the Pi image, update both:
70- - ` pi.image.repository ` + ` pi.image.tag `
71- - ` jupyterhub.custom.pi-image ` (prefer digest-pinned value)
72-
73- For best local dev stability, prefer a single-node k3d cluster for Pi work.
74-
75- #### Local k3d registry flow (recommended)
76-
77- ``` bash
78- # Create local registry attached to the cluster network (one-time)
79- k3d registry create pi-registry.localhost --port 5001 --default-network k3d-nebari-local
80-
81- # Configure node-side registry mirrors (one-time per cluster lifecycle)
82- cat > /tmp/k3s-registries-pi.yaml << 'YAML '
83- mirrors:
84- "k3d-pi-registry.localhost:5000":
85- endpoint:
86- - "http://k3d-pi-registry.localhost:5000"
87- "localhost:5001":
88- endpoint:
89- - "http://k3d-pi-registry.localhost:5000"
90- YAML
91- for n in k3d-nebari-local-server-0 k3d-nebari-local-agent-0 k3d-nebari-local-agent-1; do
92- docker cp /tmp/k3s-registries-pi.yaml " $n " :/etc/rancher/k3s/registries.yaml
93- done
94- docker restart k3d-nebari-local-agent-0 k3d-nebari-local-agent-1 k3d-nebari-local-server-0
95-
96- # Build Pi image (includes pi CLI + nebari_app_* wrappers)
97- docker build -t nebari-pi-agent:local-slim PACKS/nebari-pi-pack/images/pi-agent
98-
99- # Tag + push immutable Pi image to local registry
100- TAG=dev-$( date +%Y%m%d-%H%M%S)
101- docker tag nebari-pi-agent:local-slim localhost:5001/nebari-pi-agent:${TAG}
102- docker push localhost:5001/nebari-pi-agent:${TAG}
103-
104- # Update values-local-reliable.yaml with the new tag/digest, then deploy
105- helm upgrade --install data-science-pack PACKS/nebari-pi-pack \
106- --namespace data-science \
107- -f PACKS/nebari-pi-pack/examples/values-local-reliable.yaml \
108- --wait --timeout 45m
109- ```
110-
111- ## Migrate from existing data-science-pack
112-
113- Use same release and namespace:
114-
115- ``` bash
116- helm upgrade data-science-pack PACKS/nebari-pi-pack \
117- --namespace data-science \
118- -f < your-values.yaml> \
119- --wait --timeout 40m
120- ```
121-
12259## Important values
12360
124- - ` pi.enabled `
12561- ` pi.image.* `
126- - ` pi.sharing.enabled `
12762- ` pi.sharedSkills.enabled `
128- - ` pi.sharedSkills.mode ` (` pvc-subpath ` only)
129- - ` pi.sharedSkills.sync.* ` (chart-managed PVC sync/rotation pipeline for URL artifacts)
130- - ` relay.enabled `
131- - ` relay.deployMode ` (` configmap ` or ` image ` )
132- - ` relay.core.piAgentDir `
133-
134- Also review ` jupyterhub.custom.* ` Pi fields in ` values.yaml ` , consumed by Hub config modules (including ` pi-coding-agent-dir ` for writable Pi runtime state location).
135- Keep ` jupyterhub.custom.pi-coding-agent-dir ` aligned with ` relay.core.piAgentDir ` when relay is enabled.
136-
137- ### Production-style shared-skills updates (PVC mode)
138-
139- When ` pi.sharedSkills.mode=pvc-subpath ` , enable chart-managed sync/rotation and feed it immutable artifacts built from your skills repo CI.
63+ - ` pi.sharedSkills.mode ` (` image ` )
64+ - ` pi.sharedSkills.imagePath `
65+ - ` jupyterhub.custom.pi-image `
66+ - ` jupyterhub.custom.pi-skills-path `
67+ - ` jupyterhub.custom.pi-coding-agent-dir `
68+ - ` relay.* `
14069
141- Recommended values :
70+ When relay is enabled, keep these aligned :
14271
143- - ` pi.sharedSkills.sync.enabled=true `
144- - ` pi.sharedSkills.sync.source.type=url `
145- - ` pi.sharedSkills.sync.source.url=https://.../shared-skills-<version>.tar.gz `
146- - ` pi.sharedSkills.sync.source.sha256=<artifact-sha256> `
147- - ` pi.sharedSkills.sync.releaseId=<same-version-or-git-sha> `
148- - ` pi.sharedSkills.sync.keepReleases=<N> `
149-
150- Behavior on each Helm install/upgrade:
151- - syncs archive into ` <pvcSubPath>/releases/<release-id>/... `
152- - updates symlink: ` <pvcSubPath>/current -> releases/<release-id> `
153- - prunes old releases (keep latest N)
154-
155- This gives reproducible roll-forward/rollback via ` helm upgrade ` without rebuilding the whole cluster.
72+ - ` relay.core.piAgentDir `
73+ - ` jupyterhub.custom.pi-coding-agent-dir `
15674
157- #### Private artifact endpoints
75+ ## Build Pi image with baked skills
15876
159- If your artifact URL requires auth, set :
77+ ` images/pi-agent/Dockerfile ` expects :
16078
161- - ` pi.sharedSkills.sync.source.auth.secretName=<secret-name> `
162- - ` pi.sharedSkills.sync.source.auth.tokenKey=<key> ` (default ` token ` )
79+ - ` PI_SKILLS_URL ` (required)
80+ - ` PI_SKILLS_SHA256 ` (optional )
16381
164- Create secret example :
82+ Example :
16583
16684``` bash
167- kubectl -n data-science create secret generic pi-shared-skills-artifact-token \
168- --from-literal=token=' <your-bearer-token>'
85+ docker build \
86+ -t quay.io/openteams/pi-coding-agent-demo:baked-< tag> \
87+ --build-arg PI_SKILLS_URL=" https://github.com/nenb/nebari-agent-skills/releases/download/<release>/shared-skills-<sha>.tar.gz" \
88+ --build-arg PI_SKILLS_SHA256=" <sha256>" \
89+ images/pi-agent
16990```
17091
171- #### GitHub Actions CI workflow (skills repo)
172-
173- Use the dedicated skills repository (` nenb/nebari-agent-skills ` ) to publish immutable artifacts.
174-
175- A workflow template is provided at:
176-
177- - ` .github/workflows/publish-pi-shared-skills-artifact.yml `
178-
179- Run this workflow in the ** skills repo** , not in the Pi pack repo. It should publish:
180- - ` shared-skills-<sha>.tar.gz ` (immutable asset)
181- - ` shared-skills.tar.gz ` (rolling latest asset)
182- - matching ` .sha256 ` files
183- - release tag: ` pi-shared-skills-<sha> `
184-
185- Then point ` pi.sharedSkills.sync.source.url ` to either:
186- - immutable URL (recommended), or
187- - latest URL (convenient, less reproducible)
92+ Then set your Helm values to the pushed image tag/digest:
18893
189- If you use immutable URL, set ` releaseId ` to the same tag/sha.
94+ - ` pi.image.repository `
95+ - ` pi.image.tag `
96+ - ` jupyterhub.custom.pi-image ` (prefer digest pin)
19097
191- ## Security notes
98+ ## Notes
19299
193- - No hardcoded long-lived Pi tooling token in source.
194- - M4 tooling token is generated/stored in chart-managed Secret (` pi-secrets ` ) and injected into Hub env.
195- - Relay secrets use keep/lookup behavior for stable upgrades.
100+ - Legacy PVC-based shared-skills sync is removed from runtime flow.
101+ - Existing running Pi sessions keep old image/skills until pod restart.
0 commit comments