Skip to content
Snippets Groups Projects
Commit f94110a5 authored by Bjarke Madsen's avatar Bjarke Madsen
Browse files

Only allow a single provision process to run

parent 5860a698
No related branches found
No related tags found
No related merge requests found
......@@ -30,6 +30,8 @@ If the value is a list, dashboard titles within the list should be excluded.
import json
import jsonschema
STATE_PATH = '/tmp/briandashboardmanager-state.json'
DEFAULT_ORGANIZATIONS = [
{
"name": "GÉANT Staff",
......
......@@ -4,8 +4,10 @@ entire provisioning lifecycle.
"""
import logging
import time
import json
import datetime
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
from brian_dashboard_manager.config import DEFAULT_ORGANIZATIONS
from brian_dashboard_manager.config import DEFAULT_ORGANIZATIONS, STATE_PATH
from brian_dashboard_manager.grafana.utils.request import \
AdminRequest, \
TokenRequest
......@@ -94,6 +96,23 @@ def provision_aggregate(token_request, agg_type, aggregate_folder,
create_dashboard(token_request, rendered, aggregate_folder['id'])
def provision_maybe(config):
with open(STATE_PATH, 'r+') as f:
def write_timestamp(timestamp, provisioning):
f.seek(0)
f.write(json.dumps(
{'timestamp': timestamp, 'provisioning': provisioning}))
f.truncate()
try:
now = datetime.datetime.now()
write_timestamp(now.timestamp(), True)
provision(config)
finally:
now = datetime.datetime.now()
write_timestamp(now.timestamp(), False)
def provision(config):
request = AdminRequest(**config)
......
import json
import datetime
from flask import jsonify, Response
from concurrent.futures import ThreadPoolExecutor
from json.decoder import JSONDecodeError
from flask import Blueprint, current_app
from brian_dashboard_manager.routes import common
from brian_dashboard_manager.grafana.provision import provision
from brian_dashboard_manager.grafana.provision import provision_maybe
from brian_dashboard_manager import CONFIG_KEY
from brian_dashboard_manager.config import STATE_PATH
routes = Blueprint("update", __name__)
......@@ -22,6 +28,25 @@ def after_request(resp):
return common.after_request(resp)
def should_provision():
try:
with open(STATE_PATH, 'r+') as f:
try:
state = json.load(f)
except JSONDecodeError:
state = {}
provisioning = state.get('provisioning', False)
timestamp = datetime.datetime.fromtimestamp(
state.get('timestamp', 1))
can_provision = not provisioning
return can_provision, timestamp
except FileNotFoundError:
with open(STATE_PATH, 'w') as f:
return True, None
@routes.route('/', methods=['GET'])
def update():
"""
......@@ -37,6 +62,11 @@ def update():
:return: json
"""
executor = ThreadPoolExecutor(max_workers=1)
executor.submit(provision, current_app.config[CONFIG_KEY])
return {'data': {'message': 'Provisioning dashboards!'}}
should, timestamp = should_provision()
if should:
executor = ThreadPoolExecutor(max_workers=1)
executor.submit(provision_maybe, current_app.config[CONFIG_KEY])
return jsonify({'data': {'message': 'Provisioning dashboards!'}})
else:
message = f'Provision already in progress since {timestamp}'
return Response(message, status=503)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment