[PATCH] [Ginger] Bug fix #13: Config backup needs progress indicator

3 views
Skip to first unread message

bia...@linux.vnet.ibm.com

unread,
Feb 14, 2017, 7:52:25 AM2/14/17
to Ginger Devel, Daniel Barboza
From: Bianca Carvalho <bia...@linux.vnet.ibm.com>

Changed UI and backend to avoid more than one backup restore to run
at the same time (inclued a warning message to let the user knows
about that as well). Also changed UI elements to make sure the user
can see what is happening during the backup/restore.

Signed-off-by: Bianca Carvalho <bia...@linux.vnet.ibm.com>
---
i18n.py | 1 +
model/backup.py | 10 +-
ui/css/ginger.css | 13 +-
ui/css/src/modules/_administration.scss | 13 +-
ui/js/host-admin.js | 225 ++++++++++++++++++++++++--------
ui/js/util.js | 18 ++-
ui/pages/i18n.json.tmpl | 4 -
ui/pages/tabs/host-admin.html.tmpl | 1 +
8 files changed, 219 insertions(+), 66 deletions(-)

diff --git a/i18n.py b/i18n.py
index 2dc365f..5984043 100644
--- a/i18n.py
+++ b/i18n.py
@@ -176,6 +176,7 @@ messages = {
"GINHBK0011E": _('Archive creation task failed. "%(err)s".'),
"GINHBK0012E": _('Unable to include default backup dir (%(dir)s) to a backup file'),
"GINHBK0013E": _('Archive restore task failed. "%(err)s".'),
+ "GINHBK0014E": _('You will be unable to restore any backup until the restore of backup %(id)s.tar.gz is finished.'),

"GINADAP0001E": _("SAN adapter '%(adapter)s' does not exist in the system."
),
diff --git a/model/backup.py b/model/backup.py
index 754d472..d5b3421 100644
--- a/model/backup.py
+++ b/model/backup.py
@@ -28,7 +28,7 @@ import uuid

import cherrypy

-from wok.asynctask import AsyncTask
+from wok.asynctask import AsyncTask, tasks_queue
from wok.config import PluginPaths
from wok.exception import InvalidOperation, NotFoundError, OperationFailed
from wok.exception import InvalidParameter
@@ -323,4 +323,12 @@ class ArchiveModel(object):
def restore(self, archive_id):
taskid = AsyncTask(u'/backup/restore/%s' % (archive_id),
self._restore_task, archive_id).id
+ task = {}
+ tasks_id = tasks_queue.keys()
+ for id in tasks_id:
+ task = (self.task.lookup(taskid))
+ if task['target_uri'].startswith('/backup/restore'):
+ restore_id = task['target_uri'].split("/")[-1:]
+ print restore_id
+ raise OperationFailed('GINHBK0014E', {'id': restore_id[0]})
return self.task.lookup(taskid)
diff --git a/ui/css/ginger.css b/ui/css/ginger.css
index 87d7c4e..9a37f23 100644
--- a/ui/css/ginger.css
+++ b/ui/css/ginger.css
@@ -700,7 +700,13 @@
.no-results-found {
border-top: 1px solid #eee;
text-align: center;
- padding-top: 4px;
+ padding-top: 10px;
+}
+
+.generating-bkp, .restoring-bkp {
+ border-top: 1px solid #eee;
+ text-align: center;
+ padding-top: 10px;
}

#audit-rules-content-area .audit-rules-loaded-enable .fa {
@@ -918,6 +924,11 @@
padding: 8px 32px 8px 16px;
}

+.disable-bkplist {
+ pointer-events: none;
+ opacity: 0.4;
+}
+
#network-root-container .accordion {
margin: 12px 20px 12px 60px;
padding-bottom: 18px;
diff --git a/ui/css/src/modules/_administration.scss b/ui/css/src/modules/_administration.scss
index c3dfc3a..6c7286c 100644
--- a/ui/css/src/modules/_administration.scss
+++ b/ui/css/src/modules/_administration.scss
@@ -420,7 +420,13 @@
.no-results-found {
border-top: 1px solid #eee;
text-align: center;
- padding-top: 4px;
+ padding-top: 10px;
+}
+
+.generating-bkp, .restoring-bkp {
+ border-top: 1px solid #eee;
+ text-align: center;
+ padding-top: 10px;
}

#audit-rules-content-area{
@@ -635,3 +641,8 @@ overflow: visible;
#alert-user-modal .alert {
padding: 8px 32px 8px 16px;
}
+
+.disable-bkplist {
+ pointer-events: none;
+ opacity: 0.4;
+}
diff --git a/ui/js/host-admin.js b/ui/js/host-admin.js
index 931eee7..5f7ca8e 100644
--- a/ui/js/host-admin.js
+++ b/ui/js/host-admin.js
@@ -95,23 +95,34 @@ ginger.initBakDialog = function() {
$("body button").prop("disabled", "disabled");
$("body input").css("cursor", "wait");
$("body button").css("cursor", "wait");
- var taskAccepted = false;
- var onTaskAccepted = function() {
- if (taskAccepted) {
- return;
- }
- taskAccepted = true;
- };
- $('#newBakDialog').modal('hide');
- wok.message.success(i18n['GINCFGB00001M'], '#alert-modal-container');
- $("#newDefaultBakBtn").hide();
- $("#newCustomBakBtn").hide();
- $("#batchDeleteButton").hide();
+ $('#newBakDialog').modal().hide();
+ $('body').removeClass('modal-open');
+ $('.modal-backdrop').remove()
+
+ if ($(".no-results-found").is(':visible')) {
+ $(".no-results-found").hide();
+ } else {
+ $(".column-restore").css('pointer-events', 'none');
+ $(".column-restore").css('opacity', '0.5');
+ $(".column-delete").css('pointer-events', 'none');
+ $(".column-delete").css('opacity', '0.5');
+ }
+
+ var loadingIcon = '<span class="wok-list-loading-icon-inline" role="status" style="margin-top: 3px;"></span>'
+ var rowGenerating = "<li class='generating-bkp'>" + loadingIcon + "<span style='font-size: 12.5pt; margin-left: 20px;'>Generating backup...</span></li>";
+ $("#bakGridBody").append(rowGenerating);
+ $('.wok-list-loading-icon-inline').show();
+
+ $("#newDefaultBakBtn").prop('disabled', true);
+ $("#newCustomBakBtn").prop('disabled', true);
+ $("#batchDeleteButton").prop('disabled', true);
ginger.createBackupArchive(content, function() {
- wok.message.success(i18n['GINCFGB00002M'], '#alert-modal-container');
- $("#newDefaultBakBtn").show();
- $("#newCustomBakBtn").show();
- $("#batchDeleteButton").show();
+ $("#newDefaultBakBtn").prop('disabled', false);
+ $("#newCustomBakBtn").prop('disabled', false);
+ $("#batchDeleteButton").prop('disabled', false);
+ $("body").css('cursor', 'default');
+ $("body input").css("cursor", "text");
+ $("body button").css("cursor", "pointer");
ginger.setupBakGrid();
}, function(result) {
wok.message.error(result.message,'#alert-modal-container',true);
@@ -123,7 +134,11 @@ ginger.initBakDialog = function() {
$("body button").prop("disabled", false);
$("body input").css("cursor", "text");
$("body button").css("cursor", "pointer");
- }, onTaskAccepted);
+ $(".column-restore").css('pointer-events', 'auto');
+ $(".column-restore").css('opacity', '1');
+ $(".column-delete").css('pointer-events', 'auto');
+ $(".column-delete").css('opacity', '1');
+ }, function() {});
});

var tempNode = $.parseHTML($("#pathItem").html());
@@ -140,14 +155,11 @@ ginger.initBakDialog = function() {
});

