From 6bc1ef94dc022defce448fb2c5e4a6a46bedbc6a Mon Sep 17 00:00:00 2001
From: Patrick Jentsch
Date: Thu, 15 Aug 2019 12:02:50 +0200
Subject: [PATCH 1/4] Add api blueprint.
---
app/__init__.py | 3 ++
app/api/__init__.py | 5 ++++
app/api/views.py | 67 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 75 insertions(+)
create mode 100644 app/api/__init__.py
create mode 100644 app/api/views.py
diff --git a/app/__init__.py b/app/__init__.py
index 4432a4e8..3afd43e2 100644
--- a/app/__init__.py
+++ b/app/__init__.py
@@ -24,6 +24,9 @@ def create_app(config_name):
scheduler.init_app(app)
scheduler.start()
+ from .api import api as api_blueprint
+ app.register_blueprint(api_blueprint, url_prefix='/api')
+
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint, url_prefix='/auth')
diff --git a/app/api/__init__.py b/app/api/__init__.py
new file mode 100644
index 00000000..27a63156
--- /dev/null
+++ b/app/api/__init__.py
@@ -0,0 +1,5 @@
+from flask import Blueprint
+
+api = Blueprint('api', __name__)
+
+from . import views
diff --git a/app/api/views.py b/app/api/views.py
new file mode 100644
index 00000000..ce3bc875
--- /dev/null
+++ b/app/api/views.py
@@ -0,0 +1,67 @@
+from flask import jsonify
+from flask_login import current_user, login_required
+from . import api
+
+
+@api.route('/v1.0/corpora')
+@login_required
+def corpora():
+ corpora = []
+ for corpus in current_user.corpora.all():
+ corpora.append({'id': corpus.id,
+ 'creation_date': corpus.creation_date.timestamp(),
+ 'description': corpus.description,
+ 'title': corpus.title})
+ return jsonify(corpora)
+
+
+@api.route('/v1.0/corpora/')
+@login_required
+def corpus(corpus_id):
+ corpus = current_user.corpora.filter_by(id=corpus_id).first()
+ if not corpus:
+ ''' This should return 404 '''
+ return jsonify(None)
+ return jsonify({'id': corpus.id,
+ 'creation_date': corpus.creation_date,
+ 'description': corpus.description,
+ 'title': corpus.title})
+
+
+@api.route('/v1.0/jobs')
+@login_required
+def jobs():
+ jobs = []
+ for job in current_user.jobs.all():
+ jobs.append({'id': job.id,
+ 'creation_date': job.creation_date.timestamp(),
+ 'description': job.description,
+ 'end_date': job.end_date.timestamp() if job.end_date else None,
+ 'mem_mb': job.mem_mb,
+ 'n_cores': job.n_cores,
+ 'service': job.service,
+ 'service_args': job.service_args,
+ 'service_version': job.service_version,
+ 'status': job.status,
+ 'title': job.title})
+ return jsonify(jobs)
+
+
+@api.route('/v1.0/jobs/')
+@login_required
+def job(job_id):
+ job = current_user.jobs.filter_by(id=job_id).first()
+ if not job:
+ ''' This should return 404 '''
+ return jsonify(None)
+ return jsonify({'id': job.id,
+ 'creation_date': job.creation_date.timestamp(),
+ 'description': job.description,
+ 'end_date': job.end_date.timestamp() if job.end_date else None,
+ 'mem_mb': job.mem_mb,
+ 'n_cores': job.n_cores,
+ 'service': job.service,
+ 'service_args': job.service_args,
+ 'service_version': job.service_version,
+ 'status': job.status,
+ 'title': job.title})
From 22f47e321387642f530248049c9f8a8777d6e880 Mon Sep 17 00:00:00 2001
From: Patrick Jentsch
Date: Thu, 15 Aug 2019 12:03:16 +0200
Subject: [PATCH 2/4] Add information to README.
---
README.md | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/README.md b/README.md
index e16f6d5a..390f4081 100644
--- a/README.md
+++ b/README.md
@@ -4,3 +4,35 @@
- Docker: https://www.docker.com/
- Python 3.5+
+
+## Setup
+
+In order to run jobs, Opaque needs access to a Docker swarm manager. Currently it's not possible to specify a dedicated Docker host, instead Opaque expects the executing system to to be a swarm manager.
+
+1. Get the source code and navigate into the code directory
+```
+git clone https://gitlab.ub.uni-bielefeld.de/sfb1288inf/opaque.git
+cd opaque
+```
+
+2. Create Docker swarm
+
+2.1. Local
+```
+# Set the variable values in setup_local_swarm.sh (nano setup_local_swarm.sh)
+./setup_local_swarm.sh
+```
+
+2.2. Distributed
+
+2.2.1. Initialize swarm on manager machine
+```
+docker swarm init
+```
+
+3. Create Python virtual environment, activate it and install the required python packages.
+```
+python3 -m venv venv
+source venv/bin/activate
+pip install -r requirements.txt
+```
From 4ffb10fd11624f11541fba9d6ff7be3bf381bb01 Mon Sep 17 00:00:00 2001
From: Patrick Jentsch
Date: Thu, 15 Aug 2019 12:09:00 +0200
Subject: [PATCH 3/4] Return 404 if requested ressource does not exist.
---
app/api/views.py | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/app/api/views.py b/app/api/views.py
index ce3bc875..0555155b 100644
--- a/app/api/views.py
+++ b/app/api/views.py
@@ -1,4 +1,4 @@
-from flask import jsonify
+from flask import abort, jsonify
from flask_login import current_user, login_required
from . import api
@@ -20,8 +20,7 @@ def corpora():
def corpus(corpus_id):
corpus = current_user.corpora.filter_by(id=corpus_id).first()
if not corpus:
- ''' This should return 404 '''
- return jsonify(None)
+ return abort(404)
return jsonify({'id': corpus.id,
'creation_date': corpus.creation_date,
'description': corpus.description,
@@ -36,7 +35,8 @@ def jobs():
jobs.append({'id': job.id,
'creation_date': job.creation_date.timestamp(),
'description': job.description,
- 'end_date': job.end_date.timestamp() if job.end_date else None,
+ 'end_date': (job.end_date.timestamp() if job.end_date else
+ None),
'mem_mb': job.mem_mb,
'n_cores': job.n_cores,
'service': job.service,
@@ -52,12 +52,12 @@ def jobs():
def job(job_id):
job = current_user.jobs.filter_by(id=job_id).first()
if not job:
- ''' This should return 404 '''
- return jsonify(None)
+ return abort(404)
return jsonify({'id': job.id,
'creation_date': job.creation_date.timestamp(),
'description': job.description,
- 'end_date': job.end_date.timestamp() if job.end_date else None,
+ 'end_date': (job.end_date.timestamp() if job.end_date else
+ None),
'mem_mb': job.mem_mb,
'n_cores': job.n_cores,
'service': job.service,
From 99614a56a9315d049a9992996625daa8d40bf485 Mon Sep 17 00:00:00 2001
From: Patrick Jentsch
Date: Thu, 15 Aug 2019 13:33:15 +0200
Subject: [PATCH 4/4] Add switch for admins to get all jobs (of all users)
---
app/api/views.py | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/app/api/views.py b/app/api/views.py
index 0555155b..eb86d105 100644
--- a/app/api/views.py
+++ b/app/api/views.py
@@ -1,6 +1,7 @@
-from flask import abort, jsonify
+from flask import abort, jsonify, request
from flask_login import current_user, login_required
from . import api
+from ..models import Job
@api.route('/v1.0/corpora')
@@ -31,7 +32,15 @@ def corpus(corpus_id):
@login_required
def jobs():
jobs = []
- for job in current_user.jobs.all():
+ all = request.args.get('all')
+ if all and all.lower() == 'true':
+ if current_user.is_administrator():
+ jobs_query = Job.query
+ else:
+ return abort(403)
+ else:
+ jobs_query = current_user.jobs
+ for job in jobs_query.all():
jobs.append({'id': job.id,
'creation_date': job.creation_date.timestamp(),
'description': job.description,