|
1 | 1 | import os |
| 2 | +import sys |
2 | 3 |
|
3 | 4 | from coursewareuserspawner import CoursewareUserSpawner |
4 | 5 | from jinja2 import Environment, BaseLoader |
5 | | -from jupyterhub.handlers.static import CacheControlStaticFilesHandler |
6 | 6 | from traitlets import Unicode |
| 7 | +from tornado import web |
7 | 8 |
|
8 | | -from .builder import BuildHandler, DefaultCouseImageHandler |
9 | 9 | from .registry import get_registry, split_image_name |
10 | | -from .images import ImagesHandler |
11 | | -from .logs import LogsHandler |
12 | 10 |
|
13 | 11 |
|
14 | 12 | class Repo2DockerSpawner(CoursewareUserSpawner): |
@@ -102,6 +100,19 @@ async def get_options_form(self): |
102 | 100 | ) |
103 | 101 | return image_form_template.render(image_list=images, registry_host=self._registry.host) |
104 | 102 |
|
| 103 | + async def check_allowed(self, image): |
| 104 | + images = await self._registry.list_images() |
| 105 | + |
| 106 | + registry_host = self._registry.host |
| 107 | + image_names = [ |
| 108 | + f'{registry_host}/{image["image_name"]}' |
| 109 | + for image in images |
| 110 | + ] |
| 111 | + |
| 112 | + if image not in image_names: |
| 113 | + raise web.HTTPError(400, "Specifying image to launch is not allowed") |
| 114 | + return image |
| 115 | + |
105 | 116 | def _use_default_course_image(self, images): |
106 | 117 | self.image = self._registry.get_default_course_image() |
107 | 118 |
|
@@ -156,28 +167,49 @@ async def create_object(self, *args, **kwargs): |
156 | 167 | return await super().create_object(*args, **kwargs) |
157 | 168 |
|
158 | 169 |
|
159 | | -def cwh_repo2docker_jupyterhub_config(c): |
| 170 | +def cwh_repo2docker_jupyterhub_config( |
| 171 | + c, |
| 172 | + config_file=None, |
| 173 | + service_name='environments', |
| 174 | + custom_menu=False, |
| 175 | + service_environments={}, |
| 176 | + debug=False): |
160 | 177 | # hub |
161 | 178 | c.JupyterHub.spawner_class = Repo2DockerSpawner |
162 | 179 |
|
163 | | - # add extra templates for the service UI |
164 | | - c.JupyterHub.template_paths.insert( |
165 | | - 0, os.path.join(os.path.dirname(__file__), "templates") |
166 | | - ) |
167 | | - |
168 | 180 | c.DockerSpawner.cmd = ["jupyterhub-singleuser"] |
169 | 181 |
|
170 | | - # register the handlers to manage the user images |
171 | | - c.JupyterHub.extra_handlers.extend( |
172 | | - [ |
173 | | - (r"environments", ImagesHandler), |
174 | | - (r"api/environments", BuildHandler), |
175 | | - (r"api/environments/default-course-image", DefaultCouseImageHandler), |
176 | | - (r"api/environments/([^/]+)/logs", LogsHandler), |
177 | | - ( |
178 | | - r"environments-static/(.*)", |
179 | | - CacheControlStaticFilesHandler, |
180 | | - {"path": os.path.join(os.path.dirname(__file__), "static")}, |
181 | | - ), |
182 | | - ] |
183 | | - ) |
| 182 | + if custom_menu: |
| 183 | + # add extra templates for the service UI |
| 184 | + c.JupyterHub.template_paths.insert( |
| 185 | + 0, os.path.join(os.path.dirname(__file__), "custom_templates") |
| 186 | + ) |
| 187 | + |
| 188 | + service_command = [ |
| 189 | + sys.executable, |
| 190 | + "-m", "cwh_repo2docker.service", |
| 191 | + ] |
| 192 | + |
| 193 | + if config_file is not None: |
| 194 | + service_command.extend([ |
| 195 | + "--config-file", config_file |
| 196 | + ]) |
| 197 | + |
| 198 | + if debug: |
| 199 | + service_command.extend([ |
| 200 | + "--debug" |
| 201 | + ]) |
| 202 | + |
| 203 | + c.JupyterHub.template_vars.update({ |
| 204 | + 'cwh_repo2docker_service_name': service_name |
| 205 | + }) |
| 206 | + |
| 207 | + c.JupyterHub.services.extend([{ |
| 208 | + "name": service_name, |
| 209 | + "command": service_command, |
| 210 | + "url": "http://127.0.0.1:10101", |
| 211 | + "display": not custom_menu, |
| 212 | + "oauth_no_confirm": True, |
| 213 | + "environment": service_environments, |
| 214 | + "oauth_client_allowed_scopes": ["inherit"] |
| 215 | + }]) |
0 commit comments