[PATCH] bug fix: Lock YUM operations

From: Aline Manera <alinefm@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@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

-- Reviewed-by: Paulo Vital <pvital@linux.vnet.ibm.com> On Tue, 2014-03-25 at 15:32 -0300, Aline Manera wrote:
From: Aline Manera <alinefm@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@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): """
participants (2)
-
Aline Manera
-
Paulo Ricardo Paz Vital