Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • develop
  • feature/arch_support
  • feature/global_refactoring
  • master
  • v1.0.0
5 results

Target

Select target project
  • exact/Rosetta
1 result
Select Git revision
  • develop
  • feature/arch_support
  • feature/global_refactoring
  • master
  • v1.0.0
5 results
Show changes
Commits on Source (5)
Showing
with 630 additions and 528 deletions
...@@ -44,3 +44,4 @@ class RosettaOIDCAuthenticationCallbackView(OIDCAuthenticationCallbackView): ...@@ -44,3 +44,4 @@ class RosettaOIDCAuthenticationCallbackView(OIDCAuthenticationCallbackView):
logger.debug('No cookie-based post login redirect found, redirecting to "%s"', self.success_url) logger.debug('No cookie-based post login redirect found, redirecting to "%s"', self.success_url)
return HttpResponseRedirect(self.success_url) return HttpResponseRedirect(self.success_url)
...@@ -1333,3 +1333,4 @@ class ImportRepositoryAPI(PrivateGETAPI): ...@@ -1333,3 +1333,4 @@ class ImportRepositoryAPI(PrivateGETAPI):
import os import os
from .models import TaskStatuses, KeyPair, Task, Storage from .models import TaskStatuses, KeyPair, Task, Storage
from .utils import os_shell, get_ssh_access_mode_credentials, sanitize_container_env_vars, booleanize from .utils import os_shell, get_ssh_access_mode_credentials, sanitize_container_env_vars, booleanize, setup_tunnel_and_proxy
from .exceptions import ErrorMessage, ConsistencyException from .exceptions import ErrorMessage, ConsistencyException
from django.conf import settings from django.conf import settings
...@@ -9,7 +9,7 @@ import logging ...@@ -9,7 +9,7 @@ import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
ROSETTA_AGENT_CHECK_SSL = booleanize(os.environ.get('ROSETTA_AGENT_CHECK_SSL', True)) ROSETTA_AGENT_CHECK_SSL = booleanize(os.environ.get('ROSETTA_AGENT_CHECK_SSL', True))
CHECK_WGET_CERT_STR = '--no-check-certificate' if not ROSETTA_AGENT_CHECK_SSL else '' CHECK_CURL_CERT_STR = '--insecure' if not ROSETTA_AGENT_CHECK_SSL else ''
class ComputingManager(object): class ComputingManager(object):
...@@ -131,8 +131,30 @@ class InternalStandaloneComputingManager(StandaloneComputingManager): ...@@ -131,8 +131,30 @@ class InternalStandaloneComputingManager(StandaloneComputingManager):
# User data volume # User data volume
#run_command += ' -v {}/user-{}:/data'.format(settings.LOCAL_USER_DATA_DIR, task.user.id) #run_command += ' -v {}/user-{}:/data'.format(settings.LOCAL_USER_DATA_DIR, task.user.id)
# Handle storages (binds)
binds = ''
storages = Storage.objects.filter(computing=self.computing)
for storage in storages:
if storage.type == 'generic_posix' and storage.bind_path:
# Expand the base path
expanded_base_path = storage.base_path
if '$USER' in expanded_base_path:
expanded_base_path = expanded_base_path.replace('$USER', task.user.username)
# Expand the bind_path
expanded_bind_path = storage.bind_path
if '$USER' in expanded_bind_path:
expanded_bind_path = expanded_bind_path.replace('$USER', task.user.username)
# Add the bind
if not binds:
binds = '-v{}:{}'.format(expanded_base_path, expanded_bind_path)
else:
binds += ' -v{}:{}'.format(expanded_base_path, expanded_bind_path)
# Host name, image entry command # Host name, image entry command
run_command += ' -h task-{} --name task-{} -d -t {}/{}:{}'.format(task.short_uuid, task.short_uuid, task.container.registry, task.container.image_name, task.container.image_tag) run_command += ' {} -h task-{} --name task-{} -d -t {}/{}:{}'.format(binds, task.short_uuid, task.short_uuid, task.container.registry, task.container.image_name, task.container.image_tag)
# Debug # Debug
logger.debug('Running new task with command="{}"'.format(run_command)) logger.debug('Running new task with command="{}"'.format(run_command))
...@@ -158,6 +180,10 @@ class InternalStandaloneComputingManager(StandaloneComputingManager): ...@@ -158,6 +180,10 @@ class InternalStandaloneComputingManager(StandaloneComputingManager):
# Save # Save
task.save() task.save()
# Setup the tunnel if using a custom protocol (otherwise it will get set up via the "connect" button)
if task.container.interface_protocol not in ['http', 'https']:
setup_tunnel_and_proxy(task)
def _stop_task(self, task): def _stop_task(self, task):
# Delete the Docker container # Delete the Docker container
...@@ -166,6 +192,10 @@ class InternalStandaloneComputingManager(StandaloneComputingManager): ...@@ -166,6 +192,10 @@ class InternalStandaloneComputingManager(StandaloneComputingManager):
out = os_shell(stop_command, capture=True) out = os_shell(stop_command, capture=True)
if out.exit_code != 0: if out.exit_code != 0:
if 'No such container' in out.stderr: if 'No such container' in out.stderr:
# No container was found
pass
elif 'requires at least 1 argument' in out.stderr:
# No container was found
pass pass
else: else:
raise Exception(out.stderr) raise Exception(out.stderr)
...@@ -263,7 +293,7 @@ class SSHStandaloneComputingManager(StandaloneComputingManager, SSHComputingMana ...@@ -263,7 +293,7 @@ class SSHStandaloneComputingManager(StandaloneComputingManager, SSHComputingMana
run_command = 'ssh -p {} -o LogLevel=ERROR -i {} -4 -o StrictHostKeyChecking=no {}@{} '.format(computing_port, computing_keys.private_key_file, computing_user, computing_host) run_command = 'ssh -p {} -o LogLevel=ERROR -i {} -4 -o StrictHostKeyChecking=no {}@{} '.format(computing_port, computing_keys.private_key_file, computing_user, computing_host)
run_command += '/bin/bash -c \'"rm -rf /tmp/{}_data && mkdir -p /tmp/{}_data/tmp && mkdir -p /tmp/{}_data/home && chmod 700 /tmp/{}_data && '.format(task.uuid, task.uuid, task.uuid, task.uuid) run_command += '/bin/bash -c \'"rm -rf /tmp/{}_data && mkdir -p /tmp/{}_data/tmp && mkdir -p /tmp/{}_data/home && chmod 700 /tmp/{}_data && '.format(task.uuid, task.uuid, task.uuid, task.uuid)
run_command += 'wget {} {}/api/v1/base/agent/?task_uuid={} -O /tmp/{}_data/agent.py &> /dev/null && export BASE_PORT=\$(python /tmp/{}_data/agent.py 2> /tmp/{}_data/task.log) && '.format(CHECK_WGET_CERT_STR, webapp_conn_string, task.uuid, task.uuid, task.uuid, task.uuid) run_command += 'curl {} {}/api/v1/base/agent/?task_uuid={} -o /tmp/{}_data/agent.py &> /dev/null && export BASE_PORT=\$(python3 /tmp/{}_data/agent.py 2> /tmp/{}_data/task.log) && '.format(CHECK_CURL_CERT_STR, webapp_conn_string, task.uuid, task.uuid, task.uuid, task.uuid)
run_command += 'export SINGULARITY_NOHTTPS=true && export SINGULARITYENV_BASE_PORT=\$BASE_PORT {} {} &&'.format(authstring, varsstring) run_command += 'export SINGULARITY_NOHTTPS=true && export SINGULARITYENV_BASE_PORT=\$BASE_PORT {} {} &&'.format(authstring, varsstring)
run_command += 'exec nohup singularity run {} --pid --writable-tmpfs --no-home --home=/home/metauser --workdir /tmp/{}_data/tmp -B/tmp/{}_data/home:/home --containall --cleanenv '.format(binds, task.uuid, task.uuid) run_command += 'exec nohup singularity run {} --pid --writable-tmpfs --no-home --home=/home/metauser --workdir /tmp/{}_data/tmp -B/tmp/{}_data/home:/home --containall --cleanenv '.format(binds, task.uuid, task.uuid)
...@@ -326,7 +356,7 @@ class SSHStandaloneComputingManager(StandaloneComputingManager, SSHComputingMana ...@@ -326,7 +356,7 @@ class SSHStandaloneComputingManager(StandaloneComputingManager, SSHComputingMana
run_command = 'ssh -p {} -o LogLevel=ERROR -i {} -4 -o StrictHostKeyChecking=no {}@{} '.format(computing_port, computing_keys.private_key_file, computing_user, computing_host) run_command = 'ssh -p {} -o LogLevel=ERROR -i {} -4 -o StrictHostKeyChecking=no {}@{} '.format(computing_port, computing_keys.private_key_file, computing_user, computing_host)
run_command += '/bin/bash -c \'"rm -rf /tmp/{}_data && mkdir /tmp/{}_data && chmod 700 /tmp/{}_data && '.format(task.uuid, task.uuid, task.uuid) run_command += '/bin/bash -c \'"rm -rf /tmp/{}_data && mkdir /tmp/{}_data && chmod 700 /tmp/{}_data && '.format(task.uuid, task.uuid, task.uuid)
run_command += 'wget {} {}/api/v1/base/agent/?task_uuid={} -O /tmp/{}_data/agent.py &> /dev/null && export TASK_PORT=\$(python /tmp/{}_data/agent.py 2> /tmp/{}_data/task.log) && '.format(CHECK_WGET_CERT_STR, webapp_conn_string, task.uuid, task.uuid, task.uuid, task.uuid) run_command += 'curl {} {}/api/v1/base/agent/?task_uuid={} -o /tmp/{}_data/agent.py &> /dev/null && export TASK_PORT=\$(python3 /tmp/{}_data/agent.py 2> /tmp/{}_data/task.log) && '.format(CHECK_CURL_CERT_STR, webapp_conn_string, task.uuid, task.uuid, task.uuid, task.uuid)
run_command += 'exec nohup {} {} run -p \$TASK_PORT:{} {} {} {} '.format(prefix, container_engine, task.container.interface_port, authstring, varsstring, binds) run_command += 'exec nohup {} {} run -p \$TASK_PORT:{} {} {} {} '.format(prefix, container_engine, task.container.interface_port, authstring, varsstring, binds)
if container_engine == 'podman': if container_engine == 'podman':
run_command += '--network=private --uts=private --userns=keep-id ' run_command += '--network=private --uts=private --userns=keep-id '
...@@ -356,6 +386,10 @@ class SSHStandaloneComputingManager(StandaloneComputingManager, SSHComputingMana ...@@ -356,6 +386,10 @@ class SSHStandaloneComputingManager(StandaloneComputingManager, SSHComputingMana
# Save # Save
task.save() task.save()
# Setup the tunnel if using a custom protocol (otherwise it will get set up via the "connect" button)
if task.container.interface_protocol not in ['http', 'https']:
setup_tunnel_and_proxy(task)
def _stop_task(self, task, **kwargs): def _stop_task(self, task, **kwargs):
...@@ -519,7 +553,7 @@ class SlurmSSHClusterComputingManager(ClusterComputingManager, SSHComputingManag ...@@ -519,7 +553,7 @@ class SlurmSSHClusterComputingManager(ClusterComputingManager, SSHComputingManag
binds += ',{}:{}'.format(expanded_base_path, expanded_bind_path) binds += ',{}:{}'.format(expanded_base_path, expanded_bind_path)
run_command = 'ssh -p {} -o LogLevel=ERROR -i {} -4 -o StrictHostKeyChecking=no {}@{} '.format(computing_port, computing_keys.private_key_file, computing_user, computing_host) run_command = 'ssh -p {} -o LogLevel=ERROR -i {} -4 -o StrictHostKeyChecking=no {}@{} '.format(computing_port, computing_keys.private_key_file, computing_user, computing_host)
run_command += '\'bash -c "echo \\"#!/bin/bash\nwget {} {}/api/v1/base/agent/?task_uuid={} -O \$HOME/agent_{}.py &> \$HOME/{}.log && export BASE_PORT=\\\\\\$(python \$HOME/agent_{}.py 2> \$HOME/{}.log) && '.format(CHECK_WGET_CERT_STR, webapp_conn_string, task.uuid, task.uuid, task.uuid, task.uuid, task.uuid) run_command += '\'bash -c "echo \\"#!/bin/bash\ncurl {} {}/api/v1/base/agent/?task_uuid={} -o \$HOME/agent_{}.py &> \$HOME/{}.log && export BASE_PORT=\\\\\\$(python3 \$HOME/agent_{}.py 2> \$HOME/{}.log) && '.format(CHECK_CURL_CERT_STR, webapp_conn_string, task.uuid, task.uuid, task.uuid, task.uuid, task.uuid)
run_command += 'export SINGULARITY_NOHTTPS=true && export SINGULARITYENV_BASE_PORT=\\\\\\$BASE_PORT {} {} && '.format(authstring, varsstring) run_command += 'export SINGULARITY_NOHTTPS=true && export SINGULARITYENV_BASE_PORT=\\\\\\$BASE_PORT {} {} && '.format(authstring, varsstring)
run_command += 'rm -rf /tmp/{}_data && mkdir -p /tmp/{}_data/tmp &>> \$HOME/{}.log && mkdir -p /tmp/{}_data/home &>> \$HOME/{}.log && chmod 700 /tmp/{}_data && '.format(task.uuid, task.uuid, task.uuid, task.uuid, task.uuid, task.uuid) run_command += 'rm -rf /tmp/{}_data && mkdir -p /tmp/{}_data/tmp &>> \$HOME/{}.log && mkdir -p /tmp/{}_data/home &>> \$HOME/{}.log && chmod 700 /tmp/{}_data && '.format(task.uuid, task.uuid, task.uuid, task.uuid, task.uuid, task.uuid)
run_command += 'exec nohup singularity run {} --pid --writable-tmpfs --no-home --home=/home/metauser --workdir /tmp/{}_data/tmp -B/tmp/{}_data/home:/home --containall --cleanenv '.format(binds, task.uuid, task.uuid) run_command += 'exec nohup singularity run {} --pid --writable-tmpfs --no-home --home=/home/metauser --workdir /tmp/{}_data/tmp -B/tmp/{}_data/home:/home --containall --cleanenv '.format(binds, task.uuid, task.uuid)
...@@ -559,6 +593,9 @@ class SlurmSSHClusterComputingManager(ClusterComputingManager, SSHComputingManag ...@@ -559,6 +593,9 @@ class SlurmSSHClusterComputingManager(ClusterComputingManager, SSHComputingManag
# Save # Save
task.save() task.save()
# Setup the tunnel if using a custom protocol (otherwise it will get set up via the "connect" button)
if task.container.interface_protocol not in ['http', 'https']:
setup_tunnel_and_proxy(task)
def _stop_task(self, task, **kwargs): def _stop_task(self, task, **kwargs):
...@@ -590,4 +627,3 @@ class SlurmSSHClusterComputingManager(ClusterComputingManager, SSHComputingManag ...@@ -590,4 +627,3 @@ class SlurmSSHClusterComputingManager(ClusterComputingManager, SSHComputingManag
else: else:
return out.stdout return out.stdout
...@@ -137,3 +137,4 @@ def private_view(wrapped_view): ...@@ -137,3 +137,4 @@ def private_view(wrapped_view):
response.set_cookie('post_login_redirect', request.build_absolute_uri()) response.set_cookie('post_login_redirect', request.build_absolute_uri())
return response return response
return private_view_wrapper return private_view_wrapper
...@@ -359,3 +359,4 @@ to provide help, news and informations on your deployment. Or you can just ignor ...@@ -359,3 +359,4 @@ to provide help, news and informations on your deployment. Or you can just ignor
base_path = '/shared/data/users/$SSH_USER', base_path = '/shared/data/users/$SSH_USER',
bind_path = '/storages/personal') bind_path = '/storages/personal')
...@@ -398,6 +398,10 @@ class Storage(models.Model): ...@@ -398,6 +398,10 @@ class Storage(models.Model):
# Include as browsable in the file manager? # Include as browsable in the file manager?
browsable = models.BooleanField('Browsable in the file manager?', default=True) browsable = models.BooleanField('Browsable in the file manager?', default=True)
def save(self, *args, **kwargs):
if self.access_mode == 'internal' and self.browsable:
raise ValueError('A storage with "internal" access mode cannot be marked as browsable since it is not yet supported by the file manager')
super(Storage, self).save(*args, **kwargs)
class Meta: class Meta:
ordering = ['name'] ordering = ['name']
...@@ -457,3 +461,4 @@ class Page(models.Model): ...@@ -457,3 +461,4 @@ class Page(models.Model):
@keyframes spin {
to {
transform: rotate(360deg);
}
}
#navigate-away-loader {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 2000;
align-items: center;
justify-content: center;
color: white;
transition: opacity 0.4s ease-in-out;
visibility: hidden;
pointer-events: none;
display: flex;
& > svg {
animation: spin 1.5s infinite linear;
opacity: 0.5;
}
}
function showNavigationLoader() {
var navigationLoader = document.querySelector("#navigate-away-loader")
navigationLoader.style.visibility = "visible"
navigationLoader.style.opacity = 1
navigationLoader.style.pointerEvents = "all"
document.querySelector("#navigate-away-loader > svg").style.animation =
"spin 1.5s infinite linear"
}
function hideNavigationLoader() {
var navigationLoader = document.querySelector("#navigate-away-loader")
navigationLoader.style.visibility = "hidden"
navigationLoader.style.opacity = 0
navigationLoader.style.pointerEvents = "none"
}
window.addEventListener("beforeunload", function (e) {
showNavigationLoader()
return true
})
window.addEventListener("pageshow", function (e) {
hideNavigationLoader()
})
...@@ -178,3 +178,4 @@ ...@@ -178,3 +178,4 @@
...@@ -87,3 +87,4 @@ ...@@ -87,3 +87,4 @@
...@@ -283,3 +283,4 @@ function toggle_visibility(id) { ...@@ -283,3 +283,4 @@ function toggle_visibility(id) {
...@@ -49,3 +49,4 @@ ...@@ -49,3 +49,4 @@
</html> </html>