Skip to content

Commit 8a67f13

Browse files
committed
Fixed issue where user was not sent in the correct work folder @ container startup. Changed default pwd.
1 parent 76418b8 commit 8a67f13

File tree

5 files changed

+83
-66
lines changed

5 files changed

+83
-66
lines changed

Dockerfile_singleuser

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ COPY notebooks /home/jovyan/work/
191191
WORKDIR /home/jovyan
192192
USER jovyan
193193

194+
RUN echo "cd /home/jovyan/work" >> /home/jovyan/.bashrc
195+
194196
# Configure container startup
195197
ENTRYPOINT ["tini", "-g", "--"]
196198

Dockerfile_singleuser_gpu

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ COPY notebooks /home/jovyan/work/
220220
WORKDIR /home/jovyan
221221
USER jovyan
222222

223+
RUN echo "cd /home/jovyan/work" >> /home/jovyan/.bashrc
224+
223225
# Configure container startup
224226
ENTRYPOINT ["tini", "-g", "--"]
225227

config/jupyterhub_config.py

Lines changed: 74 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -16,107 +16,104 @@ class LocalNativeAuthenticator(NativeAuthenticator, LocalAuthenticator):
1616
pass
1717

1818

19-
c: Config = get_config()
20-
21-
# Spawn containers from this image
22-
# Either use the CoGstack one from the repo which is huge and contains all the stuff needed or,
23-
# use the default official one which is clean.
24-
c.DockerSpawner.image = os.getenv("DOCKER_NOTEBOOK_IMAGE", "cogstacksystems:jupyterhub/singleuser:latest-amd64")
19+
DOCKER_NOTEBOOK_IMAGE = os.getenv("DOCKER_NOTEBOOK_IMAGE", "cogstacksystems:jupyterhub/singleuser:latest-amd64")
2520

2621
# JupyterHub requires a single-user instance of the Notebook server, so we
2722
# default to using the `start-singleuser.sh` script included in the
2823
# jupyter/docker-stacks *-notebook images as the Docker run command when
2924
# spawning containers. Optionally, you can override the Docker run command
3025
# using the DOCKER_SPAWN_CMD environment variable.
31-
spawn_cmd = os.environ.get("DOCKER_SPAWN_CMD", "start-singleuser.sh")
26+
SPAWN_CMD = os.environ.get("DOCKER_SPAWN_CMD", "start-singleuser.sh")
3227

3328
# Connect containers to this Docker network
3429
# IMPORTANT, THIS MUST MATCH THE NETWORK DECLARED in "services.yml", by default: "cogstack-net"
35-
network_name = os.environ.get("DOCKER_NETWORK_NAME", "cogstack-net")
30+
NETWORK_NAME = os.environ.get("DOCKER_NETWORK_NAME", "cogstack-net")
3631

3732
# The IP address or hostname of the JupyterHub container in the Docker network
38-
hub_container_ip_or_name = os.environ.get("DOCKER_JUPYTER_HUB_CONTAINER_NAME", "cogstack-jupyter-hub")
33+
HUB_CONTAINER_IP_OR_NAME = os.environ.get("DOCKER_JUPYTER_HUB_CONTAINER_NAME", "cogstack-jupyter-hub")
3934

4035
# The timeout in seconds after which the idle notebook container will be shutdown
41-
notebook_idle_timeout = os.environ.get("DOCKER_NOTEBOOK_IDLE_TIMEOUT", "7200")
36+
NOTEBOOK_IDLE_TIMEOUT = int(os.environ.get("DOCKER_NOTEBOOK_IDLE_TIMEOUT", "7200"))
4237

43-
c.DockerSpawner.use_internal_ip = True
44-
c.DockerSpawner.network_name = network_name
45-
# Pass the network name as argument to spawned containers
46-
c.DockerSpawner.extra_host_config = {"network_mode": network_name}
38+
SELECT_NOTEBOOK_IMAGE_ALLOWED = str(os.environ.get("DOCKER_SELECT_NOTEBOOK_IMAGE_ALLOWED", "false")).lower()
39+
40+
RUN_IN_DEBUG_MODE = str(os.environ.get("DOCKER_NOTEBOOK_DEBUG_MODE", "false")).lower()
4741

4842
# Explicitly set notebook directory because we"ll be mounting a host volume to
4943
# it. Most jupyter/docker-stacks *-notebook images run the Notebook server as
5044
# user `jovyan`, and set the notebook directory to `/home/jovyan/work`.
5145
# We follow the same convention.
52-
notebook_dir = os.environ.get("DOCKER_NOTEBOOK_DIR", "/home/jovyan/work")
53-
shared_content_dir = os.environ.get("DOCKER_SHARED_DIR", "/home/jovyan/scratch")
54-
work_dir = os.environ.get("JUPYTER_WORK_DIR", "/lab/workspaces/auto-b/tree/" + str(notebook_dir.split("/")[-1]))
55-
56-
#c.DockerSpawner.notebook_dir = notebook_dir
57-
# Mount the real user"s Docker volume on the host to the notebook user"s
58-
# notebook directory in the container
59-
c.DockerSpawner.volumes = {"jupyterhub-user-{username}": notebook_dir, "jupyter-hub-shared-scratch": shared_content_dir}
60-
# volume_driver is no longer a keyword argument to create_container()
46+
NOTEBOOK_DIR = os.environ.get("DOCKER_NOTEBOOK_DIR", "/home/jovyan/work")
47+
SHARED_CONTENT_DIR = os.environ.get("DOCKER_SHARED_DIR", "/home/jovyan/scratch")
48+
#WORK_DIR = os.environ.get("DOCKER_JUPYTER_WORK_DIR", "/lab/workspaces/auto-b/tree/" + str(NOTEBOOK_DIR.split("/")[-1]))
49+
WORK_DIR = "/lab/"
6150

51+
ENV_PROXIES = {
52+
"HTTP_PROXY": os.environ.get("HTTP_PROXY", ""),
53+
"HTTPS_PROXY": os.environ.get("HTTPS_PROXY", ""),
54+
"NO_PROXY": ",".join(list(filter(len, os.environ.get("NO_PROXY", "").split(",") + [HUB_CONTAINER_IP_OR_NAME]))),
55+
"http_proxy": os.environ.get("HTTP_PROXY", os.environ.get("http_proxy", "")),
56+
"https_proxy": os.environ.get("HTTPS_PROXY", os.environ.get("https_proxy", "")),
57+
"no_proxy": ",".join(list(filter(len, os.environ.get("no_proxy", "").split(",") + [HUB_CONTAINER_IP_OR_NAME]))),
58+
}
59+
60+
os.environ["NO_PROXY"] = ""
61+
os.environ["no_proxy"] = ""
62+
os.environ["HTTP_PROXY"] = ""
63+
os.environ["HTTPS_PROXY"] = ""
64+
os.environ["http_proxy"] = ""
65+
os.environ["https_proxy"] = ""
66+
67+
c: Config = get_config()
68+
69+
# Spawn containers from this image
70+
# Either use the CoGstack one from the repo which is huge and contains all the stuff needed or,
71+
# use the default official one which is clean.
72+
c.DockerSpawner.image = DOCKER_NOTEBOOK_IMAGE
73+
74+
c.DockerSpawner.use_internal_ip = True
75+
c.DockerSpawner.network_name = NETWORK_NAME
76+
# Pass the network name as argument to spawned containers
77+
c.DockerSpawner.extra_host_config = {"network_mode": NETWORK_NAME}
78+
79+
# # Mount the real users Docker volume on the host to the notebook user"s
80+
# # notebook directory in the container
81+
c.DockerSpawner.volumes = {"jupyterhub-user-{username}": NOTEBOOK_DIR, "jupyter-hub-shared-scratch": SHARED_CONTENT_DIR}
82+
83+
# volume_driver is no longer a keyword argument to create_container()
6284

6385
# Remove containers once they are stopped
64-
# c.DockerSpawner.remove_containers = False # Deprected for c.DockerSpawner.remove
6586
c.DockerSpawner.remove = False
6687

