Skip to content

Commit 9baa163

Browse files
committed
no persistent volume & cleanup
1 parent e1a5630 commit 9baa163

File tree

2 files changed

+2
-223
lines changed

2 files changed

+2
-223
lines changed

helm/form-0.py

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,7 @@
22
from tornado import gen
33
from kubespawner import KubeSpawner
44

5-
class SillySpawner(KubeSpawner):
6-
form_template = Unicode("""
7-
<h3>Home</h3>
8-
<div id="phomeDiv" style="display: block;">
9-
<input type="checkbox" id="delhome" name="delhome" value="delete">
10-
<label for="delhome">Erase if home exists</label><br/>
11-
<p style="background-color:orange;">Take care of checking this button, it removes whole home directory and previous data will be lost. Use in case only when notebook is broken so it does not start, in other cases, remove data from terminal.</p>
12-
</div>
13-
""",)
14-
15-
option_template = Unicode("""
16-
<option value="{item}">{item}</option>""",
17-
config = True, help = "Template for html form options."
18-
)
19-
20-
21-
async def get_options_form(self):
22-
return self.form_template
23-
24-
25-
c.JupyterHub.spawner_class = SillySpawner
5+
# c.JupyterHub.spawner_class = SillySpawner
266
c.MappingKernelManager.cull_idle_timeout = 259200
277
c.MappingKernelManager.cull_connected = False
288
c.MappingKernelManager.cull_busy = False

helm/pre-spawn-hook.py

Lines changed: 1 addition & 202 deletions
Original file line numberDiff line numberDiff line change
@@ -1,187 +1,11 @@
1-
import asyncio
1+
import asyncio
22
import kubernetes_asyncio
33
from kubernetes_asyncio import config, client
44
import datetime
55

6-
#nsprefix = 'mtdminer-'
7-
#nssuffix = '-prod-ns'
86
ns = 'metadynminer-ns'
97
usagelog = '/srv/jupyterhub/usage.log'
108