var clearForm = function() {
- $("body").css('cursor', 'default');
$("#description-textbox", "#newBakDialog").prop("value", null);
$("#includeBox").empty();
$("#excludeBox").empty();
$("body input").prop("readonly", false);
$("body button").prop("disabled", false);
- $("body input").css("cursor", "text");
- $("body button").css("cursor", "pointer");
$("#newBakFormBtn").prop("disabled", true);
};
};
@@ -211,9 +223,98 @@ ginger.initBatDelDialog = function() {
});
});
};
+var restoreId;
+var getPending = function(target_uri) {
+ var backups = [];
+ var filter = 'status=running&target_uri=' + target_uri;
+
+ ginger.getTasksByFilter(filter, function(tasks) {
+ for (var i = 0; i < tasks.length; i++) {
+ var bkpName = tasks[i].target_uri;
+ backups.push({
+ 'name': bkpName,
+ });
+
+ if (ginger.trackingTasks.indexOf(tasks[i].id) >= 0) {
+ continue;
+ }
+
+ ginger.trackTask(tasks[i].id, function(result) {
+ wok.topic('ginger/bkpAdded').publish();
+ }, function(result) {
+ // Error message from Async Task status
+ if (result['message']) {
+ var errText = result['message'];
+ }
+ // Error message from standard ginger exception
+ else {
+ var errText = result['responseJSON']['reason'];
+ }
+ result && wok.message.error(errText);
+ wok.topic('ginger/bkpAdded').publish();
+ }, null);
+ }
+ if (!(restoreId) && (backups.length > 0)) {
+ restoreId = bkpName.split("/")[3];
+ }
+ }, null, true);
+
+ return backups;
+};
+
+var getBackupList = function() {
+ var pendingBackups = getPending('/backup/create/');
+ setTimeout(function(){
+ if (pendingBackups.length > 0) {
+ if ($(".no-results-found").is(':visible')) {
+ $(".no-results-found").hide();
+ } else {
+ $(".column-restore").css('pointer-events', 'none');
+ $(".column-restore").css('opacity', '0.5');
+ $(".column-delete").css('pointer-events', 'none');
+ $(".column-delete").css('opacity', '0.5');
+ }
+ var loadingIcon = '<span class="wok-list-loading-icon-inline" role="status" style="margin-top: 3px;"></span>'
+ var rowGenerating = "<li class='generating-bkp'>" + loadingIcon + "<span style='font-size: 12.5pt; margin-left: 20px;'>Generating backup...</span></li>";
+ $("#bakGridBody").append(rowGenerating);
+ $('.wok-list-loading-icon-inline').show();
+ $("#newDefaultBakBtn").prop('disabled', true);
+ $("#newCustomBakBtn").prop('disabled', true);
+ $("#batchDeleteButton").prop('disabled', true);
+ }
+ }, 500);
+};
+
+var getRestoreList = function() {
+ var pendingRestore = getPending('/backup/restore/');
+ $('#alert-fields').remove();
+ setTimeout(function(){
+ var warningMsg = '<div id="bkp-warning" class="alert alert-warning"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> You will be unable to restore any backup until the restore of backup <strong>' + restoreId + '.tar.gz</strong> is finished.</div>'
+ var loadingIcon = '<span class="wok-list-loading-icon-inline" role="status" style="margin-top: 13px;"></span>'
+ if (pendingRestore.length > 0) {
+ if (!($('#bkp-warning').is(':visible'))) {
+ $('.wok-datagrid').prepend(warningMsg);
+ }
+ $(".column-restore").css('pointer-events', 'none');
+ $(".column-restore").css('opacity', '0.5');
+ $('#' + restoreId).addClass('disable-bkplist');
+ $('#' + restoreId + ' .column-file').html(loadingIcon + '<span style="margin-left: 20px;">' + restoreId + '.tar.gz</span>');
+ $('.wok-list-loading-icon-inline').show();
+ } else {
+ $('#bkp-warning').remove();
+ $('#' + restoreId).removeClass('disable-bkplist');
+ $('#' + restoreId + ' .column-file').html('<span>' + restoreId + '.tar.gz</span>');
+ $('.wok-list-loading-icon-inline').hide();
+ $(".column-restore").css('pointer-events', '');
+ $(".column-restore").css('opacity', '1');
+ }
+ }, 200);
+};