67-
select_notebook_image_allowed = os.environ.get("DOCKER_SELECT_NOTEBOOK_IMAGE_ALLOWED", "false")
68-
if select_notebook_image_allowed == "true":
88+
89+
if SELECT_NOTEBOOK_IMAGE_ALLOWED == "true":
6990
# c.DockerSpawner.image_whitelist has been deprecated for allowed_images
7091
c.DockerSpawner.allowed_images = {
7192
"minimal": "jupyterhub/singleuser:latest-amd64",
7293
"cogstack": "cogstacksystems/jupyter-singleuser:latest-amd64",
73-
"cogstack-gpu": "cogstacksystem s/jupyter-singleuser-gpu:latest-amd64"
94+
"cogstack-gpu": "cogstacksystems/jupyter-singleuser-gpu:latest-amd64"
7495
}
7596
# https://github.com/jupyterhub/dockerspawner/issues/423
7697
c.DockerSpawner.remove = True
7798

78-
run_in_debug_mode = os.environ.get("DOCKER_NOTEBOOK_DEBUG_MODE", "false")
79-
80-
if run_in_debug_mode == "true":
99+
if RUN_IN_DEBUG_MODE == "true":
81100
# For debugging arguments passed to spawned containers
82101
c.DockerSpawner.debug = True
83102
c.Spawner.debug = True
84103
# Enable debug-logging of the single-user server
85104
c.LocalProcessSpawner.debug = True
86105

87-
ENV_PROXIES = {
88-
"HTTP_PROXY": os.environ.get("HTTP_PROXY", ""),
89-
"HTTPS_PROXY": os.environ.get("HTTPS_PROXY", ""),
90-
"NO_PROXY": ",".join(list(filter(len, os.environ.get("NO_PROXY", "").split(",") + [hub_container_ip_or_name]))),
91-
"http_proxy": os.environ.get("HTTP_PROXY", os.environ.get("http_proxy", "")),
92-
"https_proxy": os.environ.get("HTTPS_PROXY", os.environ.get("https_proxy", "")),
93-
"no_proxy": ",".join(list(filter(len, os.environ.get("no_proxy", "").split(",") + [hub_container_ip_or_name]))),
94-
}
95-
96-
os.environ["NO_PROXY"] = ""
97-
os.environ["no_proxy"] = ""
98-
os.environ["HTTP_PROXY"] = ""
99-
os.environ["HTTPS_PROXY"] = ""
100-
os.environ["http_proxy"] = ""
101-
os.environ["https_proxy"] = ""
102-
103-
104-
"""
105-
def pre_spawn_hook(spawner):
106-
username = str(spawner.user.name).lower()
107-
try:
108-
pwd.getpwnam(username)
109-
except KeyError:
110-
subprocess.check_call(["useradd", "-ms", "/bin/bash", username])
111-
"""
112-
113106

114107
# Spawn single-user servers as Docker containers
115108
class DockerSpawner(dockerspawner.DockerSpawner):
116109
def start(self):
117110
# username is self.user.name
118-
self.volumes = {"jupyterhub-user-{}".format(self.user.name): notebook_dir}
111+
self.volumes = {"jupyterhub-user-{}".format(self.user.name): NOTEBOOK_DIR}
119112

113+
# Mount the real users Docker volume on the host to the notebook user"s
114+
# # notebook directory in the container
115+
#self.volumes = {f"jupyterhub-user-{self.user.name}": NOTEBOOK_DIR, "jupyter-hub-shared-scratch": SHARED_CONTENT_DIR}
116+
120117
if self.user.name not in whitelist:
121118
whitelist.add(self.user.name)
122119
with open(userlist_path, "a") as f:
@@ -125,15 +122,15 @@ def start(self):
125122

126123
if self.user.name in list(team_map.keys()):
127124
for team in team_map[self.user.name]:
128-
team_dir_path = os.path.join(shared_content_dir, team)
125+
team_dir_path = os.path.join(SHARED_CONTENT_DIR, team)
129126
self.volumes["jupyterhub-team-{}".format(team)] = {
130127
"bind": team_dir_path,
131128
"mode": "rw", # or ro for read-only
132129
}
133130

134131
# this is a temporary fix, need to actually check permissions
135132
self.mem_limit = resource_allocation_user_ram_limit
136-
self.post_start_cmd = "chmod -R 777 " + shared_content_dir
133+
self.post_start_cmd = "chmod -R 777 " + SHARED_CONTENT_DIR
137134

138135
return super().start()
139136

@@ -151,7 +148,17 @@ def pre_spawn_hook(spawner: DockerSpawner):
151148
traceback.print_exc()
152149

153150

154-
c.Spawner.default_url = work_dir
151+
"""
152+
def pre_spawn_hook(spawner):
153+
username = str(spawner.user.name).lower()
154+
try:
155+
pwd.getpwnam(username)
156+
except KeyError:
157+
subprocess.check_call(["useradd", "-ms", "/bin/bash", username])
158+
"""
159+
160+
161+
c.Spawner.default_url = WORK_DIR
155162
c.Spawner.pre_spawn_hook = pre_spawn_hook
156163

157164
#c.Spawner.ip = "127.0.0.1"
@@ -203,10 +210,12 @@ def per_user_limit(role):
203210
c.JupyterHub.spawner_class = DockerSpawner
204211

205212
# set DockerSpawner args
206-
c.DockerSpawner.extra_create_kwargs.update({"command": spawn_cmd})
213+
c.DockerSpawner.extra_create_kwargs.update({"command": SPAWN_CMD})
207214
# c.DockerSpawner.extra_create_kwargs.update({ "volume_driver": "local" })
208215
c.DockerSpawner.extra_create_kwargs = {"user": "root"}
209216

217+
c.DockerSpawner.notebook_dir = NOTEBOOK_DIR
218+
210219
with open(userlist_path) as f:
211220
for line in f:
212221
if not line:
@@ -277,7 +286,7 @@ def per_user_limit(role):
277286
# User containers will access hub by container name on the Docker network
278287
c.JupyterHub.ip = "0.0.0.0"
279288
c.JupyterHub.hub_ip = "0.0.0.0"
280-
c.JupyterHub.hub_connect_ip = hub_container_ip_or_name
289+
c.JupyterHub.hub_connect_ip = HUB_CONTAINER_IP_OR_NAME
281290

282291

283292
jupyter_hub_port = int(os.environ.get("JUPYTERHUB_INTERNAL_PORT", 8888))
@@ -301,14 +310,15 @@ def per_user_limit(role):
301310
c.JupyterHub.cookie_secret_file = data_dir + "jupyterhub_cookie_secret"
302311

303312
c.JupyterHub.services = []
304-
if int(notebook_idle_timeout) > 0:
313+
314+
if NOTEBOOK_IDLE_TIMEOUT > 0:
305315
c.JupyterHub.services.append({
306316
"name": "idle-culler",
307317
"admin": True,
308318
"command": [
309319
sys.executable,
310320
"-m", "jupyterhub_idle_culler",
311-
f"--timeout={notebook_idle_timeout}",
321+
f"--timeout={NOTEBOOK_IDLE_TIMEOUT}",
312322
],
313323
})
314324

env/jupyter.env

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ SSL_KEY="/srv/jupyterhub/root-ca.key"
3535
SSL_CERT="/srv/jupyterhub/root-ca.pem"
3636

3737
DOCKER_NETWORK_NAME="cogstack-net"
38-
DOCKER_JUPYTER_HUB_CONTAINER_NAME="cogstack-jupyter-hub"
38+
39+
# This needs to match the container name of jupyter-hub. In DEV_MODE, change this to : cogstack-jupyter-hub-dev
40+
DOCKER_JUPYTER_HUB_CONTAINER_NAME="cogstack-jupyter-hub-dev"
3941

4042
# general user resource cap per container, default 2 cores, 2GB ram
4143
RESOURCE_ALLOCATION_USER_CPU_LIMIT="2"

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,5 @@ xnat==0.7.1
4545
plotly==6.1.1
4646
click==8.2.1
4747
medcat==1.16.0
48-
torchvision>=0.20.1
48+
torchvision>=0.20.1
49+
traitlets==5.14.3

0 commit comments

Comments
 (0)