
- Kimchi package manager classes are now able to know if there is already a package manager instance running in the system and where to find the default logfiles for those package managers. Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com> --- src/wok/plugins/kimchi/i18n.py | 1 + src/wok/plugins/kimchi/swupdate.py | 84 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/src/wok/plugins/kimchi/i18n.py b/src/wok/plugins/kimchi/i18n.py index ea325b8..416d951 100644 --- a/src/wok/plugins/kimchi/i18n.py +++ b/src/wok/plugins/kimchi/i18n.py @@ -270,6 +270,7 @@ messages = { "KCHPKGUPD0002E": _("Package %(name)s is not marked to be updated."), "KCHPKGUPD0003E": _("Error while getting packages marked to be updated. Details: %(err)s"), "KCHPKGUPD0004E": _("There is no compatible package manager for this system."), + "KCHPKGUPD0005E": _("There is a package manager instance running in the system."), "KCHUTILS0003E": _("Unable to choose a virtual machine name"), diff --git a/src/wok/plugins/kimchi/swupdate.py b/src/wok/plugins/kimchi/swupdate.py index b966424..73692d5 100644 --- a/src/wok/plugins/kimchi/swupdate.py +++ b/src/wok/plugins/kimchi/swupdate.py @@ -17,6 +17,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +import fcntl import os import signal import subprocess @@ -27,6 +28,8 @@ from wok.exception import NotFoundError, OperationFailed from wok.utils import run_command, wok_log from config import kimchiLock +from configobj import ConfigObj, ConfigObjError +from psutil import pid_exists from yumparser import get_yum_packages_list_update @@ -157,6 +160,23 @@ class YumUpdate(object): def __init__(self): self._pkgs = {} self.update_cmd = ["yum", "-y", "update"] + self.logfile = self._get_output_log() + + def _get_output_log(self): + """ + Return the logfile path + """ + yumcfg = None + try: + yumcfg = ConfigObj('/etc/yum.conf') + + except ConfigObjError: + return None + + if 'main' in yumcfg and 'logfile' in yumcfg['main']: + return yumcfg['main']['logfile'] + + return None def _refreshUpdateList(self): """ @@ -177,6 +197,9 @@ class YumUpdate(object): package = {'package_name': <string>, 'version': <string>, 'arch': <string>, 'repository': <string>} """ + if self.isRunning(): + raise OperationFailed('KCHPKGUPD0005E') + self._refreshUpdateList() pkg_list = [] for pkg in self._pkgs: @@ -185,6 +208,25 @@ class YumUpdate(object): pkg_list.append(package) return pkg_list + def isRunning(self): + """ + Return True whether the YUM package manager is already running or + False otherwise. + """ + try: + with open('/var/run/yum.pid', 'r') as pidfile: + pid = int(pidfile.read().rstrip('\n')) + + # cannot find pidfile, assumes yum is not running + except (IOError, ValueError): + return False + + # the pidfile exists and it lives in process table + if pid_exists(pid): + return True + + return False + class AptUpdate(object): """ @@ -196,6 +238,7 @@ class AptUpdate(object): self._pkgs = {} self.pkg_lock = getattr(__import__('apt_pkg'), 'SystemLock') self.update_cmd = ['apt-get', 'upgrade', '-y'] + self.logfile = '/var/log/apt/term.log' def _refreshUpdateList(self): """ @@ -218,6 +261,9 @@ class AptUpdate(object): package = {'package_name': <string>, 'version': <string>, 'arch': <string>, 'repository': <string>} """ + if self.isRunning(): + raise OperationFailed('KCHPKGUPD0005E') + kimchiLock.acquire() self._refreshUpdateList() kimchiLock.release() @@ -231,6 +277,21 @@ class AptUpdate(object): return pkg_list + def isRunning(self): + """ + Return True whether the APT package manager is already running or + False otherwise. + """ + try: + with open('/var/lib/dpkg/lock', 'w') as lockfile: + fcntl.lockf(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB) + + # cannot open dpkg lock file to write in exclusive mode means the + # apt is currently running + except IOError: + return True + + return False class ZypperUpdate(object): """ @@ -242,6 +303,7 @@ class ZypperUpdate(object): self._pkgs = {} self.update_cmd = ["zypper", "--non-interactive", "update", "--auto-agree-with-licenses"] + self.logfile = '/var/log/zypp/history' def _refreshUpdateList(self): """ @@ -268,7 +330,29 @@ class ZypperUpdate(object): package = {'package_name': <string>, 'version': <string>, 'arch': <string>, 'repository': <string>} """ + if self.isRunning(): + raise OperationFailed('KCHPKGUPD0005E') + kimchiLock.acquire() self._refreshUpdateList() kimchiLock.release() return self._pkgs + + def isRunning(self): + """ + Return True whether the Zypper package manager is already running or + False otherwise. + """ + try: + with open('/var/run/zypp.pid', 'r') as pidfile: + pid = int(pidfile.read().rstrip('\n')) + + # cannot find pidfile, assumes yum is not running + except (IOError, ValueError): + return False + + # the pidfile exists and it lives in process table + if pid_exists(pid): + return True + + return False -- 1.9.1