diff --git a/README.md b/README.md index da97ed2fb6c99c4e4a319005674ec012c34f5e34..3ccd9f0f83aed8f57777fa3e616e19d09709287e 100755 --- a/README.md +++ b/README.md @@ -43,30 +43,40 @@ Clean ### Configuration -Example Webapp configuraion: +Webapp service configuraion parameters and their defaults: - - SAFEMODE=False - - DJANGO_DEV_SERVER=True - - DJANGO_DEBUG=True + - SAFEMODE=false + - DJANGO_DEV_SERVER=true + - DJANGO_DEBUG=true - DJANGO_LOG_LEVEL=ERROR - ROSETTA_LOG_LEVEL=ERROR - - ROSETTA_TUNNEL_HOST=localhost # Not http or https - - ROSETTA_WEBAPP_HOST= + - ROSETTA_HOST=localhost + - ROSETTA_TUNNEL_HOST=localhost + - ROSETTA_WEBAPP_HOST="" - ROSETTA_WEBAPP_PORT=8080 - - LOCAL_DOCKER_REGISTRY_HOST= - - LOCAL_DOCKER_REGISTRY_PORT=5000 + - ROSETTA_REGISTRY_HOST=proxy + - ROSETTA_REGISTRY_PORT=5000 - DJANGO_EMAIL_SERVICE=Sendgrid - - DJANGO_EMAIL_APIKEY= + - DJANGO_EMAIL_APIKEY="" - DJANGO_EMAIL_FROM="Rosetta <notifications@rosetta.local>" - - DJANGO_PUBLIC_HTTP_HOST=http://localhost # Public facing, with http or https + - INVITATION_CODE="" - OIDC_RP_CLIENT_ID="" - OIDC_RP_CLIENT_SECRET="" - OIDC_OP_AUTHORIZATION_ENDPOINT="" - OIDC_OP_TOKEN_ENDPOINT="" - OIDC_OP_JWKS_ENDPOINT="" - - DISABLE_LOCAL_AUTH=False - -In Rosetta, only power users can: + - DISABLE_LOCAL_AUTH=false + +Notes: + + - `ROSETTA_TUNNEL_HOST` must not include http:// or https:// + - `ROSETTA_REGISTRY_HOST` should be set to the same value as `ROSETTA_HOST` for production scenarios, in order to be secured unders SSL. The `standaloneworker` is configured to treat the following hosts (and ports) as unsecure registies, where it can connect without a valid certificate: `proxy:5000`,`dregistry:5000` and `rosetta.platform:5000`. + - `ROSETTA_WEBAPP_HOST` is used for let the agent know where to connect, and it is differentiated from `ROSETTA_HOST` as it can be on an internal Docker network. It is indeed defaulted to the `webapp` container IP address. + + + +### User types +In Rosetta there are two user types: standard users and power users. Their type is set in their user profile, and only power users can: - set custom task passwords - choose task access methods other than the default one (bypassing HTTP proxy + auth) diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index a72375381ef17c579800d994dd882651afe87567..5d7f06730fbb637066127789ee514f8275fd93c6 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -60,8 +60,8 @@ services: - ROSETTA_LOG_LEVEL=DEBUG #- ROSETTA_WEBAPP_HOST=localhost # Internal, for the agent #- ROSETTA_WEBAPP_PORT=8080 # Internal, for the agent - #- LOCAL_DOCKER_REGISTRY_HOST= - #- LOCAL_DOCKER_REGISTRY_PORT=5000 + #- ROSETTA_REGISTRY_HOST= + #- ROSETTA_REGISTRY_PORT=5000 #- DJANGO_EMAIL_APIKEY="" #- DJANGO_EMAIL_FROM="Rosetta Platform <notifications@rosetta.platform>" #- DJANGO_SECRET_KEY="" diff --git a/services/standaloneworker/registries.conf b/services/standaloneworker/registries.conf index e32f8d0e317231e5404308840507100e6a7a6375..fb97bbba383dfdd08172e801781b858adc8b69af 100644 --- a/services/standaloneworker/registries.conf +++ b/services/standaloneworker/registries.conf @@ -85,6 +85,10 @@ short-name-mode="enforcing" location = "dregistry:5000" insecure = true +[[registry]] +location = "proxy:5000" +insecure = true + [[registry]] location = "rosetta.platform:5000" insecure = true diff --git a/services/webapp/code/rosetta/core_app/computing_managers.py b/services/webapp/code/rosetta/core_app/computing_managers.py index 4889817483fe89d874ae35c0c683a5bc132a4d71..ff6dfcbb169e480fb8524cc6cc93b1d72b33e400 100644 --- a/services/webapp/code/rosetta/core_app/computing_managers.py +++ b/services/webapp/code/rosetta/core_app/computing_managers.py @@ -71,6 +71,9 @@ class ComputingManager(object): # Call actual get task log logic return self._get_task_log(task, **kwargs) + + def is_configured_for(self, user): + return True class StandaloneComputingManager(ComputingManager): @@ -82,8 +85,14 @@ class ClusterComputingManager(ComputingManager): class SSHComputingManager(ComputingManager): - # SSH-f + keys utils here - pass + + def is_configured_for(self, user): + try: + get_ssh_access_mode_credentials(self.computing, user) + except: + return False + else: + return True @@ -376,7 +385,7 @@ class SSHStandaloneComputingManager(StandaloneComputingManager, SSHComputingMana stop_command = 'ssh -o LogLevel=ERROR -i {} -4 -o StrictHostKeyChecking=no {}@{} \'/bin/bash -c "{}"\''.format(computing_keys.private_key_file, computing_user, computing_host, internal_stop_command) out = os_shell(stop_command, capture=True) if out.exit_code != 0: - if ('No such process' in out.stderr) or ('No such container' in out.stderr): + if ('No such process' in out.stderr) or ('No such container' in out.stderr) or ('no container' in out.stderr): pass else: raise Exception(out.stderr) diff --git a/services/webapp/code/rosetta/core_app/templates/components/computing.html b/services/webapp/code/rosetta/core_app/templates/components/computing.html index 6c55b09e3c091d824a8d30f8cab75ded93c76545..8e709da9fc38ab48d1041ea8760087b85263e8ee 100644 --- a/services/webapp/code/rosetta/core_app/templates/components/computing.html +++ b/services/webapp/code/rosetta/core_app/templates/components/computing.html @@ -76,14 +76,36 @@ {% else %} - <div style="width:300px; float:left; border: #e0e0e0 solid 1px; margin:10px; background:#f8f8f8; margin-bottom:15px"> + + {% load computing_helpers %} + {% is_computing_configured computing request.user as computing_configured %} + + <!-- Insert an "if false" here to let the computign show up even when creating the task but to not allow to be chosen (greyed out button) --> + {% if container and not computing_configured %} + {% else%} + + <div style="width:300px; float:left; border: #e0e0e0 solid 1px; margin:10px; background:#f8f8f8; margin-bottom:15px;"> <!-- <div style="background:{{computing.color}}; height:24px"></div> --> - + <div style="padding:10px; margin-top:5px; text-align:center; border-bottom: #e0e0e0 solid 1px; "> <a href="/computing/?uuid={{ computing.uuid }}&details=True">{{ computing.name }}</a> </div> + + + {% if not computing_configured %} + <div style="width:298px; float:left; margin:0; margin-bottom:5px; padding:2px; background: gary; color:black; text-align:center; border-bottom: #e0e0e0 solid 1px;"> + <i class="fa fa-info-circle"></i> Not configured <!-- style="color:#337ab7" --> + </div> + {% endif %} + + + {% if not computing_configured %} + <!-- <div style="padding:10px; -webkit-filter: blur(5px); -moz-filter: blur(5px); -o-filter: blur(5px); -ms-filter: blur(5px); filter: blur(5px);"> --> + <div style="padding:10px;"> + {% else %} <div style="padding:10px;"> + {% endif %} {% if computing.description %} <div class="description-box" title="{{ computing.description }}"> @@ -116,6 +138,7 @@ {% if 'singularity' in computing.container_engines %}<img src="/static/img/singularity-logo.svg" style="height:18px; width:18px; margin-bottom:2px" />{% endif %}--> {% if container %} <div style="margin:0px; margin-top:2px; text-align:center; padding:5px"> + {% if computing_configured %} <form action="/new_task/" method="POST"> {% csrf_token %} <input type="hidden" name="step" value="{{ data.next_step }}" /> @@ -124,12 +147,16 @@ <input type="hidden" name="task_computing_uuid" value="{{computing.uuid}}"> <input type="submit" value="Choose" class="btn btn-connect"> </form> + {% else %} + <input type="submit" value="Choose" class="btn btn-connect" disabled> + {% endif %} </div> {% endif %} </div> </div> + {% endif %} diff --git a/services/webapp/code/rosetta/core_app/templates/new_task.html b/services/webapp/code/rosetta/core_app/templates/new_task.html index 16aed722728a7ceb239121d41a38566a7445950d..78d8cffb5ffb500db7a06ab4b19b7aed9e9f3b87 100644 --- a/services/webapp/code/rosetta/core_app/templates/new_task.html +++ b/services/webapp/code/rosetta/core_app/templates/new_task.html @@ -132,7 +132,7 @@ <tr> <td><b>Container engine</b></td><td> <select name="container_engine" > - <option value="" selected>Default</option> + <option value="" selected>Default ({{data.task_computing.container_engines.0}})</option> {% for container_engine in data.task_computing.container_engines %} <option value="{{container_engine}}">{{container_engine}}</option> {% endfor %} diff --git a/services/webapp/code/rosetta/core_app/templatetags/__init__.py b/services/webapp/code/rosetta/core_app/templatetags/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/services/webapp/code/rosetta/core_app/templatetags/computing_helpers.py b/services/webapp/code/rosetta/core_app/templatetags/computing_helpers.py new file mode 100644 index 0000000000000000000000000000000000000000..7e85d6915b034eaf899ad35c954b818a01b40390 --- /dev/null +++ b/services/webapp/code/rosetta/core_app/templatetags/computing_helpers.py @@ -0,0 +1,10 @@ +from django import template + +register = template.Library() + +@register.simple_tag +def is_computing_configured(computing, user): + return computing.manager.is_configured_for(user) + + +# {% is_computing_configured computing user %} diff --git a/services/webapp/code/rosetta/core_app/utils.py b/services/webapp/code/rosetta/core_app/utils.py index 16e3502b1d1bc06b185940b06a909015a1dc6a21..e296c8b495d03a08afb6ac79ae240ec56fd63aff 100644 --- a/services/webapp/code/rosetta/core_app/utils.py +++ b/services/webapp/code/rosetta/core_app/utils.py @@ -509,11 +509,11 @@ def get_webapp_conn_string(): webapp_conn_string = 'http://{}:{}'.format(webapp_host, webapp_port) return webapp_conn_string -def get_local_docker_registry_conn_string(): - local_docker_registry_host = os.environ.get('LOCAL_DOCKER_REGISTRY_HOST', 'dregistry') - local_docker_registry_port = os.environ.get('LOCAL_DOCKER_REGISTRY_PORT', '5000') - local_docker_registry_conn_string = '{}:{}'.format(local_docker_registry_host, local_docker_registry_port) - return local_docker_registry_conn_string +def get_platform_registry(): + platform_registry_host = os.environ.get('PLATFORM_REGISTRY_HOST', 'proxy') + platform_registry_port = os.environ.get('PLATFORM_REGISTRY_PORT', '5000') + platform_registry_conn_string = '{}:{}'.format(platform_registry_host, platform_registry_port) + return platform_registry_conn_string def get_task_tunnel_host(): tunnel_host = os.environ.get('TASK_TUNNEL_HOST', 'localhost') @@ -784,7 +784,7 @@ def get_or_create_container_from_repository(user, repository_url, repository_tag raise Exception('Cannot build') # Set image registry, name and tag. Use "strip()" as sometimes the newline chars might jump in. - registry = os.environ.get('REGISTRY_HOST','proxy:5000').strip() + registry = get_platform_registry() image_name = repository_name.lower().strip() image_tag = repo2docker_image_name[-7:] # The last part of the image name generated by repo2docker is the git short hash