Skip to content
Snippets Groups Projects
Commit 6a58a802 authored by František Dvořák's avatar František Dvořák
Browse files

EGI devel deployment

* OpenStack infrastructure
* Kubernetes
* Jupyter Notebooks
* Sonatype Nexus repository
* tune email config
* Matlab
* local accounting
* backup and recover
parent 24f9316b
Branches
Tags v1.1
No related merge requests found
Showing
with 596 additions and 2 deletions
...@@ -67,7 +67,7 @@ ...@@ -67,7 +67,7 @@
inet_protocols: ipv4 inet_protocols: ipv4
set_fact: set_fact:
main: '{{ main | combine(main_cesnet) }}' main: '{{ main | combine(main_cesnet) }}'
when: site_name == "cesnet-testing" or site_name == "cesnet-mcc" when: site_name is regex('^(cesnet|egi)-')
- name: Site-specific postfix settings - mail_fromdomain - name: Site-specific postfix settings - mail_fromdomain
set_fact: set_fact:
main: '{{ main | combine({"myhostname": mail_fromdomain}) }}' main: '{{ main | combine({"myhostname": mail_fromdomain}) }}'
...@@ -90,7 +90,7 @@ ...@@ -90,7 +90,7 @@
src: templates/etc/mailutils.conf src: templates/etc/mailutils.conf
dest: /etc/mailutils.conf dest: /etc/mailutils.conf
mode: 0644 mode: 0644
when: (site_name == "cesnet-testing" or site_name == "cesnet-mcc" or mail_fromdomain is defined) and not (mail_local | default(false)) when: (site_name is regex('^(cesnet|egi)-') or mail_fromdomain is defined) and not (mail_local | default(false))
rescue: rescue:
- name: Mail Settings Fail - name: Mail Settings Fail
fail: fail:
......
accounting:
# schedule: 23 */6 * * *
sitename: EGI-NOTEBOOKS-DEVEL2
default_fqan: vo.notebooks.egi.eu
# fqan_key: primary_group
fqan:
auger: urn:mace:egi.eu:group:auger:role=member#aai.egi.eu
biomed: urn:mace:egi.eu:group:biomed:role=member#aai.egi.eu
eiscat.se: urn:mace:egi.eu:group:eiscat.se:Dev:role=member#aai.egi.eu,urn:mace:egi.eu:group:eiscat.se:Hub:role=member#aai.egi.eu,urn:mace:egi.eu:group:cc-eiscat3d#sso.egi.eu
eval.c-scale.eu: urn:mace:egi.eu:group:eval.c-scale.eu:role=member#aai.egi.eu
vo.cessda.eduteams.org: urn:mace:egi.eu:group:vo.cessda.eduteams.org:role=member#aai.egi.eu
vo.environmental.egi.eu: urn:mace:egi.eu:group:vo.environmental.egi.eu:role=member#aai.egi.eu
vo.lethe-project.eu: urn:mace:egi.eu:group:vo.lethe-project.eu:role=member#aai.egi.eu,urn:mace:egi.eu:group:vo.lethe-project.eu:lethe-notebooks:role=member#aai.egi.eu
vo.panosc.eu: urn:mace:egi.eu:group:vo.panosc.eu:role=vm_operator#aai.egi.eu
vo.reliance-project.eu: urn:mace:egi.eu:group:vo.reliance-project.eu:role=member#aai.egi.eu
vo.access.egi.eu: urn:mace:egi.eu:group:vo.access.egi.eu:role=member#aai.egi.eu
vo.notebooks.egi.eu: urn:mace:egi.eu:group:vo.notebooks.egi.eu:role=member#aai.egi.eu
# used in devel
fedcloud.egi.eu: urn:mace:egi.eu:www.egi.eu:fedcloud-users:member@egi.eu,urn:mace:egi.eu:group:fedcloud-users#sso.egi.eu,urn:egi.eu:group:fedcloud-users
debug: true
prometheus:
filter: "pod=~'jupyter-.*'"
storage:
apelSpool: /accounting/ssm
[defaults]
inventory=inventory
[diff]
always=true
#! /bin/bash -xe
#
# Deploy EGI devel instance
#
cd terraform && terraform init && terraform apply
cd -
cp -pv terraform/inventory.yaml inventory/1-cesnet.yaml
# dynamic DNS
ip="$(head -n 1 <terraform/fip.txt)"
shellstate=$(shopt -po xtrace)
set +o xtrace
# https://nsupdate.fedcloud.eu
vault_prefix=secrets/users/e1662e20-e34b-468c-b0ce-d899bc878364@egi.eu/egi-devel
FEDCLOUD_DYNAMIC_DNS=$(vault read -field data $vault_prefix/FEDCLOUD_DYNAMIC_DNS | grep ^map | head -n 1 | sed 's/map\[\(.*\)\]/\1/')
for auth in $FEDCLOUD_DYNAMIC_DNS; do
echo "curl -i -X GET -u $(echo "$auth" | cut -d: -f1):XXX https://nsupdate.fedcloud.eu/nic/update?myip=$ip"
curl -i -X GET -u "$auth" https://nsupdate.fedcloud.eu/nic/update?myip="$ip"
done
eval "$shellstate"
echo "Terraform finished. Check terraform/docker-volume.sh. Continue? (CTRL-C to quit)"
read -r _
# wait for ping and ssh
while read -r ip; do
while ! ping -c 1 "$ip"; do sleep 5; done
ssh-keygen -R "$ip"
while ! ssh egi@"$ip" -o ConnectTimeout=10 -o PreferredAuthentications=publickey -o StrictHostKeyChecking=no :; do sleep 10; done
done <terraform/fip.txt
# check ssh access
ansible -m command -a 'uname -a' allnodes
# wait cloud-init
ansible -m shell -a 'while ! test -f /var/lib/cloud/instance/boot-finished; do sleep 2; done' allnodes
# setup volumes
ansible -m copy -a 'src=terraform/nfs-volume.sh dest=/root/ mode=preserve' nfs
ansible -m command -a '/root/nfs-volume.sh' nfs
ansible -m copy -a 'src=terraform/squid-volume.sh dest=/root/ mode=preserve' 'ingress[0]'
ansible -m command -a '/root/squid-volume.sh' 'ingress[0]'
# kubernetes
ansible-playbook playbooks/k8s.yaml
while ansible -m command -a 'kubectl get pods --all-namespaces' master | tail -n +3 | grep -Ev ' (Running|Completed) '; do sleep 5; done
# docker runtime directory after Kubernetes deployment (problem with unmounts)
ansible -m copy -a 'src=terraform/docker-volume.sh dest=/root/ mode=preserve' 'ingress nfs worker gpu'
ansible -m command -a '/root/docker-volume.sh' 'ingress nfs worker gpu'
ansible-playbook playbooks/squid.yaml
ansible-playbook playbooks/cvmfs.yaml
# image repository
ansible-playbook playbooks/repository-nexus.yaml
# wait for finish
while ansible -m command -a 'kubectl get pods --all-namespaces' master | tail -n +3 | grep -Ev ' (Running|Completed) '; do sleep 5; done
---
proxy:
service:
type: NodePort
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: "nginx"
kubernetes.io/tls-acme: "true"
hosts:
- "{{ notebooks_hostname }}"
tls:
- hosts:
- "{{ notebooks_hostname }}"
secretName: acme-tls-hub
imagePullSecret:
create: true
registry: "{{ registry_notebooks_hostname }}"
username: notebooks-reader
password: "{{ nexus_secrets['notebooks-reader'] }}"
singleuser:
# keep resource limits in sync with:
# - profileList
# - EGI web-page https://www.egi.eu/service/notebooks/
storage:
capacity: 10Gi
dynamic:
pvcNameTemplate: claim-{userid}{servername}
volumeNameTemplate: vol-{userid}{servername}
storageAccessModes: ["ReadWriteMany"]
extraVolumes:
- name: cvmfs-host
hostPath:
path: /cvmfs
type: Directory
- name: b2drop
empty_dir:
extraVolumeMounts:
- name: cvmfs-host
mountPath: "/cvmfs:shared"
- name: b2drop
mountPath: '/mnt/b2drop:shared'
lifecycleHooks:
postStart:
exec:
command:
- "/bin/sh"
- "-c"
- |
ln -snf /mnt/oneclient $HOME/datahub
ln -snf /mnt/b2drop $HOME/b2drop
ln -snf /cvmfs $HOME/cvmfs
mkdir -p /home/jovyan/.notebookCheckpoints
memory:
limit: 6G
guarantee: 128M
cpu:
limit: 2
guarantee: .02
defaultUrl: "/lab"
networkPolicy:
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
app.kubernetes.io/instance: cluster-ingress
image:
name: eginotebooks/single-user
tag: "sha-0e47d79"
profileList:
- display_name: Default EGI environment - 6 GB RAM / 2 core
description: >
The Default notebook environment includes Python, R, Julia and Octave kernels.
default: true
kubespawner_override:
args:
- "--CondaKernelSpecManager.env_filter='/opt/conda$'"
- display_name: Default EGI environment with Elyra and AI tools - 6 GB RAM / 2 core
description: >
The Default notebook environment includes Python, R, Julia and Octave kernels extended with Elyra and AI tools.
kubespawner_override:
args:
- "--CondaKernelSpecManager.env_filter='/opt/conda$'"
image: "eginotebooks/single-user-ai:sha-0e47d79"
- display_name: RELIANCE project environment - 12 GB RAM / 2 core
description: >
Notebook environment for RELIANCE project includes Python, R, Julia and Octave kernels
kubespawner_override:
args:
- "--CondaKernelSpecManager.env_filter='/opt/conda$'"
mem_guarantee: 2G
mem_limit: 12G
vo_claims:
- urn:mace:egi.eu:group:notebooks-support#sso.egi.eu
- urn:mace:egi.eu:group:vo.reliance-project.eu:role=member#aai.egi.eu
- urn:mace:egi.eu:www.egi.eu:notebooks-support:member@egi.eu
- urn:mace:egi.eu:group:notebooks-support#sso.egi.eu
- display_name: MATLAB Environment (Basic) - 4GB RAM / 4 cores
description: >
The MATLAB environment 24.1.0.2537033 (R2024a) (requires a
<a href="https://github.com/mathworks/jupyter-matlab-proxy/blob/main/MATLAB-Licensing-Info.md">
valid license</a>), includes Python and MATLAB kernels
kubespawner_override:
cpu_guarantee: 2
cpu_limit: 4
mem_guarantee: 2G
mem_limit: 4G
image: "{{ registry_notebooks_hostname }}/matlab:r2024a-notebook"
- display_name: MATLAB Environment (Full) - 4GB RAM / 4 cores
description: >
The MATLAB environment 24.1.0.2537033 (R2024a) with toolboxes (requires a
<a href="https://github.com/mathworks/jupyter-matlab-proxy/blob/main/MATLAB-Licensing-Info.md">
valid license</a>), includes Python and MATLAB kernels
kubespawner_override:
cpu_guarantee: 2
cpu_limit: 4
mem_guarantee: 2G
mem_limit: 4G
image: "{{ registry_notebooks_hostname }}/matlab:r2024a-full"
- display_name: EISCAT environment - 4 GB RAM / 2 cores
description: >
The EISCAT environment.
kubespawner_override:
image: "ingemarh/guisdap"
imagePullPolicy: Always
vo_claims:
- urn:mace:egi.eu:group:cc-eiscat3d#sso.egi.eu
- urn:mace:egi.eu:group:eiscat.se:Hub:role=member#aai.egi.eu
- urn:mace:egi.eu:group:notebooks-support#sso.egi.eu
- urn:mace:egi.eu:www.egi.eu:notebooks-support:member@egi.eu
- urn:mace:egi.eu:group:notebooks-support#sso.egi.eu
hub:
services:
status:
url: "http://status-web/"
admin: true
# recommended to keep in sync with common/playbooks/files/jupyterhub-jwt.yaml
# keep k8s-hub version in sync with ../playbooks/notebooks.yaml
image:
name: eginotebooks/hub
# k8s-hub 4.0.0
tag: "sha-aef23d2"
config:
Authenticator:
enable_auth_state: true
admin_users:
- 529a87e5ce04cd5ddd7161734d02df0e2199a11452430803e714cb1309cc3907@egi.eu
- 025166931789a0f57793a6092726c2ad89387a4cc167e7c63c5d85fc91021d18@egi.eu
- 7ce47695f1e7fc91a1156e672f4a47576559938cdbe840355e2429e3a05b4ff8@egi.eu
# fdvorak2 @ aai.egi.eu
- 52cc7599bd1553c9d63e34e4c90b7e84d44967490c28bb4c53fe97b0c881d677@egi.eu
# fdvorak2 @ aai-dev.egi.eu
- c481e0a85e1ae0a5a1480a63e62295ca2f9ac652244947995bd4a0210fbcb77c@egi.eu
# jhradil3 @ aai-dev.egi.eu
- 240c0594fe34ac26cffd82fd0ad85f29d9ad9dfbb46febb05ed42db0bff594d1@egi.eu
# keep in sync with:
# - cesnet/playbooks/templates/binder.yaml
# - documentation/content/en/users/dev-env/notebooks/_index.md
allowed_groups:
# EISCAT Dirac testing
- urn:mace:egi.eu:group:cc-eiscat3d#sso.egi.eu
- urn:mace:egi.eu:group:auger:role=member#aai.egi.eu
- urn:mace:egi.eu:group:biomed:role=member#aai.egi.eu
- urn:mace:egi.eu:group:vo.cessda.eduteams.org:role=member#aai.egi.eu
- urn:mace:egi.eu:group:eiscat.se:Hub:role=member#aai.egi.eu
- urn:mace:egi.eu:group:eval.c-scale.eu:role=member#aai.egi.eu
- urn:mace:egi.eu:group:vo.environmental.egi.eu:role=member#aai.egi.eu
- urn:mace:egi.eu:group:vo.lethe-project.eu:lethe-notebooks:role=member#aai.egi.eu
- urn:mace:egi.eu:group:vo.panosc.eu:role=vm_operator#aai.egi.eu
- urn:mace:egi.eu:group:vo.reliance-project.eu:role=member#aai.egi.eu
- urn:mace:egi.eu:group:vo.access.egi.eu:role=member#aai.egi.eu
- urn:mace:egi.eu:group:vo.notebooks.egi.eu:role=member#aai.egi.eu
- urn:mace:egi.eu:group:vo.bioexcel.eu:role=member#aai.egi.eu
- urn:mace:egi.eu:group:vo.egu2024.egi.eu:role=member#aai.egi.eu
- urn:mace:egi.eu:www.egi.eu:fedcloud-users:member@egi.eu
- urn:mace:egi.eu:www.egi.eu:techsolutions:member@egi.eu
# changed 2022-10
- urn:mace:egi.eu:group:fedcloud-users#sso.egi.eu
- urn:mace:egi.eu:group:supplier-notebooks#sso.egi.eu
- urn:mace:egi.eu:group:techsolutions#sso.egi.eu
- urn:mace:egi.eu:group:notebooks-support#sso.egi.eu
# changed 2025-03
- urn:egi.eu:group:supplier-notebooks
- urn:egi.eu:group:notebooks-support
- urn:egi.eu:group:fedcloud-users
- urn:egi.eu:group:egi-ace-all
auto_login: true
claim_groups_key: "entitlements"
OnedataAuthenticator:
oneprovider_host: "cesnet-oneprovider-01.datahub.egi.eu"
authorize_url: "https://{{ secrets['checkin_host'] }}/auth/realms/egi/protocol/openid-connect/auth"
token_url: "https://{{ secrets['checkin_host'] }}/auth/realms/egi/protocol/openid-connect/token"
userdata_url: "https://{{ secrets['checkin_host'] }}/auth/realms/egi/protocol/openid-connect/userinfo"
client_id: "{{ secrets['client_id'] }}"
client_secret: "{{ secrets['client_secret'] }}"
oauth_callback_url: "https://{{ notebooks_hostname }}/hub/oauth_callback"
scope: ["openid", "profile", "email", "offline_access", "eduperson_scoped_affiliation", "eduperson_entitlement"]
username_key: "sub"
OnedataSpawner:
sidecar_image: "eginotebooks/oneclient-sidecar:sha-9789b9a"
force_direct_io: true
http_timeout: 60
args:
- "--FileCheckpoints.checkpoint_dir='/home/jovyan/.notebookCheckpoints'"
JupyterHub:
admin_access: true
authenticate_prometheus: false
authenticator_class: egi_notebooks_hub.onedata.OnedataAuthenticator
# spawner_class: (in egi-notebooks-b2drop)
extraConfig:
egi-notebooks-welcome: |-
from egi_notebooks_hub.welcome import WelcomeHandler
c.JupyterHub.default_url = "/welcome"
c.JupyterHub.extra_handlers = [(r'/welcome', WelcomeHandler)]
egi-notebooks-b2drop: |-
{%- raw %}
import base64
from jinja2 import BaseLoader
from jinja2 import Environment
from egi_notebooks_hub.onedata import OnedataSpawner
from kubernetes_asyncio.client.rest import ApiException
class B2DropSpawner(OnedataSpawner):
async def auth_state_hook(self, spawner, auth_state):
await super().auth_state_hook(spawner, auth_state)
self.b2drop_ready = False
self.b2drop_user = ""
self.b2drop_pwd = ""
try:
secret = await self.api.read_namespaced_secret(self.token_secret_name, self.namespace)
except ApiException:
return
if secret and secret.data:
self.b2drop_user = base64.b64decode(secret.data.get("b2drop-user", "")).decode()
self.b2drop_pwd = base64.b64decode(secret.data.get("b2drop-pwd", "")).decode()
self.b2drop_ready = (self.b2drop_user and self.b2drop_pwd)
def _render_options_form(self, profile_list):
# old hub: self._profile_list = self._init_profile_list(profile_list)
self._profile_list = self._get_initialized_profile_list(profile_list)
profile_form_template = Environment(loader=BaseLoader).from_string(
self.profile_form_template
)
return profile_form_template.render(profile_list=self._profile_list, b2drop_ready=self.b2drop_ready, b2drop_user=self.b2drop_user, b2drop_pwd=self.b2drop_pwd)
async def pre_spawn_hook(self, spawner):
await super(B2DropSpawner, self).pre_spawn_hook(spawner)
b2drop_user = self.user_options.get("b2drop-user", "")
b2drop_pwd = self.user_options.get("b2drop-pwd", "")
b2drop_remember = self.user_options.get("b2drop-remember", None)
if not (b2drop_user and b2drop_pwd):
secret = await self.api.read_namespaced_secret(self.token_secret_name, self.namespace)
if secret and secret.data:
b2drop_user = base64.b64decode(secret.data.get("b2drop-user", "")).decode()
b2drop_pwd = base64.b64decode(secret.data.get("b2drop-pwd", "")).decode()
if b2drop_user and b2drop_pwd:
volume_mounts = [
{"mountPath": "/b2drop:shared", "name": "b2drop"},
]
spawner.extra_containers.append(
{
"name": "b2drop",
"image": "eginotebooks/webdav-sidecar:sha-e5e8df2",
"env": [
{"name": "WEBDAV_URL", "value": "https://b2drop.eudat.eu/remote.php/webdav"},
{"name": "WEBDAV_PWD", "value": b2drop_pwd},
{"name": "WEBDAV_USER", "value": b2drop_user},
{"name": "MOUNT_PATH", "value": "/b2drop"},
],
"resources": self.sidecar_resources,
# "command": cmd,
"securityContext": {
"runAsUser": 0,
"privileged": True,
"capabilities": {"add": ["SYS_ADMIN"]},
},
"volumeMounts": volume_mounts,
"lifecycle": {
"preStop": {
"exec": {"command": ["umount", "-l", "/b2drop"]}
},
},
}
)
if b2drop_remember:
await self._update_secret({"b2drop-user": b2drop_user,
"b2drop-pwd": b2drop_pwd})
else:
await self._update_secret({"b2drop-user": "", "b2drop-pwd": ""})
def options_from_form(self, formdata):
data = super(B2DropSpawner, self)._options_from_form(formdata)
data.update({'b2drop-user': formdata.get('b2drop-user', [None])[0],
'b2drop-remember': formdata.get('b2drop-remember', [None])[0],
'b2drop-pwd': formdata.get('b2drop-pwd', [None])[0]})
return data
c.JupyterHub.spawner_class = B2DropSpawner
c.B2DropSpawner.http_timeout = 60
c.B2DropSpawner.args = ["--FileCheckpoints.checkpoint_dir='/home/jovyan/.notebookCheckpoints'"]
c.B2DropSpawner.profile_form_template = """
<style>
/*
.profile divs holds two div tags: one for a radio button, and one
for the profile's content.
*/
#kubespawner-profiles-list .profile {
display: flex;
flex-direction: row;
font-weight: normal;
border-bottom: 1px solid #ccc;
padding-bottom: 12px;
}
#kubespawner-profiles-list .profile .radio {
padding: 12px;
}
/* .option divs holds a label and a select tag */
#kubespawner-profiles-list .profile .option {
display: flex;
flex-direction: row;
align-items: center;
padding-bottom: 12px;
}
#kubespawner-profiles-list .profile .option label {
font-weight: normal;
margin-right: 8px;
min-width: 96px;
}
</style>
<div class='form-group' id='kubespawner-profiles-list'>
{%- for profile in profile_list %}
{#- Wrap everything in a <label> so clicking anywhere selects the option #}
<label for='profile-item-{{ profile.slug }}' class='profile'>
<div class='radio'>
<input type='radio' name='profile' id='profile-item-{{ profile.slug }}'
value='{{ profile.slug }}' {% if profile.default %}checked{% endif %} />
</div>
<div>
<h3>{{ profile.display_name }}</h3>
{%- if profile.description %}
<p>{{ profile.description }}</p>
{%- endif %}
{%- if profile.profile_options %}
<div>
{%- for k, option in profile.profile_options.items() %}
<div class='option'>
<label for='profile-option-{{profile.slug}}-{{k}}'>{{option.display_name}}</label>
<select name="profile-option-{{profile.slug}}-{{k}}" class="form-control">
{%- for k, choice in option['choices'].items() %}
<option value="{{ k }}" {% if choice.default %}selected{%endif %}>{{ choice.display_name }}</option>
{%- endfor %}
</select>
</div>
{%- endfor %}
</div>
{%- endif %}
</div>
</label>
{%- endfor %}
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
<a class="collapsed" role="button" data-bs-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="false"
aria-controls="collapseOne">
B2DROP connection
</a>
{%if b2drop_ready %}<span class="label label-success">Already configured!</span>{% endif %}
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne">
<div class="panel-body">
<div class='form-group'>
<label for="b2drop-user" class="form-label">B2DROP app Username</label>
<input type="text" class="form-control" name="b2drop-user" id="b2drop-user" aria-describedby="b2drop-user-help" value="{{ b2drop_user }}">
<div id="b2drop-user-help" class="form-text">Create new app password at <a href="https://b2drop.eudat.eu/settings/user/security">
B2DROP security configuration</a></div>
</div>
<div class='form-group'>
<label for="b2drop-pwd" class="form-label">B2DROP app Password</label>
<input type="password" class="form-control" name="b2drop-pwd" id="b2drop-pwd" value="{{ b2drop_pwd }}">
</div>
<div class='form-group'>
<input type="checkbox" id="b2drop-remember" name="b2drop-remember" {%if b2drop_ready %}checked{% endif %}>
<label class="form-check-label" for="from-check-input">Remember B2DROP credentials</label>
</div>
</div>
</div>
</div>
</div>
"""
{% endraw %}
templatePaths:
- /egi-notebooks-hub/templates
extraFiles:
login.html:
mountPath: /egi-notebooks-hub/templates/login.html
stringData: |-
{%- raw %}
{% extends "egi-login.html" %}
{% block main_intro %}
<h1><img alt="Notebooks Logo" src="{{ static_url('images/egi-icon-notebooks.svg') }}"
height="100">Notebooks</h1>
<p>
Notebooks is an environment based on <a href="http://jupyter.org/">Jupyter</a> and
the <a href="https://www.egi.eu/services/cloud-compute/">EGI cloud service</a> that
offers a browser-based, scalable tool for interactive data analysis. The Notebooks
environment provides users with notebooks where they can combine text, mathematics,
computations and rich media output.
</p>
<p>
Access requires a valid <a href="https://docs.egi.eu/users/check-in/signup">EGI account</a>
and <a href="https://docs.egi.eu/users/dev-env/notebooks/#notebooks-for-researchers">
enrolling to one of the supported VOs</a>.
</p>
<p>
Default environment provides 4 vCPU cores, 6 GB RAM and 10GB of personal storage space per user.
</p>
{% endblock main_intro %}
{% endraw %}
../common/extra
\ No newline at end of file
---
fip:
hosts:
147.251.245.198:
master:
hosts:
192.168.0.77:
# must be IPv4 address or hostname
kube_server: 192.168.0.77
ingress:
hosts:
192.168.0.118:
nfs:
hosts:
192.168.0.219:
worker:
hosts:
192.168.0.119:
gpu:
hosts:
# using public IP of kube_server for ansible delegate_to
kube_server:
hosts:
192.168.0.77:
ansible_host: 192.168.0.77
---
allnodes:
children:
master:
ingress:
nfs:
worker:
gpu:
all:
vars:
ansible_become: true
ansible_user: egi
ansible_ssh_common_args: >-
-o ProxyCommand="ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -W %h:%p -q egi@{{ groups["fip"][0] }}"
-o StrictHostKeyChecking=no
-o UserKnownHostsFile=/dev/null
site_name: egi-devel
vault_mount_point: secrets/users/e1662e20-e34b-468c-b0ce-d899bc878364@egi.eu/egi-devel
backup_repository: s3:s3.cl2.du.cesnet.cz/notebooks-devel-g2
notebooks_hostname: notebooks-dev.egi.zcu.cz
grafana_hostname: grafana.notebooks-dev.egi.zcu.cz
nexus_hostname: nexus.notebooks-dev.egi.zcu.cz
registry_binder_hostname: registry.binder-dev.egi.zcu.cz
registry_notebooks_hostname: registry.notebooks-dev.egi.zcu.cz
../../common/playbooks/accounting.yaml
\ No newline at end of file
../../common/playbooks/backup.yaml
\ No newline at end of file
../../common/playbooks/cvmfs.yaml
\ No newline at end of file
../../../common/playbooks/files/calico.yaml
\ No newline at end of file
../../../common/playbooks/files/etc
\ No newline at end of file
../../../common/playbooks/files/jupyterhub-jwt.yaml
\ No newline at end of file
../../../common/playbooks/files/usr
\ No newline at end of file
../../common/playbooks/k8s.yaml
\ No newline at end of file
../../common/playbooks/notebooks.yaml
\ No newline at end of file
../../common/playbooks/public_keys
\ No newline at end of file
../../common/playbooks/recover.yaml
\ No newline at end of file
../../common/playbooks/repository-nexus.yaml
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment