Module: check_mk
Branch: master
Commit: ae49c4c2a26fa392ae2fdeca78db926694b84bf4
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=ae49c4c2a26fa3…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Wed Sep 2 13:51:34 2015 +0200
In previous versions it might occur that users experience exceptions about non
parsable user_dashboards.mk files when editing dashboards. This was caused by
non existant file locking during editing of dashboards.
Conflicts:
ChangeLog
web/htdocs/visuals.py
---
.werks/2551 | 12 ++++++++++++
ChangeLog | 1 +
web/htdocs/config.py | 3 ++-
web/htdocs/dashboard.py | 18 +++++++++---------
web/htdocs/visuals.py | 10 +++++++---
5 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/.werks/2551 b/.werks/2551
new file mode 100644
index 0000000..b4cccec
--- /dev/null
+++ b/.werks/2551
@@ -0,0 +1,12 @@
+Title: Fixed locking issues when editing dashboards
+Level: 1
+Component: multisite
+Class: fix
+Compatible: compat
+State: unknown
+Version: 1.2.7i3
+Date: 1441194578
+
+In previous versions it might occur that users experience exceptions about non
+parsable user_dashboards.mk files when editing dashboards. This was caused by
+non existant file locking during editing of dashboards.
diff --git a/ChangeLog b/ChangeLog
index 55a4275..0f9c8d5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -184,6 +184,7 @@
* 2531 FIX: Fixed graph hover for services containing backslashes...
* 2532 FIX: Fixed undefined variable exception in prediction in rare cases...
* 1289 FIX: Fixed missing table headers in hostgroup view
+ * 2551 FIX: Fixed locking issues when editing dashboards...
WATO:
* 2365 Removed old deprecated notification global options for plain emails...
diff --git a/web/htdocs/config.py b/web/htdocs/config.py
index 0915a9b..88b103b 100644
--- a/web/htdocs/config.py
+++ b/web/htdocs/config.py
@@ -432,7 +432,8 @@ def save_user_file(name, content, unlock=False, user=None):
make_nagios_directory(dirname)
path = dirname + "/" + name + ".mk"
try:
- write_settings_file(path, content)
+ write_settings_file(path+".new", content)
+ os.rename(path+".new", path)
if unlock:
release_lock(path)
diff --git a/web/htdocs/dashboard.py b/web/htdocs/dashboard.py
index c42dcdd..9eda7b4 100644
--- a/web/htdocs/dashboard.py
+++ b/web/htdocs/dashboard.py
@@ -87,10 +87,10 @@ def load_plugins():
# Make sure that custom views also have permissions
config.declare_dynamic_permissions(lambda:
visuals.declare_custom_permissions('dashboards'))
-def load_dashboards():
+def load_dashboards(lock=False):
global dashboards, available_dashboards
transform_builtin_dashboards()
- dashboards = visuals.load('dashboards', builtin_dashboards)
+ dashboards = visuals.load('dashboards', builtin_dashboards, lock=lock)
transform_dashboards(dashboards)
available_dashboards = visuals.available('dashboards', dashboards)
@@ -695,7 +695,7 @@ def ajax_dashlet():
# '----------------------------------------------------------------------'
def page_edit_dashboards():
- load_dashboards()
+ load_dashboards(lock=html.is_transaction())
visuals.page_list('dashboards', _("Edit Dashboards"), dashboards)
#.
@@ -729,7 +729,7 @@ def page_create_dashboard():
global vs_dashboard
def page_edit_dashboard():
- load_dashboards()
+ load_dashboards(lock=html.is_transaction())
# This is not defined here in the function in order to be l10n'able
global vs_dashboard
@@ -826,7 +826,7 @@ def choose_view(name):
view_name = vs_view.from_html_vars('view')
vs_view.validate_value(view_name, 'view')
- load_dashboards()
+ load_dashboards(lock=True)
dashboard = available_dashboards[name]
# Add the dashlet!
@@ -878,7 +878,7 @@ def page_edit_dashlet():
if ident == None and not ty:
raise MKGeneralException(_('The ID of the dashlet is missing.'))
- load_dashboards()
+ load_dashboards(lock=html.is_transaction())
if board not in available_dashboards:
raise MKGeneralException(_('The requested dashboard does not exist.'))
@@ -1054,7 +1054,7 @@ def page_delete_dashlet():
except ValueError:
raise MKGeneralException(_('Invalid dashlet id'))
- load_dashboards()
+ load_dashboards(lock=True)
if board not in available_dashboards:
raise MKGeneralException(_('The requested dashboard does not exist.'))
@@ -1113,7 +1113,7 @@ def check_ajax_update():
ident = int(html.var('id'))
- load_dashboards()
+ load_dashboards(lock=True)
if board not in available_dashboards:
raise MKGeneralException(_('The requested dashboard does not exist.'))
@@ -1175,7 +1175,7 @@ def popup_add_dashlet(dashboard_name, dashlet_type, context,
params):
# Exceptions do not work here.
return
- load_dashboards()
+ load_dashboards(lock=True)
if dashboard_name not in available_dashboards:
return
diff --git a/web/htdocs/visuals.py b/web/htdocs/visuals.py
index f6bc014..e497645 100644
--- a/web/htdocs/visuals.py
+++ b/web/htdocs/visuals.py
@@ -104,10 +104,11 @@ def save(what, visuals, user_id = None):
for (owner_id, name), visual in visuals.items():
if user_id == owner_id:
uservisuals[name] = visual
- config.save_user_file('user_' + what, uservisuals, user = user_id)
+ config.save_user_file('user_' + what, uservisuals, user = user_id,
unlock=True)
-
-def load(what, builtin_visuals, skip_func = None):
+# FIXME: Currently all user visual files of this type are locked. We could optimize
+# this not to lock all files but only lock the files the user is about to modify.
+def load(what, builtin_visuals, skip_func = None, lock=False):
visuals = {}
# first load builtins. Set username to ''
@@ -141,6 +142,9 @@ def load(what, builtin_visuals, skip_func = None):
if not os.path.exists(path):
continue
+ if lock:
+ aquire_lock(path)
+
user_visuals = eval(file(path).read())
for name, visual in user_visuals.items():
visual["owner"] = user