Skip to content

Commit 6640e4d

Browse files
feat(vre-swan-cern): change parent base and overwrite jupyter_server_config.py with VRE options (#88)
1 parent c10cd22 commit 6640e4d

File tree

2 files changed

+174
-6
lines changed

2 files changed

+174
-6
lines changed

vre-swan-cern/Dockerfile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
#ARG VERSION_PARENT=v0.0.32
2-
#FROM gitlab-registry.cern.ch/swan/docker-images/jupyter/swan:${VERSION_PARENT}
3-
# Same image as swan-cern/v0.0.48 - VRE-ied
4-
5-
ARG VERSION_PARENT=sha-beea694
6-
FROM ghcr.io/vre-hub/vre-swan:${VERSION_PARENT}
1+
ARG VERSION_PARENT=v0.0.33
2+
FROM gitlab-registry.cern.ch/swan/docker-images/jupyter/swan:${VERSION_PARENT}
73

84
LABEL maintainer="[email protected]"
95
ARG NB_UID="1000"
@@ -38,6 +34,10 @@ RUN pip install --no-deps --no-cache-dir rucio-jupyterlab==${RUCIO_JUPYTERLAB_VE
3834
RUN pip install --no-deps --no-cache-dir --target ${SWAN_LIB_DIR}/nb_term_lib \
3935
swandaskcluster==3.1.0
4036

37+
# Overwrite Python configuration, including section for the VRE
38+
# Add jupyter notebook configuration
39+
ADD python/jupyter_server_config.py /home/${NB_USER}/.jupyter/jupyter_server_config.py
40+
4141
# Add helper scripts
4242
COPY scripts/others/* /srv/singleuser/
4343

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
import os
2+
import json
3+
from site import getsitepackages
4+
5+
home = os.environ.get("HOME")
6+
jupyter_path = os.environ.get("JUPYTER_PATH", f"{home}/.local/share/jupyter")
7+
8+
c.NotebookNotary.db_file = f"{jupyter_path}/nbsignatures.db"
9+
c.NotebookNotary.secret_file = f"{jupyter_path}/notebook_secret"
10+
11+
# Configure jupyter lab to start in the HOME of the user
12+
# which is usually EOS for CERN users.
13+
c.ServerApp.root_dir = home
14+
15+
c.ServerApp.contents_manager_class = "swancontents.filemanager.SwanEosFileManager"
16+
# To allow deleting Projects, which are never empty because of .swancontents
17+
c.FileContentsManager.always_delete_dir = True
18+
19+
cernbox_oauth_id = os.environ.get("CERNBOX_OAUTH_ID", "cernbox-service")
20+
eos_oauth_id = os.environ.get("EOS_OAUTH_ID", "eos-service")
21+
oauth2_file = os.environ.get("OAUTH2_FILE", "")
22+
oauth_inspection_endpoint = os.environ.get("OAUTH_INSPECTION_ENDPOINT", "")
23+
c.SwanOauthRenew.files = [
24+
("/tmp/swan_oauth.token", "access_token", "{token}"),
25+
("/tmp/cernbox_oauth.token", f"exchanged_tokens/{cernbox_oauth_id}", "{token}"),
26+
(oauth2_file, f"exchanged_tokens/{eos_oauth_id}", "oauth2:{token}:" + oauth_inspection_endpoint)
27+
]
28+
29+
# Toggle JupyterLab based on user preference
30+
use_jupyterlab = os.environ.get('SWAN_USE_JUPYTERLAB', 'false').lower() == 'true'
31+
if use_jupyterlab:
32+
c.ServerApp.default_url = '/lab'
33+
else:
34+
c.ServerApp.default_url = '/projects'
35+
36+
user = os.environ.get('USER')
37+
# Change the HOME environment variable to the local user home instead of EOS
38+
# to prevent xelatex from touching EOS during the PDF conversion and so
39+
# reduce the time it takes to convert a PDF (including preventing timeouts).
40+
c.PDFExporter.latex_command = ['env', f'HOME=/home/{user}' , 'xelatex', '-quiet', '{filename}']
41+
42+
# Configure path to SwanCustomenvironments template
43+
for path in getsitepackages():
44+
candidate = os.path.join(path, "swancustomenvironments", "templates")
45+
if os.path.isdir(candidate):
46+
c.ServerApp.extra_template_paths = [candidate]
47+
break
48+
49+
# CERN-VRE - Configure the JupyterLab server - TRIGGERED TO ALWAYS WORK
50+
use_rucio_extension = os.environ.get('USE_RUCIO_EXTENSION', 'true').lower() == 'true'
51+
if use_rucio_extension:
52+
53+
def write_jupyterlab_config():
54+
dir_config_jupyterlab = os.getenv('JUPYTER_CONFIG_DIR',
55+
os.path.join(os.getenv('HOME'), '.jupyter')
56+
)
57+
file_server_config = os.path.join(dir_config_jupyterlab, 'jupyter_server_config.json')
58+
59+
if not os.path.exists(dir_config_jupyterlab):
60+
os.makedirs( dir_config_jupyterlab, exist_ok=True)
61+
elif os.path.isfile(file_server_config) :
62+
with open(file_server_config, "r") as config_file:
63+
config_payload = config_file.read()
64+
65+
try:
66+
config_json = json.loads(config_payload)
67+
except:
68+
config_json = {}
69+
70+
escape_config = {
71+
"name": os.getenv('RUCIO_NAME', 'vre-rucio.cern.ch'),
72+
"display_name": os.getenv('RUCIO_DISPLAY_NAME', 'ESCAPE Rucio instance'),
73+
"rucio_base_url": os.getenv('RUCIO_BASE_URL', 'https://vre-rucio.cern.ch'),
74+
"rucio_auth_url": os.getenv('RUCIO_AUTH_URL', 'https://vre-rucio-auth.cern.ch'),
75+
"rucio_webui_url": os.getenv('RUCIO_WEBUI_URL', 'https://vre-rucio-ui.cern.ch'),
76+
"rucio_ca_cert": os.getenv('RUCIO_CA_CERT', '/eos/user/e/engarcia/rucio_ca_certs/rucio_ca.pem'),
77+
"site_name": os.getenv('RUCIO_SITE_NAME', 'CERN'),
78+
"vo": os.getenv('RUCIO_VO', 'escape'),
79+
"voms_enabled": os.getenv('RUCIO_VOMS_ENABLED', '0') == '1',
80+
"voms_vomses_path": os.getenv('RUCIO_VOMS_VOMSES_PATH', '/etc/vomses'),
81+
"voms_certdir_path": os.getenv('RUCIO_VOMS_CERTDIR_PATH',),
82+
"voms_vomsdir_path": os.getenv('RUCIO_VOMS_VOMSDIR_PATH', '/etc/grid-security/vomsdir'),
83+
"destination_rse": os.getenv('RUCIO_DESTINATION_RSE', 'CERN-EOSPILOT'),
84+
"rse_mount_path": os.getenv('RUCIO_RSE_MOUNT_PATH', '/eos/eulake'),
85+
"replication_rule_lifetime_days": int(os.getenv('RUCIO_REPLICATION_RULE_LIFETIME_DAYS')) if os.getenv('RUCIO_REPLICATION_RULE_LIFETIME_DAYS') else None,
86+
"path_begins_at": int(os.getenv('RUCIO_PATH_BEGINS_AT', '5')),
87+
"mode": os.getenv('RUCIO_MODE', 'replica'),
88+
"wildcard_enabled": os.getenv('RUCIO_WILDCARD_ENABLED', '1') == '1',
89+
#"oidc_auth": os.getenv('RUCIO_OIDC_AUTH'),
90+
#"oidc_env_name": os.getenv('RUCIO_OIDC_ENV_NAME'),
91+
#"oidc_file_name": os.getenv('RUCIO_OIDC_FILE_NAME'),
92+
}
93+
atlas_config = {
94+
"name": os.getenv('ATLAS_RUCIO_NAME', 'https://voatlasrucio-server-prod.cern.ch'),
95+
"display_name": os.getenv('ATLAS_RUCIO_DISPLAY_NAME', 'ATLAS RUCIO'),
96+
"rucio_base_url": os.getenv('ATLAS_RUCIO_BASE_URL', 'https://voatlasrucio-server-prod.cern.ch:443'),
97+
"rucio_auth_url": os.getenv('ATLAS_RUCIO_AUTH_URL', 'https://atlas-rucio-auth.cern.ch:443'),
98+
"rucio_webui_url": os.getenv('ATLAS_RUCIO_WEBUI_URL', 'https://rucio-ui.cern.ch'),
99+
"rucio_ca_cert": os.getenv('RUCIO_CA_CERT', '/eos/user/e/engarcia/rucio_ca_certs/rucio_ca.pem'),
100+
"site_name": os.getenv('ATLAS_RUCIO_SITE_NAME', 'CERN'),
101+
"vo": os.getenv('ATLAS_RUCIO_VO', 'atlas'),
102+
"voms_enabled": os.getenv('RUCIO_VOMS_ENABLED', '0') == '1',
103+
"voms_vomses_path": os.getenv('RUCIO_VOMS_VOMSES_PATH', '/etc/vomses'),
104+
"voms_certdir_path": os.getenv('RUCIO_VOMS_CERTDIR_PATH',),
105+
"voms_vomsdir_path": os.getenv('RUCIO_VOMS_VOMSDIR_PATH', '/etc/grid-security/vomsdir'),
106+
"destination_rse": os.getenv('ATLAS_RUCIO_DESTINATION_RSE', 'CERN-PROD_PHYS-TOP'),
107+
"rse_mount_path": os.getenv('ATLAS_RUCIO_RSE_MOUNT_PATH', '/eos/atlas/atlasgroupdisk/phys-top'),
108+
"replication_rule_lifetime_days": int(os.getenv('ATLAS_RUCIO_REPLICATION_RULE_LIFETIME_DAYS')) if os.getenv('ATLAS_RUCIO_REPLICATION_RULE_LIFETIME_DAYS') else None,
109+
"path_begins_at": int(os.getenv('ATLAS_RUCIO_PATH_BEGINS_AT', '4')),
110+
"mode": os.getenv('ATLAS_RUCIO_MODE', 'replica'),
111+
"wildcard_enabled": os.getenv('ATLAS_RUCIO_WILDCARD_ENABLED', '1') == '1',
112+
}
113+
114+
115+
escape_config = {k: v for k,
116+
v in escape_config.items() if v is not None}
117+
118+
atlas_config = {k: v for k,
119+
v in atlas_config.items() if v is not None}
120+
121+
config_json['RucioConfig'] = {
122+
'instances': [escape_config, atlas_config], # cms,
123+
"default_instance": os.getenv('RUCIO_DEFAULT_INSTANCE', escape_config['name']),
124+
"default_auth_type": os.getenv('RUCIO_DEFAULT_AUTH_TYPE', 'x509_proxy'),
125+
"log_level": os.getenv('RUCIO_LOG_LEVEL', 'debug'),
126+
}
127+
128+
config_file = open(file_server_config, 'w')
129+
config_file.write(json.dumps(config_json, indent=2))
130+
config_file.close()
131+
132+
def write_ipython_config():
133+
file_path = os.path.join(os.getenv('HOME'), '.ipython/profile_default')
134+
file_name = os.path.join(file_path, 'ipython_kernel_config.json')
135+
extension_module = 'rucio_jupyterlab.kernels.ipython'
136+
137+
if not os.path.isfile(file_name):
138+
os.makedirs(file_path, exist_ok=True)
139+
else:
140+
config_file = open(file_name, 'r')
141+
config_payload = config_file.read()
142+
config_file.close()
143+
144+
try:
145+
config_json = json.loads(config_payload)
146+
except:
147+
config_json = {}
148+
149+
if 'IPKernelApp' not in config_json:
150+
config_json['IPKernelApp'] = {}
151+
152+
ipkernel_app = config_json['IPKernelApp']
153+
154+
if 'extensions' not in ipkernel_app:
155+
ipkernel_app['extensions'] = []
156+
157+
if extension_module not in ipkernel_app['extensions']:
158+
ipkernel_app['extensions'].append(extension_module)
159+
160+
config_file = open(file_name, 'w')
161+
config_file.write(json.dumps(config_json, indent=2))
162+
config_file.close()
163+
164+
write_jupyterlab_config()
165+
write_ipython_config()
166+
167+
else:
168+
pass

0 commit comments

Comments
 (0)