11-
from kubernetes_asyncio.client import (
12-
V1ObjectMeta,
13-
V1Secret,
14-
V1PersistentVolume,
15-
V1PersistentVolumeClaim,
16-
V1ResourceRequirements,
17-
V1LabelSelector,
18-
V1CSIPersistentVolumeSource,
19-
V1PersistentVolumeSpec,
20-
V1PersistentVolumeClaimSpec,
21-
V1Namespace,
22-
V1ServiceAccount,
23-
V1RoleBinding,
24-
V1RoleRef,
25-
V1Subject,
26-
V1ClusterRole,
27-
V1PolicyRule,
28-
ApiException,
29-
)
30-
31-
async def check_pvc(home_pvc_name, namespace):
32-
async with kubernetes_asyncio.client.ApiClient() as api_client:
33-
v1 = kubernetes_asyncio.client.CoreV1Api(api_client)
34-
pvcs = await v1.list_namespaced_persistent_volume_claim(namespace)
35-
for claim in pvcs.items:
36-
if claim.metadata.name == home_pvc_name:
37-
return claim
38-
return None
39-
40-
async def delete_pvc(namespace, pvc):
41-
async with kubernetes_asyncio.client.ApiClient() as api_client:
42-
v1 = kubernetes_asyncio.client.CoreV1Api(api_client)
43-
await v1.delete_namespaced_persistent_volume_claim(name=pvc, namespace=namespace)
44-
await asyncio.sleep(1)
45-
46-
async def create_pvc(home_pvc_name, home_pv_name, namespace, storage_class, capacity):
47-
pvc = V1PersistentVolumeClaim()
48-
pvc.api_version = "v1"
49-
pvc.kind = "PersistentVolumeClaim"
50-
pvc.metadata = V1ObjectMeta()
51-
pvc.metadata.name = home_pvc_name
52-
pvc.spec = V1PersistentVolumeClaimSpec()
53-
pvc.spec.access_modes = ['ReadWriteMany']
54-
pvc.spec.resources = V1ResourceRequirements()
55-
pvc.spec.resources.requests = {"storage": capacity}
56-
pvc.spec.storage_class_name = storage_class
57-
if storage_class != "nfs-csi":
58-
pvc.spec.selector = V1LabelSelector()
59-
pvc.spec.selector.match_labels = {"name": home_pv_name}
60-
try:
61-
async with kubernetes_asyncio.client.ApiClient() as api_client:
62-
v1 = kubernetes_asyncio.client.CoreV1Api(api_client)
63-
x = await v1.create_namespaced_persistent_volume_claim(namespace, pvc)
64-
await asyncio.sleep(1)
65-
except ApiException as e:
66-
if re.search("object is being deleted:", e.body):
67-
raise web.HTTPError(401, "Can't delete PVC {}, please contact administrator!".format(home_pvc_name))
68-
return False
69-
return True
70-
71-
def add_volume(spawner_vol_list, volume, volname):
72-
volume_exists = False
73-
for vol in spawner_vol_list:
74-
if "name" in vol and vol["name"] == volname:
75-
volume_exists = True
76-
if not volume_exists:
77-
spawner_vol_list.append(volume)
78-
79-
def mount(spawner, pv, pvc, mountpath):
80-
volume = {"name": pv, "persistentVolumeClaim": {"claimName": pvc}}
81-
volume_mount = {"mountPath": mountpath, "name": pv}
82-
if len(spawner.volumes) == 0:
83-
spawner.volumes = [volume]
84-
else:
85-
add_volume(spawner.volumes, volume, pv)
86-
if len(spawner.volume_mounts) == 0:
87-
spawner.volume_mounts = [volume_mount]
88-
else:
89-
add_volume(spawner.volume_mounts, volume_mount, pvc)
90-
91-
async def mount_persistent_hub_home(spawner, username, namespace):
92-
hub_home_name = username + "-home-default"
93-
94-
if spawner.user_options.get('delhome') == "delete":
95-
pvc = await check_pvc(hub_home_name, namespace)
96-
if pvc:
97-
await delete_pvc(namespace, hub_home_name)
98-
await create_pvc(hub_home_name, hub_home_name + "-pv", namespace, "nfs-csi", "10Gi")
99-
else:
100-
pvc = await check_pvc(hub_home_name, namespace)
101-
if not pvc:
102-
await create_pvc(hub_home_name, hub_home_name + "-pv", namespace, "nfs-csi", "10Gi")
103-
104-
mount(spawner, hub_home_name + "-pv", hub_home_name, "/home/jovyan")
105-
106-
async def check_ns(user_ns):
107-
async with kubernetes_asyncio.client.ApiClient() as api_client:
108-
v1 = kubernetes_asyncio.client.CoreV1Api(api_client)
109-
nss = await v1.list_namespace(watch=False)
110-
for ns in nss.items:
111-
if ns.metadata.name == user_ns:
112-
ann = ns.metadata.annotations.get("field.cattle.io/projectId")
113-
if not ann or ann != 'c-m-qvndqhf6:p-wt9xp':
114-
return True, False
115-
return True, True
116-
return False, False
117-
118-
119-
async def create_ns(username, original):
120-
namespace = nsprefix + username + nssuffix
121-
exists, ann = await check_ns(namespace)
122-
if not exists:
123-
ns = V1Namespace()
124-
ns.metadata = V1ObjectMeta(name=namespace,
125-
annotations={'field.cattle.io/projectId': 'c-m-qvndqhf6:p-wt9xp', 'user': original},
126-
labels={'hub.jupyter.org/network-access-hub': 'true'})
127-
128-
async with kubernetes_asyncio.client.ApiClient() as api_client:
129-
v1 = kubernetes_asyncio.client.CoreV1Api(api_client)
130-
await v1.create_namespace(body=ns)
131-
await asyncio.sleep(1)
132-
return namespace
133-
if exists and not ann:
134-
raise web.HTTPError(401, "Non-labelled namespace error! Please contact administrator at [email protected].")
135-
return namespace
136-
137-
async def check_sa(user_sa, namespace):
138-
async with kubernetes_asyncio.client.ApiClient() as api_client:
139-
v1 = kubernetes_asyncio.client.CoreV1Api(api_client)
140-
sas = await v1.list_namespaced_service_account(namespace=namespace)
141-
for sa in sas.items:
142-
if sa.metadata.name == user_sa:
143-
return True
144-
return False
145-
146-
147-
async def create_sa(username, namespace):
148-
sa_name = "sa-" + username
149-
exists = await check_sa(sa_name, namespace)
150-
if not exists:
151-
sa = V1ServiceAccount()
152-
sa.metadata = V1ObjectMeta(name=sa_name)
153-
async with kubernetes_asyncio.client.ApiClient() as api_client:
154-
v1 = kubernetes_asyncio.client.CoreV1Api(api_client)
155-
await v1.create_namespaced_service_account(namespace=namespace, body=sa)
156-
await asyncio.sleep(1)
157-
return sa_name
158-
159-
160-
async def check_rb(namespace):
161-
async with kubernetes_asyncio.client.ApiClient() as api_client:
162-
v1 = kubernetes_asyncio.client.RbacAuthorizationV1Api(api_client)
163-
rbs = await v1.list_namespaced_role_binding(namespace=namespace)
164-
for rb in rbs.items:
165-
if rb.metadata.name == "hub-resources-access-binding":
166-
return True
167-
return False
168-
169-
170-
async def create_rb(sa_name, namespace):
171-
try:
172-
rb = V1RoleBinding(role_ref=V1RoleRef(api_group="rbac.authorization.k8s.io", kind="ClusterRole",
173-
name="hub-resources-access"))
174-
rb.metadata = V1ObjectMeta(name="hub-resources-access-binding", namespace=namespace)
175-
rb.subjects = [V1Subject(kind="ServiceAccount", name=sa_name)]
176-
async with kubernetes_asyncio.client.ApiClient() as api_client:
177-
v1 = kubernetes_asyncio.client.RbacAuthorizationV1Api(api_client)
178-
await v1.create_namespaced_role_binding(namespace=namespace, body=rb)
179-
await asyncio.sleep(1)
180-
except kubernetes_asyncio.client.exceptions.ApiException as e:
181-
pass # buzz off
182-
183-
184-
1859
async def bootstrap_pre_spawn(spawner):
18610
config.load_incluster_config()
18711
namespace = spawner.namespace
@@ -192,28 +16,9 @@ async def bootstrap_pre_spawn(spawner):
19216
if "_" in username:
19317
username = username.replace("_", "-5f")
19418

