[PATCH ] Optimize return code check.
by Leonardo Garcia
From: Leonardo Garcia <lagarcia(a)br.ibm.com>
Instead of doing two comparisons, make just one and make this check
faster.
Signed-off-by: Leonardo Garcia <lagarcia(a)br.ibm.com>
---
src/kimchi/model/debugreports.py | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/src/kimchi/model/debugreports.py b/src/kimchi/model/debugreports.py
index 6ae282a..479d936 100644
--- a/src/kimchi/model/debugreports.py
+++ b/src/kimchi/model/debugreports.py
@@ -68,10 +68,7 @@ class DebugReportsModel(object):
command = ['sosreport', '--batch', '--name=%s' % name]
output, error, retcode = run_command(command)
- if retcode < 0:
- raise OperationFailed("KCHDR0003E", {'name': name,
- 'err': retcode})
- elif retcode > 0:
+ if retcode != 0:
raise OperationFailed("KCHDR0003E", {'name': name,
'err': retcode})
--
1.8.5.3
10 years, 9 months
[PATCH V2] Show error message from debug report generation async task
by Rodrigo Trujillo
If the process of generating a debug report in Kimchi fails while it
was executing (e.g. due to running out of disk space to generate the
report), the error message was not being shown in the Kimchi UI.
Basically src/kimchi/control/tasks.py was putting the error message
in a JSON field called message, while the UI was looking for the error
message in a field called reason. 'reason' is used in standard
exception json returned only.
Signed-off-by: Leonardo Garcia <lagarcia(a)br.ibm.com>
Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.report_add_main.js | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/ui/js/src/kimchi.report_add_main.js b/ui/js/src/kimchi.report_add_main.js
index 15cc76b..8759c2b 100644
--- a/ui/js/src/kimchi.report_add_main.js
+++ b/ui/js/src/kimchi.report_add_main.js
@@ -23,9 +23,11 @@ kimchi.report_add_main = function() {
result: result
});
}, function(result) {
- if (result['reason']) {
- var errText = result['reason'];
+ // Error message from Async Task status
+ if (result['message']) {
+ var errText = result['message'];
}
+ // Error message from standard kimchi exception
else {
var errText = result['responseJSON']['reason'];
}
--
1.8.5.3
10 years, 9 months
[PATCH] bug fix: Lock YUM operations
by Aline Manera
From: Aline Manera <alinefm(a)br.ibm.com>
In addition to cherrypy lock - that avoids concurrent requests - we also
need to use the yum.doLock() to avoid different applications running
YUM, example, Kimchi and Package Kit.
Signed-off-by: Aline Manera <alinefm(a)br.ibm.com>
---
src/kimchi/i18n.py | 4 ++++
src/kimchi/repositories.py | 27 ++++++++++++++++++++-------
src/kimchi/swupdate.py | 9 +++++++--
3 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index c084e21..398d49a 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -249,4 +249,8 @@ messages = {
"KCHREPOS0021E": _("Could not disable repository %(repo_id)s."),
"KCHREPOS0022E": _("YUM Repository ID already exists"),
"KCHREPOS0023E": _("YUM Repository name must be a string"),
+ "KCHREPOS0024E": _("Unable to list repositories. Details: '%(err)s'"),
+ "KCHREPOS0025E": _("Unable to retrieve repository information. Details: '%(err)s'"),
+ "KCHREPOS0026E": _("Unable to add repository. Details: '%(err)s'"),
+ "KCHREPOS0027E": _("Unable to remove repository. Details: '%(err)s'"),
}
diff --git a/src/kimchi/repositories.py b/src/kimchi/repositories.py
index bdf5df5..1c74f04 100644
--- a/src/kimchi/repositories.py
+++ b/src/kimchi/repositories.py
@@ -115,14 +115,26 @@ class YumRepo(object):
self._confdir = d
break
+ def _get_repos(self, errcode):
+ try:
+ yb = self._yb()
+ yb.doLock()
+ repos = yb.repos
+ yb.doUnlock()
+ except Exception, e:
+ kimchiLock.release()
+ raise OperationFailed(errcode, {'err': e.message})
+
+ return repos
+
def getRepositoriesList(self):
"""
Return a list of repositories IDs
"""
kimchiLock.acquire()
- repos = self._yb().repos.repos.keys()
+ repos = self._get_repos('KCHREPOS0024E')
kimchiLock.release()
- return repos
+ return repos.repos.keys()
def getRepo(self, repo_id):
"""
@@ -130,8 +142,9 @@ class YumRepo(object):
repository ID format with the information of a YumRepository object.
"""
kimchiLock.acquire()
- repos = self._yb().repos
+ repos = self._get_repos('KCHREPOS0025E')
kimchiLock.release()
+
if repo_id not in repos.repos.keys():
raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
@@ -169,7 +182,7 @@ class YumRepo(object):
repo_id = "kimchi_repo_%s" % str(int(time.time() * 1000))
kimchiLock.acquire()
- repos = self._yb().repos
+ repos = self._get_repos('KCHREPOS0026E')
kimchiLock.release()
if repo_id in repos.repos.keys():
raise InvalidOperation("KCHREPOS0022E", {'repo_id': repo_id})
@@ -199,7 +212,7 @@ class YumRepo(object):
def toggleRepo(self, repo_id, enable):
kimchiLock.acquire()
- repos = self._yb().repos
+ repos = self._get_repos('KCHREPOS0011E')
kimchiLock.release()
if repo_id not in repos.repos.keys():
raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
@@ -234,7 +247,7 @@ class YumRepo(object):
Update a given repository in repositories.Repositories() format
"""
kimchiLock.acquire()
- repos = self._yb().repos
+ repos = self._get_repos('KCHREPOS0011E')
kimchiLock.release()
if repo_id not in repos.repos.keys():
raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
@@ -265,7 +278,7 @@ class YumRepo(object):
Remove a given repository
"""
kimchiLock.acquire()
- repos = self._yb().repos
+ repos = self._get_repos('KCHREPOS0027E')
kimchiLock.release()
if repo_id not in repos.repos.keys():
raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
diff --git a/src/kimchi/swupdate.py b/src/kimchi/swupdate.py
index 625b091..9489900 100644
--- a/src/kimchi/swupdate.py
+++ b/src/kimchi/swupdate.py
@@ -149,8 +149,13 @@ class YumUpdate(object):
"""
Update the list of packages to be updated in the system.
"""
- self._yb = getattr(__import__('yum'), 'YumBase')()
- self._pkgs = self._yb.doPackageLists('updates')
+ try:
+ yb = getattr(__import__('yum'), 'YumBase')()
+ yb.doLock()
+ self._pkgs = yb.doPackageLists('updates')
+ yb.doUnlock()
+ except Exception, e:
+ raise OperationFailed('KCHPKGUPD0003E', {'err': e.message})
def getPackagesList(self):
"""
--
1.7.10.4
10 years, 9 months
[PATCH 0/5] Fix 'disk full' issue
by Rodrigo Trujillo
If the disk where objectstore (Kimchi database) is full, then a lot of
errors will be raised without any special treatment. This can lead the
system to an unexpected state.
This patchset modifies kimchi in order to give the right treatment to
exceptions, showing the error to the user or hidding when possible.
Rodrigo Trujillo (5):
Fix 'disk full' issue: Change objectstore exception handling
Fix 'disk full' issue: Fix Templates db store/delete error handling
Fix 'disk full' issue: Fix storage volume error handling
Fix 'disk full' issue: Fix storagepool and asynctasks error handling
Fix 'disk full' issue: Fix vms/screenshot db store/delete error
handling
src/kimchi/asynctask.py | 7 ++--
src/kimchi/i18n.py | 5 +++
src/kimchi/model/storagepools.py | 8 +++--
src/kimchi/model/storagevolumes.py | 45 +++++++++++++++----------
src/kimchi/model/templates.py | 22 ++++++++----
src/kimchi/model/vms.py | 68 +++++++++++++++++++++++++++-----------
src/kimchi/objectstore.py | 8 +++++
7 files changed, 113 insertions(+), 50 deletions(-)
--
1.8.5.3
10 years, 9 months
[PATCH ] Show error message if debug report generation errors.
by Leonardo Garcia
From: Leonardo Garcia <lagarcia(a)br.ibm.com>
If the process of generating a debug report in Kimchi fails while it
was executing (e.g. due to running out of disk space to generate the
report), the error message was not being shown in the Kimchi UI. Basically
src/kimchi/control/tasks.py was putting the error message in a JSON field
called message, while the UI was looking for the error message in a field
called reason.
Signed-off-by: Leonardo Garcia <lagarcia(a)br.ibm.com>
---
ui/js/src/kimchi.report_add_main.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/ui/js/src/kimchi.report_add_main.js b/ui/js/src/kimchi.report_add_main.js
index 15cc76b..3248e2f 100644
--- a/ui/js/src/kimchi.report_add_main.js
+++ b/ui/js/src/kimchi.report_add_main.js
@@ -23,11 +23,11 @@ kimchi.report_add_main = function() {
result: result
});
}, function(result) {
- if (result['reason']) {
- var errText = result['reason'];
+ if (result['message']) {
+ var errText = result['message'];
}
else {
- var errText = result['responseJSON']['reason'];
+ var errText = result['responseJSON']['message'];
}
result && kimchi.message.error(errText)
submitButton
--
1.8.5.3
10 years, 9 months
[PATCH 0/2] Fixes on Update feature
by Aline Manera
From: Aline Manera <alinefm(a)br.ibm.com>
Aline Manera (2):
bug fix: Display update progress on real time
bug fix: Update progress area when an error occurs during update
process
src/kimchi/swupdate.py | 16 +++++++++++-----
ui/js/src/kimchi.host.js | 1 +
2 files changed, 12 insertions(+), 5 deletions(-)
--
1.7.10.4
10 years, 9 months
[PATCH] bug fix: Allow user specifies the repository name when adding a new YUM repo
by Aline Manera
From: Aline Manera <alinefm(a)br.ibm.com>
The backend already supports the repo_name as an optional parameter while
creating a new YUM repo but the jsonschema and docs are not consistent with that.
Fix it.
Also insert repo_name under "config" as it is YUM specific information.
Signed-off-by: Aline Manera <alinefm(a)br.ibm.com>
---
docs/API.md | 1 +
src/kimchi/API.json | 5 +++++
src/kimchi/i18n.py | 1 +
src/kimchi/mockmodel.py | 7 ++++---
src/kimchi/repositories.py | 2 +-
5 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/docs/API.md b/docs/API.md
index a380558..fed7f5e 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -854,6 +854,7 @@ http://, ftp:// or file:// URL.
* repo_id *(optional)*: Unique YUM repository ID
* config: A dictionary that contains specific data according to repository
type.
+ * repo_name *(optional)*: YUM Repository name
* mirrorlist *(optional)*: Specifies a URL to a file containing a
list of baseurls for YUM repository
* dist: Distribution to DEB repository
diff --git a/src/kimchi/API.json b/src/kimchi/API.json
index 9bde6a2..8ecd665 100644
--- a/src/kimchi/API.json
+++ b/src/kimchi/API.json
@@ -552,6 +552,11 @@
"error": "KCHREPOS0006E"
}
},
+ "repo_name": {
+ "description": "YUM repository name",
+ "type": "string",
+ "error": "KCHREPOS0023E"
+ },
"mirrorlist": {
"description": "URL to a file containing a list of baseurls",
"type": "string",
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index 1f84034..c084e21 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -248,4 +248,5 @@ messages = {
"KCHREPOS0020E": _("Could not enable repository %(repo_id)s."),
"KCHREPOS0021E": _("Could not disable repository %(repo_id)s."),
"KCHREPOS0022E": _("YUM Repository ID already exists"),
+ "KCHREPOS0023E": _("YUM Repository name must be a string"),
}
diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py
index 01480f4..b272933 100644
--- a/src/kimchi/mockmodel.py
+++ b/src/kimchi/mockmodel.py
@@ -1135,13 +1135,14 @@ class MockRepositories(object):
def addRepository(self, params):
# Create and enable the repository
repo_id = params['repo_id']
+ config = params.get('config', {})
repo = {'repo_id': repo_id,
'baseurl': params.get('baseurl'),
'enabled': True,
- 'config': {'repo_name': params.get('repo_name', repo_id),
- 'gpgkey': params.get('gpgkey', []),
+ 'config': {'repo_name': config.get('repo_name', repo_id),
+ 'gpgkey': config.get('gpgkey', []),
'gpgcheck': True,
- 'mirrorlist': params.get('mirrorlist', "")}
+ 'mirrorlist': config.get('mirrorlist', "")}
}
self._repos[repo_id] = repo
diff --git a/src/kimchi/repositories.py b/src/kimchi/repositories.py
index 39dde12..93603e8 100644
--- a/src/kimchi/repositories.py
+++ b/src/kimchi/repositories.py
@@ -174,7 +174,7 @@ class YumRepo(object):
if repo_id in repos.repos.keys():
raise InvalidOperation("KCHREPOS0022E", {'repo_id': repo_id})
- repo_name = params.get('repo_name', None)
+ repo_name = config.get('repo_name', None)
if repo_name is None:
repo_name = repo_id
--
1.7.10.4
10 years, 9 months
[PATCH V4 0/4] check the python code with pyflakes
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
V3 -> V4
address Rodrigo's comment.
add delete the cloned template in rollback.
V2 -> V3
address zhengsheng's comment.
improve the SKIP_PYFLAKES_ERR list.
V1 -> V2
address Crístian'comment:
remove the whole statement "info = self._get_vm(name).inf"
address ming's comment:
break down the patch into small patches by the pyflakes error.
Pyflakes analyzes programs and detects various errors. It works by
parsing the source file, not importing it, so it is safe to use on
modules with side effects. It's also much faster.
This is important to improve the code quality.
ShaoHe Feng (4):
make pyflakes happly, remove the unused import module
make pyflakes happly, remove unused availables
add template_delete to rollback after create a template
run pyflakes when make check
Makefile.am | 7 +++++++
configure.ac | 7 +++++++
contrib/DEBIAN/control.in | 1 +
contrib/kimchi.spec.fedora.in | 1 +
docs/README.md | 6 +++---
src/kimchi/control/plugins.py | 2 +-
src/kimchi/featuretests.py | 2 --
src/kimchi/mockmodel.py | 5 ++---
src/kimchi/model/storagepools.py | 2 +-
src/kimchi/screenshot.py | 1 -
src/kimchi/template.py | 1 -
tests/test_model.py | 2 ++
tests/test_server.py | 1 -
ui/pages/help/gen-index.py | 1 -
14 files changed, 25 insertions(+), 14 deletions(-)
--
1.8.5.3
10 years, 9 months
[PATCH v2] Issue#349: Software Update Grid Keeps Loading when Error Returns
by Hongliang Wang
Software update grid keeps loading on UI when server returns 500 error.
Instead, we shall remove the loading UI and add a message UI to let the
user know something is wrong, as well as add a button to allow the user
retry.
v1 -> v2:
2a) Made message more user-friendly and informative
(Aline's comment)
Signed-off-by: Hongliang Wang <hlwang(a)linux.vnet.ibm.com>
---
ui/css/theme-default/grid.css | 20 +++++++++++++
ui/js/src/kimchi.api.js | 4 +--
ui/js/src/kimchi.grid.js | 66 +++++++++++++++++++++++++++++++++----------
ui/js/src/kimchi.host.js | 11 +++++++-
ui/pages/i18n.html.tmpl | 5 ++++
5 files changed, 87 insertions(+), 19 deletions(-)
diff --git a/ui/css/theme-default/grid.css b/ui/css/theme-default/grid.css
index 44ae614..684dd7b 100644
--- a/ui/css/theme-default/grid.css
+++ b/ui/css/theme-default/grid.css
@@ -239,3 +239,23 @@
height: 48px;
width: 49px;
}
+
+.grid-message {
+ background: white;
+ box-sizing: border-box;
+ bottom: 0;
+ left: 0;
+ overflow: auto;
+ padding: .2em .5em;
+ position: absolute;
+ right: 0;
+ z-index: 5;
+}
+
+.grid-message-text {
+ line-height: 25px;
+}
+
+.retry-button {
+ margin: 0 1em;
+}
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
index 4310435..11f83df 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -838,10 +838,8 @@ var kimchi = {
}, 200);
break;
case 'finished':
- suc(result);
- break;
case 'failed':
- err(result);
+ suc(result);
break;
default:
break;
diff --git a/ui/js/src/kimchi.grid.js b/ui/js/src/kimchi.grid.js
index 540f1ba..f35228d 100644
--- a/ui/js/src/kimchi.grid.js
+++ b/ui/js/src/kimchi.grid.js
@@ -62,6 +62,18 @@ kimchi.widget.Grid = function(params) {
'</div>',
'</div>',
'</div>',
+ '<div class="grid-message hidden">',
+ '<div class="grid-message-text">',
+ i18n['KCHGRD6002M'],
+ '<button class="retry-button btn-small">',
+ i18n['KCHGRD6003M'],
+ '</button>',
+ '</div>',
+ '<div class="detailed-title">',
+ i18n['KCHGRD6004M'],
+ '</div>',
+ '<div class="detailed-text"></div>',
+ '</div>',
'</div>'
];
@@ -161,6 +173,9 @@ kimchi.widget.Grid = function(params) {
var maskNode = $('.grid-mask', gridNode);
maskNode.css('top', captionHeight + 'px');
+ var messageNode = $('.grid-message', gridNode);
+ messageNode.css('top', captionHeight + 'px');
+
var fillBody = function(container, fields, data) {
var tbody = ($('tbody', container).length && $('tbody', container))
|| $('<tbody></tbody>').appendTo(container);
@@ -384,28 +399,49 @@ kimchi.widget.Grid = function(params) {
$('body').on('mousemove', positionResizer);
$('body').on('mouseup', endResizing);
+ this.showMessage = function(msg) {
+ $('.detailed-text', messageNode).text(msg);
+ $(messageNode).removeClass('hidden');
+ };
+
+ this.hideMessage = function() {
+ $(messageNode).addClass('hidden');
+ };
+
this.destroy = function() {
$('body').off('mousemove', positionResizer);
$('body').off('mouseup', endResizing);
};
var data = params['data'];
- if(!data) {
- return;
- }
+ var self = this;
+ var reload = function() {
+ if(!data) {
+ return;
+ }
- if($.isArray(data)) {
- this.setData(data);
- return;
- }
+ $(messageNode).addClass('hidden');
- if($.isFunction(data)) {
- var self = this;
- var loadData = data;
- maskNode.removeClass('hidden');
- loadData(function(data) {
+ if($.isArray(data)) {
self.setData(data);
- maskNode.addClass('hidden');
- });
- }
+ return;
+ }
+
+ if($.isFunction(data)) {
+ var loadData = data;
+ maskNode.removeClass('hidden');
+ loadData(function(data) {
+ self.setData(data);
+ maskNode.addClass('hidden');
+ });
+ }
+ };
+
+ var reloadButton = $('.retry-button', gridNode);
+ $(reloadButton).on('click', function(event) {
+ reload();
+ });
+
+ this.reload = reload;
+ reload();
};
diff --git a/ui/js/src/kimchi.host.js b/ui/js/src/kimchi.host.js
index ae2ee7d..53a4541 100644
--- a/ui/js/src/kimchi.host.js
+++ b/ui/js/src/kimchi.host.js
@@ -57,7 +57,9 @@ kimchi.host_main = function() {
kimchi.topic('kimchi/softwareUpdated').publish({
result: result
});
- }, function(result) {
+ }, function(error) {
+ var message = error && error['responseJSON'] && error['responseJSON']['reason'];
+ kimchi.message.error(message || i18n['KCHUPD6009M']);
$(updateButton).text(i18n['KCHUPD6006M']).prop('disabled', false);
}, reloadProgressArea);
}
@@ -100,6 +102,13 @@ kimchi.host_main = function() {
var updateButton = $('#' + softwareUpdatesGridID + '-update-button');
$(updateButton).prop('disabled', softwareUpdates.length === 0);
+ }, function(error) {
+ var message = error && error['responseJSON'] && error['responseJSON']['reason'];
+ if($.isFunction(gridCallback)) {
+ gridCallback([]);
+ }
+ softwareUpdatesGrid &&
+ softwareUpdatesGrid.showMessage(message || i18n['KCHUPD6008M']);
});
};
diff --git a/ui/pages/i18n.html.tmpl b/ui/pages/i18n.html.tmpl
index 2f47e50..9f7537f 100644
--- a/ui/pages/i18n.html.tmpl
+++ b/ui/pages/i18n.html.tmpl
@@ -60,6 +60,9 @@ var i18n = {
'KCHAPI6006M': "$_("Warning")",
'KCHGRD6001M': "$_("Loading...")",
+ 'KCHGRD6002M': "$_("An error occurs while checking for packages update.")",
+ 'KCHGRD6003M': "$_("Retry")",
+ 'KCHGRD6004M': "$_("Detailed message:")",
'KCHTMPL6001W': "$_("No iso found")",
@@ -87,6 +90,8 @@ var i18n = {
'KCHUPD6005M': "$_("Repository")",
'KCHUPD6006M': "$_("Update All")",
'KCHUPD6007M': "$_("Updating...")",
+ 'KCHUPD6008M': "$_("Failed to retrieve updates.")",
+ 'KCHUPD6009M': "$_("Failed to update package(s).")",
'KCHDR6001M': "$_("Debug report will be removed permanently and can't be recovered. Do you want to continue?")",
--
1.8.1.4
10 years, 9 months