ginger.setupBakGrid = function() {
ginger.listBackupArchives(function(data) {
+ getBackupList();
+ getRestoreList();
$("#bakGridBody").empty();
if (data.length == 0) {
$("#batchDeleteButton").prop("disabled", true);
@@ -247,26 +348,21 @@ ginger.setupBakGrid = function() {
var bakItem = $(this).parent();
window.open('plugins/ginger/backup/archives/' + encodeURIComponent(bakItem.prop("id")) + '/file');
});
- $(".btn-restore").on("click", function(event) {
+ $(".btn-restore").on('click', function(event) {
event.preventDefault();
- var taskAccepted = false;
- var onTaskAccepted = function() {
- if (taskAccepted) {
- return;
- }
- taskAccepted = true;
- };
- wok.message.success(i18n['GINCFGB00004M'], '#alert-modal-container');
- $(".btn-restore").css('cursor', 'not-allowed');
- $(".btn-delete").css('cursor', 'not-allowed');
+ restoreId = $(this).parent().attr('id');
var bakItem = $(this).parent();
ginger.restoreBackupArchive(bakItem.prop("id"), function() {
- wok.message.success(i18n['GINCFGB00003M'], '#alert-modal-container');
$(".btn-restore").css('cursor', '');
$(".btn-delete").css('cursor', '');
ginger.setupBakGrid();
- }, function() {}, onTaskAccepted )
+ }, function(result) {
+ wok.message.error(result.message,'#alert-modal-container',true);
+ }, function() {} )
+
+ ginger.setupBakGrid();
});
+
$(".btn-delete").on("click", function(event) {
event.preventDefault();
event.stopImmediatePropagation();
@@ -275,6 +371,7 @@ ginger.setupBakGrid = function() {
ginger.setupBakGrid();
});
});
+
}

$('.arrow').on('click', function(event) {
@@ -293,6 +390,7 @@ ginger.setupBakGrid = function() {
ginger.changeArrow($('.arrow-up', that));
}
});
+
});
};

@@ -305,31 +403,39 @@ ginger.changeArrow = function(obj) {
}

