diff options
author | Chris St. Pierre <chris.a.st.pierre@gmail.com> | 2013-07-18 14:22:11 -0400 |
---|---|---|
committer | Chris St. Pierre <chris.a.st.pierre@gmail.com> | 2013-07-18 14:22:11 -0400 |
commit | 827d0a83b8c9148598c23cb550862c0cf50b5a23 (patch) | |
tree | 9f8f09b3d8414c98b82e2a960c6d7a4d881c8766 | |
parent | 20794ebf60a9cc63d762b047ba24a2ad5c6a115f (diff) | |
download | bcfg2-827d0a83b8c9148598c23cb550862c0cf50b5a23.tar.gz bcfg2-827d0a83b8c9148598c23cb550862c0cf50b5a23.tar.bz2 bcfg2-827d0a83b8c9148598c23cb550862c0cf50b5a23.zip |
Packages: added lock to yum cache update
-rw-r--r-- | src/lib/Bcfg2/Server/Plugins/Packages/Yum.py | 13 | ||||
-rwxr-xr-x | src/sbin/bcfg2-yum-helper | 32 |
2 files changed, 45 insertions, 0 deletions
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index 7c950a435..7a90f4f2e 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -53,11 +53,13 @@ The Yum Backend import os import re import sys +import time import copy import errno import socket import logging import lxml.etree +from lockfile import FileLock from subprocess import Popen, PIPE import Bcfg2.Server.Plugin # pylint: disable=W0622 @@ -864,6 +866,17 @@ class YumCollection(Collection): if not self.use_yum: return Collection.complete(self, packagelist) + lock = FileLock(os.path.join(self.cachefile, "lock")) + slept = 0 + while lock.is_locked(): + if slept > 30: + self.logger.warning("Packages: Timeout waiting for yum cache " + "to release its lock") + return set(), set() + self.logger.debug("Packages: Yum cache is locked, waiting...") + time.sleep(3) + slept += 3 + if packagelist: try: result = self.call_helper( diff --git a/src/sbin/bcfg2-yum-helper b/src/sbin/bcfg2-yum-helper index 414606abb..1f22c0ff9 100755 --- a/src/sbin/bcfg2-yum-helper +++ b/src/sbin/bcfg2-yum-helper @@ -10,6 +10,8 @@ import sys import yum import logging import Bcfg2.Logger +from Bcfg2.Compat import wraps +from lockfile import FileLock, LockTimeout from optparse import OptionParser try: import json @@ -192,6 +194,27 @@ class DepSolver(YumHelper): return list(packages), list(unknown) +def acquire_lock(func): + """ decorator for CacheManager methods that gets and release a + lock while the method runs """ + @wraps(func) + def inner(self, *args, **kwargs): + self.logger.debug("Acquiring lock at %s" % self.lockfile) + while not self.lock.i_am_locking(): + try: + self.lock.acquire(timeout=60) # wait up to 60 seconds + except LockTimeout: + self.lock.break_lock() + self.lock.acquire() + try: + func(self, *args, **kwargs) + finally: + self.lock.release() + self.logger.debug("Released lock at %s" % self.lockfile) + + return inner + + class CacheManager(YumHelper): """ Yum cache manager. Unlike :class:`DepSolver`, this can write to the yum cache, and so is used for operations that muck with the @@ -199,6 +222,14 @@ class CacheManager(YumHelper): either DepSolver or CacheManager, but for consistency I've put it here.) """ + def __init__(self, cfgfile, verbose=1): + YumHelper.__init__(self, cfgfile, verbose=verbose) + self.lockfile = \ + os.path.join(os.path.dirname(self.yumbase.conf.config_file_path), + "lock") + self.lock = FileLock(self.lockfile) + + @acquire_lock def clean_cache(self): """ clean the yum cache """ for mdtype in ["Headers", "Packages", "Sqlite", "Metadata", @@ -211,6 +242,7 @@ class CacheManager(YumHelper): if not msg.startswith("0 "): self.logger.info(msg) + @acquire_lock def populate_cache(self): """ populate the yum cache """ for repo in self.yumbase.repos.findRepos('*'): |