195-
# spawner.environment = {"JUPYTERHUB_API_URL": "http://hub.gmxhub-ns.svc.cluster.local:8081/hub/api",
196-
# "JUPYTERHUB_ACTIVITY_URL": "http://hub.gmxhub-ns.svc.cluster.local:8081/hub/api/users/"+username+"/activity"}
197-
198-
# ns = await create_ns(username, original)
199-
# sa = await create_sa(username, ns)
200-
# sa = 'hub'
201-
# await create_rb(sa, ns)
202-
203-
await mount_persistent_hub_home(spawner, username, ns)
204-
205-
# spawner.args += [ '--port=8888', '--ip=0.0.0.0', f'--NotebookApp.base_url=/user/{username}/' ]
206-
# spawner.args += [ '--port=8888', '--ip=0.0.0.0' ]
207-
20819
with open(usagelog,"a") as l:
20920
l.write(datetime.datetime.now(datetime.timezone.utc).strftime('%c %z:') + username + '\n')
21021

211-
# gpu = spawner.user_options.get('gpu')
212-
# cpu = spawner.user_options.get('cpu')
213-
# mem = spawner.user_options.get('mem')
214-
# image = spawner.user_options.get('container_image')
215-
216-
# spawner.image = 'ljocha/gromacs-hub'
21722
spawner.image = get_config('hub.config.notebookImage')
21823
spawner.cpu_limit = 1.
21924
spawner.cpu_guarantee = .2
@@ -222,10 +27,4 @@ async def bootstrap_pre_spawn(spawner):
22227
spawner.container_security_context = {"capabilities": {"drop": ["ALL"]}}
22328

22429
c.KubeSpawner.pre_spawn_hook = bootstrap_pre_spawn
225-
#c.KubeSpawner.enable_user_namespaces = True
226-
#c.KubeSpawner.user_namespace_template = nsprefix + "{username}" + nssuffix
227-
#c.KubeSpawner.enable_user_namespaces = False
228-
#c.KubeSpawner.user_namespace_template = "jupyterhub-{username}-prod-ns"
22930
c.KubeSpawner.automount_service_account_token = False
230-
#c.KubeSpawner.service_account = "sa-{username}"
231-
# c.KubeSpawner.service_account = "metadynminer-jobs"

0 commit comments

Comments
 (0)