ginger.initConfigBak = function() {
- $("#newDefaultBakBtn").on("click", function(event) {
- event.preventDefault();
- var taskAccepted = false;
- var onTaskAccepted = function() {
- if (taskAccepted) {
- return;
+ $("#newDefaultBakBtn").on("click", function(event) {
+ event.preventDefault();
+ if ($(".no-results-found").is(':visible')) {
+ $(".no-results-found").hide();
+ } else {
+ $(".column-restore").css('pointer-events', 'none');
+ $(".column-restore").css('opacity', '0.5');
+ $(".column-delete").css('pointer-events', 'none');
+ $(".column-delete").css('opacity', '0.5');
}
- taskAccepted = true;
- };
- wok.message.success(i18n['GINCFGB00001M'], '#alert-modal-container');
- $("#newDefaultBakBtn").hide();
- $("#newCustomBakBtn").hide();
- $("#batchDeleteButton").hide();
- ginger.createBackupArchive({}, function() {
- wok.message.success(i18n['GINCFGB00002M'], '#alert-modal-container');
- $("#newDefaultBakBtn").show();
- $("#newCustomBakBtn").show();
- $("#batchDeleteButton").show();
- ginger.setupBakGrid();
- }, function() {}, onTaskAccepted )
- });
+ var loadingIcon = '<span class="wok-list-loading-icon-inline" role="status" style="margin-top: 3px;"></span>'
+ var rowGenerating = "<li class='generating-bkp'>" + loadingIcon + "<span style='font-size: 12.5pt; margin-left: 20px;'>Generating backup...</span></li>";
+ $("#bakGridBody").append(rowGenerating);
+ $('.wok-list-loading-icon-inline').show();
+ $("#batchDeleteButton").prop('disabled', true);
+ $("#newDefaultBakBtn").prop('disabled', true);
+ $("#newCustomBakBtn").prop('disabled', true);
+ $("#batchDeleteButton").prop('disabled', true);
+ ginger.createBackupArchive({}, function() {
+ $(".column-restore").css('pointer-events', 'auto');
+ $(".column-restore").css('opacity', '1');
+ $(".column-delete").css('pointer-events', 'auto');
+ $(".column-delete").css('opacity', '1');
+ $("#newDefaultBakBtn").prop('disabled', false);
+ $("#newCustomBakBtn").prop('disabled', false);
+ $("#batchDeleteButton").prop('disabled', false);
+ ginger.setupBakGrid();
+ }, function() {}, function() {} )
+ });

- ginger.setupBakGrid();
- ginger.initBakDialog();
- ginger.initBatDelDialog();
+ ginger.setupBakGrid();
+ ginger.initBakDialog();
+ ginger.initBatDelDialog();
};

ginger.initPowerMgmt = function() {
@@ -2191,6 +2297,13 @@ ginger.initGraphDetails = function(columnInfo){
$("#generate-report-graph-button").off();
});
};
+
+ginger.restoreTaks = function() {
+ setInterval(function(){
+ getRestoreList();
+ }, 3000);
+};
+
ginger.initAdmin = function() {
$(".content-area", "#gingerHostAdmin").css("height", "100%");
ginger.getCapabilities(function(result) {
diff --git a/ui/js/util.js b/ui/js/util.js
index a4e4bd5..b99cc7e 100644
--- a/ui/js/util.js
+++ b/ui/js/util.js
@@ -20,7 +20,7 @@ ginger = {};
ginger.hostarch = null;
ginger.selectedInterface = null;

-trackingTasks = [];
+ginger.trackingTasks = [];
ginger.getFirmware = function(suc, err){
wok.requestJSON({
url : 'plugins/ginger/firmware',
@@ -830,6 +830,18 @@ ginger.getTask = function(taskId, suc, err) {
error : err
});
}
+
+ginger.getTasksByFilter = function(filter, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/ginger/tasks?' + filter,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+},
+
ginger.trackTask = function(taskID, suc, err, progress) {
var onTaskResponse = function(result) {
var taskStatus = result['status'];
@@ -855,8 +867,8 @@ ginger.trackTask = function(taskID, suc, err, progress) {
};

ginger.getTask(taskID, onTaskResponse, err);
- if(trackingTasks.indexOf(taskID) < 0)
- trackingTasks.push(taskID);
+ if(ginger.trackingTasks.indexOf(taskID) < 0)
+ ginger.trackingTasks.push(taskID);
}

ginger.trackdevices = function(trackDevicelist,removeItem) {
diff --git a/ui/pages/i18n.json.tmpl b/ui/pages/i18n.json.tmpl
index dce9943..61ca48a 100644
--- a/ui/pages/i18n.json.tmpl
+++ b/ui/pages/i18n.json.tmpl
@@ -130,10 +130,6 @@
"GINUM0006M": "$_("Password changed successfully for '%1'.")",
"GINUM0007M": "$_("'%1' deleted successfully.")",

- "GINCFGB00001M" : "$_("New Config Backup creation has started.")",
- "GINCFGB00004M" : "$_("New Config Backup restore has started.")",
- "GINCFGB00002M" : "$_("Config Backup has been successfully created.")",
- "GINCFGB00003M" : "$_("Config Backup has been successfully restored.")",
"GINTITLE0001M": "$_("Name")",
"GINTITLE0002M": "$_("Type")",
"GINTITLE0003M": "$_("Mount Point")",
diff --git a/ui/pages/tabs/host-admin.html.tmpl b/ui/pages/tabs/host-admin.html.tmpl
index 05eb024..64556c6 100644
--- a/ui/pages/tabs/host-admin.html.tmpl
+++ b/ui/pages/tabs/host-admin.html.tmpl
@@ -944,6 +944,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
</script>
<script>
ginger.initAdmin();
+ginger.restoreTaks();
</script>
<script id="userManagement" type="text/javascript"></script>
</body>
--
2.9.3

bia...@linux.vnet.ibm.com

unread,
Feb 15, 2017, 1:32:56 PM2/15/17
to Ginger Devel, Daniel Barboza
From: Bianca Carvalho <bia...@linux.vnet.ibm.com>

Changed UI and backend to avoid more than one backup restore to run
at the same time (inclued a warning message to let the user knows
about that as well). Also changed UI elements to make sure the user
can see what is happening during the backup/restore.

Signed-off-by: Bianca Carvalho <bia...@linux.vnet.ibm.com>
---
model/backup.py | 5 +
ui/css/ginger.css | 13 +-
ui/css/src/modules/_administration.scss | 13 +-
ui/js/host-admin.js | 213 +++++++++++++++++++++++---------
ui/js/util.js | 18 ++-
ui/pages/i18n.json.tmpl | 4 -
ui/pages/tabs/host-admin.html.tmpl | 1 +
7 files changed, 202 insertions(+), 65 deletions(-)

diff --git a/model/backup.py b/model/backup.py
index 754d472..ee6498c 100644
--- a/model/backup.py
+++ b/model/backup.py
@@ -23,6 +23,7 @@ import hashlib
import itertools
import os
import re
+import threading
import time
import uuid

@@ -35,6 +36,7 @@ from wok.exception import InvalidParameter
from wok.model.tasks import TaskModel
from wok.utils import run_command, wok_log

+restoreLock = threading.Lock()

class BackupModel(object):

@@ -312,6 +314,7 @@ class ArchiveModel(object):
def _restore_task(self, rb, backup_id):
rb('entering task to restore config backup')
try:
+ restoreLock.acquire()
self._restore_tar(backup_id)
rb('OK', True)
except (InvalidOperation) as e:
@@ -319,6 +322,8 @@ class ArchiveModel(object):
except (OperationFailed) as e:
rb(e.message, False)
raise OperationFailed('GINHBK0013E', {'err': e.message})
+ finally:
+ restoreLock.release()

def restore(self, archive_id):
taskid = AsyncTask(u'/backup/restore/%s' % (archive_id),
index cccb54b..1f68661 100644
@@ -211,9 +223,87 @@ ginger.initBatDelDialog = function() {
+ setTimeout(function(){
+ var loadingIcon = '<span class="wok-list-loading-icon-inline" role="status" style="margin-top: 13px;"></span>'
+ if (pendingRestore.length > 0) {
+ $('#' + restoreId).addClass('disable-bkplist');
+ $('#' + restoreId + ' .column-restore').css('pointer-events', 'none');
+ $('#' + restoreId + ' .column-file').html(loadingIcon + '<span style="margin-left: 20px;">' + restoreId + '.tar.gz</span>');
+ $('.wok-list-loading-icon-inline').show();
+ } else {
+ $('#' + restoreId).removeClass('disable-bkplist');
+ $('#' + restoreId + ' .column-restore').css('pointer-events', '');
+ $('#' + restoreId + ' .column-file').html('<span>' + restoreId + '.tar.gz</span>');
+ $('.wok-list-loading-icon-inline').hide();
+ }
+ }, 200);
+};

ginger.setupBakGrid = function() {
ginger.listBackupArchives(function(data) {
+ getBackupList();
+ getRestoreList();
$("#bakGridBody").empty();
if (data.length == 0) {
$("#batchDeleteButton").prop("disabled", true);
@@ -247,26 +337,20 @@ ginger.setupBakGrid = function() {
var bakItem = $(this).parent();
window.open('plugins/ginger/backup/archives/' + encodeURIComponent(bakItem.prop("id")) + '/file');
});
- $(".btn-restore").on("click", function(event) {
+ $(".btn-restore").on('click', function(event) {
event.preventDefault();
- var taskAccepted = false;
- var onTaskAccepted = function() {
- if (taskAccepted) {
- return;
- }
- taskAccepted = true;
- };
- wok.message.success(i18n['GINCFGB00004M'], '#alert-modal-container');
- $(".btn-restore").css('cursor', 'not-allowed');
- $(".btn-delete").css('cursor', 'not-allowed');
+ event.stopImmediatePropagation();
+ restoreId = $(this).parent().attr('id');
var bakItem = $(this).parent();
ginger.restoreBackupArchive(bakItem.prop("id"), function() {
- wok.message.success(i18n['GINCFGB00003M'], '#alert-modal-container');
$(".btn-restore").css('cursor', '');
$(".btn-delete").css('cursor', '');
ginger.setupBakGrid();
- }, function() {}, onTaskAccepted )
+ }, function(result) {
+ wok.message.error(result.message,'#alert-modal-container',true);
+ }, function() {} )
});
+
$(".btn-delete").on("click", function(event) {
event.preventDefault();
event.stopImmediatePropagation();
@@ -275,6 +359,7 @@ ginger.setupBakGrid = function() {
ginger.setupBakGrid();
});
});
+
}

$('.arrow').on('click', function(event) {
@@ -293,6 +378,7 @@ ginger.setupBakGrid = function() {
ginger.changeArrow($('.arrow-up', that));
}
});
+
});
};

@@ -305,31 +391,39 @@ ginger.changeArrow = function(obj) {
@@ -2205,6 +2299,13 @@ ginger.initGraphDetails = function(columnInfo){
$("#generate-report-graph-button").off();
});
};
+
+ginger.restoreTask = function() {
index 1c521b6..68342dd 100644
--- a/ui/pages/i18n.json.tmpl
+++ b/ui/pages/i18n.json.tmpl
@@ -132,10 +132,6 @@
"GINUM0006M": "$_("Password changed successfully for '%1'.")",
"GINUM0007M": "$_("'%1' deleted successfully.")",

- "GINCFGB00001M" : "$_("New Config Backup creation has started.")",
- "GINCFGB00004M" : "$_("New Config Backup restore has started.")",
- "GINCFGB00002M" : "$_("Config Backup has been successfully created.")",
- "GINCFGB00003M" : "$_("Config Backup has been successfully restored.")",
"GINTITLE0001M": "$_("Name")",
"GINTITLE0002M": "$_("Type")",
"GINTITLE0003M": "$_("Mount Point")",
diff --git a/ui/pages/tabs/host-admin.html.tmpl b/ui/pages/tabs/host-admin.html.tmpl
index 05eb024..da86708 100644
--- a/ui/pages/tabs/host-admin.html.tmpl
+++ b/ui/pages/tabs/host-admin.html.tmpl
@@ -944,6 +944,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
</script>
<script>
ginger.initAdmin();
+ginger.restoreTask();

Ramon Medeiros

unread,
Feb 15, 2017, 1:38:15 PM2/15/17
to bia...@linux.vnet.ibm.com, Ginger Devel, Daniel Barboza
Reviewed-By: Ramon Medeiros <ram...@br.ibm.com>

Daniel Henrique Barboza

unread,
Feb 15, 2017, 2:02:22 PM2/15/17
to ginger-...@googlegroups.com
make[2]: Entering directory
'/home/danielhb/kimchi/wok_all_plugins/src/wok/plugins/ginger'
contrib/check_i18n.py ./i18n.py
Checking for invalid i18n string...
Checking for invalid i18n string successfully
/bin/pep8 --version
1.7.0
/bin/pep8 --filename '*.py,*.py.in' control model tests
model/backup.py:41:1: E302 expected 2 blank lines, found 1
Makefile:968: recipe for target 'check-local' failed
make[2]: *** [check-local] Error 1
make[2]: Leaving directory
'/home/danielhb/kimchi/wok_all_plugins/src/wok/plugins/ginger'
Makefile:831: recipe for target 'check-am' failed
make[1]: *** [check-am] Error 2
make[1]: Leaving directory
'/home/danielhb/kimchi/wok_all_plugins/src/wok/plugins/ginger'
Makefile:543: recipe for target 'check-recursive' failed
make: *** [check-recursive] Error 1


On 02/15/2017 04:32 PM, bia...@linux.vnet.ibm.com wrote:

bia...@linux.vnet.ibm.com

unread,
Feb 15, 2017, 3:24:47 PM2/15/17
to Ginger Devel, Daniel Barboza
From: Bianca Carvalho <bia...@linux.vnet.ibm.com>

Changed UI and backend to avoid more than one backup restore to run
at the same time (inclued a warning message to let the user knows
about that as well). Also changed UI elements to make sure the user
can see what is happening during the backup/restore.

Signed-off-by: Bianca Carvalho <bia...@linux.vnet.ibm.com>
---
model/backup.py | 6 +
ui/css/ginger.css | 13 +-
ui/css/src/modules/_administration.scss | 13 +-
ui/js/host-admin.js | 213 +++++++++++++++++++++++---------
ui/js/util.js | 18 ++-
ui/pages/i18n.json.tmpl | 4 -
ui/pages/tabs/host-admin.html.tmpl | 1 +
7 files changed, 203 insertions(+), 65 deletions(-)

diff --git a/model/backup.py b/model/backup.py
index 754d472..bf515e7 100644
--- a/model/backup.py
+++ b/model/backup.py
@@ -23,6 +23,7 @@ import hashlib
import itertools
import os
import re
+import threading
import time
import uuid

@@ -35,6 +36,8 @@ from wok.exception import InvalidParameter
from wok.model.tasks import TaskModel
from wok.utils import run_command, wok_log

+restoreLock = threading.Lock()
+

class BackupModel(object):

@@ -312,6 +315,7 @@ class ArchiveModel(object):
def _restore_task(self, rb, backup_id):
rb('entering task to restore config backup')
try:
+ restoreLock.acquire()
self._restore_tar(backup_id)
rb('OK', True)
except (InvalidOperation) as e:
@@ -319,6 +323,8 @@ class ArchiveModel(object):
--
2.9.3

Daniel Henrique Barboza

unread,
Feb 15, 2017, 4:05:10 PM2/15/17
to ginger-...@googlegroups.com
Reviewed-by: Daniel Barboza <dani...@linux.vnet.ibm.com>
Tested-by: Daniel Barboza <dani...@linux.vnet.ibm.com>

ps: testing this feature with the Default Backup will cause
WoK logout and mess up with the system fonts. I think it's due
to the fact of messing up with the /etc files.

Aline Manera

unread,
Feb 17, 2017, 7:31:16 AM2/17/17
to bia...@linux.vnet.ibm.com, Ginger Devel, Daniel Barboza
Hi Bianca,

1) When a backup is being generated, I am not able to do any other
actions in other backup files.
For example, I should be able to create multiple backups at the
same time or delete others.

2) When restoring a large backup, the loading icon appears and
disappears time by time.
When it disappears I had the feeling the restore had finished, but
it came back in a second.

3) Not related to that patch, just a comment. The delete backup is a
destructive action so it would be better to have a confirmation message.
The same for restore.

That is all!

Regards,
Aline Manera

On 02/15/2017 06:23 PM, bia...@linux.vnet.ibm.com wrote:
Reply all
Reply to author
Forward
0 new messages