summaryrefslogtreecommitdiffstats
path: root/py/mock/plugins/root_cache.py
diff options
context:
space:
mode:
authorMichael E Brown <mebrown@michaels-house.net>2007-11-30 11:51:25 -0600
committerMichael E Brown <mebrown@michaels-house.net>2007-11-30 11:51:25 -0600
commit97f06be255f9a20613c66510e05f68372af7215f (patch)
tree2d57f70b6889bd351f3efac9f32ae806faa53aee /py/mock/plugins/root_cache.py
parent96dd05c47ed25102fe92a1c7810d12716083e05e (diff)
downloadmock-97f06be255f9a20613c66510e05f68372af7215f.tar.gz
mock-97f06be255f9a20613c66510e05f68372af7215f.tar.xz
mock-97f06be255f9a20613c66510e05f68372af7215f.zip
move things around so that we can run mock.py from the build tree instead of having to install it.
Diffstat (limited to 'py/mock/plugins/root_cache.py')
-rw-r--r--py/mock/plugins/root_cache.py93
1 files changed, 93 insertions, 0 deletions
diff --git a/py/mock/plugins/root_cache.py b/py/mock/plugins/root_cache.py
new file mode 100644
index 0000000..8ed2492
--- /dev/null
+++ b/py/mock/plugins/root_cache.py
@@ -0,0 +1,93 @@
+# vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=python:textwidth=0:
+# License: GPL2 or later see COPYING
+# Written by Michael Brown
+# Copyright (C) 2007 Michael E Brown <mebrown@michaels-house.net>
+
+# python library imports
+import fcntl
+import logging
+import os
+import time
+
+# our imports
+from mock.trace_decorator import traceLog
+import mock.util
+
+# set up logging, module options
+moduleLog = logging.getLogger("mock")
+requires_api_version = "1.0"
+
+# plugin entry point
+def init(rootObj, conf):
+ rootCache = RootCache(rootObj, conf)
+
+# classes
+class RootCache(object):
+ """caches root environment in a tarball"""
+ @traceLog(moduleLog)
+ def __init__(self, rootObj, conf):
+ self.rootObj = rootObj
+ self.root_cache_opts = conf
+ self.rootSharedCachePath = self.root_cache_opts['dir'] % self.root_cache_opts
+ self.rootCacheFile = os.path.join(self.rootSharedCachePath, "cache.tar.gz")
+ self.rootCacheLock = None
+ self.state = rootObj.state
+ self.rootdir = rootObj.rootdir
+ rootObj.rootCacheObj = self
+ rootObj.addHook("preinit", self._rootCachePreInitHook)
+ rootObj.addHook("postinit", self._rootCachePostInitHook)
+
+ # =============
+ # 'Private' API
+ # =============
+ @traceLog(moduleLog)
+ def _rootCacheLock(self, shared=1):
+ lockType = fcntl.LOCK_EX
+ if shared: lockType = fcntl.LOCK_SH
+ try:
+ fcntl.lockf(self.rootCacheLock.fileno(), lockType | fcntl.LOCK_NB)
+ except IOError, e:
+ oldState = self.state()
+ self.state("Waiting for rootcache lock")
+ fcntl.lockf(self.rootCacheLock.fileno(), lockType)
+ self.state(oldState)
+
+ @traceLog(moduleLog)
+ def _rootCacheUnlock(self):
+ fcntl.lockf(self.rootCacheLock.fileno(), fcntl.LOCK_UN)
+
+ @traceLog(moduleLog)
+ def _rootCachePreInitHook(self):
+ moduleLog.info("enabled root cache")
+ mock.util.mkdirIfAbsent(self.rootSharedCachePath)
+ # lock so others dont accidentally use root cache while we operate on it.
+ if self.rootCacheLock is None:
+ self.rootCacheLock = open(os.path.join(self.rootSharedCachePath, "rootcache.lock"), "a+")
+
+ # check cache age:
+ try:
+ statinfo = os.stat(self.rootCacheFile)
+ file_age_days = (time.time() - statinfo.st_ctime) / (60 * 60 * 24)
+ if file_age_days > self.root_cache_opts['max_age_days']:
+ os.unlink(self.rootCacheFile)
+ except OSError:
+ pass
+
+ # optimization: dont unpack root cache if chroot was not cleaned
+ if os.path.exists(self.rootCacheFile) and self.rootObj.chrootWasCleaned:
+ self.state("unpacking cache")
+ self._rootCacheLock()
+ mock.util.do("tar xzf %s -C %s" % (self.rootCacheFile, self.rootdir))
+ self._rootCacheUnlock()
+ self.chroot_setup_cmd = "update"
+ self.rootObj.chrootWasCleaned = False
+
+ @traceLog(moduleLog)
+ def _rootCachePostInitHook(self):
+ # never rebuild cache unless it was a clean build.
+ if self.rootObj.chrootWasCleaned:
+ self.state("creating cache")
+ self._rootCacheLock(shared=0)
+ mock.util.do("tar czf %s -C %s ." % (self.rootCacheFile, self.rootdir))
+ self._rootCacheUnlock()
+