summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py
diff options
context:
space:
mode:
authorChris St. Pierre <chris.a.st.pierre@gmail.com>2013-07-15 15:32:21 -0400
committerChris St. Pierre <chris.a.st.pierre@gmail.com>2013-07-15 15:43:07 -0400
commit2217fa6295070f137988006c4bb00d25dfc0cb5e (patch)
treefa79bcf1be203d5719871c3ea9d01b42c5c689b2 /src/lib/Bcfg2/Server/Plugins/Packages/Yum.py
parent156212c6fc294382198840e143f0867e0536601e (diff)
downloadbcfg2-2217fa6295070f137988006c4bb00d25dfc0cb5e.tar.gz
bcfg2-2217fa6295070f137988006c4bb00d25dfc0cb5e.tar.bz2
bcfg2-2217fa6295070f137988006c4bb00d25dfc0cb5e.zip
Read-only yum cache
This makes the yum cache read-only so that bcfg2-yum-helper cannot update the cache on the fly, which should help avoid locking issues with the yum caches that can cause client runs to fail. It also makes the Packages plugin behave more consistently, since use of yum libraries won't cause the cache to be refreshed at random times on the fly, but rather more predictably as with the Apt cache or the yum cache without using yum libraries. Unlike those two cases, though, the caches will not all be downloaded initially, but rather opportunistically as needed. In order for this to work, the Bcfg2 server must not run as root. Root ignores the 'w' permissions bit, so the cache cannot be made read-only.
Diffstat (limited to 'src/lib/Bcfg2/Server/Plugins/Packages/Yum.py')
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/Yum.py60
1 files changed, 43 insertions, 17 deletions
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py
index 4608bcca5..55787681f 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py
@@ -53,6 +53,7 @@ The Yum Backend
import os
import re
import sys
+import stat
import copy
import errno
import socket
@@ -282,13 +283,15 @@ class YumCollection(Collection):
#: for cached yum metadata
self.cachefile = os.path.join(self.cachepath,
"cache-%s" % self.cachekey)
- if not os.path.exists(self.cachefile):
- os.mkdir(self.cachefile)
#: The path to the server-side config file used when
#: resolving packages with the Python yum libraries
self.cfgfile = os.path.join(self.cachefile, "yum.conf")
- self.write_config()
+
+ if not os.path.exists(self.cachefile):
+ self.debug_log("Creating common cache %s" % self.cachefile)
+ os.mkdir(self.cachefile)
+ self.setup_data()
else:
self.cachefile = None
@@ -924,6 +927,28 @@ class YumCollection(Collection):
"output: %s" % err)
raise
+ def _set_cache_writeable(self, writeable):
+ """ Set the writeability of the yum cache.
+
+ :param writeable: If True, the cache will be made writeable.
+ If False, the cache will be made read-only.
+ :type writeable: bool
+ """
+ fmode = stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH
+ if writeable:
+ self.debug_log("Packages: Making cache %s writeable" %
+ self.cachefile)
+ fmode |= stat.S_IWUSR
+ else:
+ self.debug_log("Packages: Making cache %s read-only" %
+ self.cachefile)
+ dmode = fmode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
+ for root, dirs, files in os.walk(self.cachefile):
+ for dname in dirs:
+ os.chmod(os.path.join(root, dname), dmode)
+ for fname in files:
+ os.chmod(os.path.join(root, fname), fmode)
+
def setup_data(self, force_update=False):
""" Do any collection-level data setup tasks. This is called
when sources are loaded or reloaded by
@@ -931,11 +956,11 @@ class YumCollection(Collection):
If the builtin yum parsers are in use, this defers to
:func:`Bcfg2.Server.Plugins.Packages.Collection.Collection.setup_data`.
- If using the yum Python libraries, this cleans up cached yum
- metadata, regenerates the server-side yum config (in order to
- catch any new sources that have been added to this server),
- and then cleans up cached yum metadata again, in case the new
- config has any preexisting cache.
+ If using the yum Python libraries, this makes the cache
+ writeable, cleans up cached yum metadata, regenerates the
+ server-side yum config (in order to catch any new sources that
+ have been added to this server), regenerates the yum cache,
+ and then sets the cache back to read-only.
:param force_update: Ignore all local cache and setup data
from its original upstream sources (i.e.,
@@ -945,24 +970,25 @@ class YumCollection(Collection):
if not self.use_yum:
return Collection.setup_data(self, force_update)
+ self._set_cache_writeable(True)
if force_update:
- # we call this twice: one to clean up data from the old
- # config, and once to clean up data from the new config
+ # clean up data from the old config
try:
self.call_helper("clean")
except ValueError:
# error reported by call_helper
pass
- os.unlink(self.cfgfile)
+ if os.path.exists(self.cfgfile):
+ os.unlink(self.cfgfile)
self.write_config()
- if force_update:
- try:
- self.call_helper("clean")
- except ValueError:
- # error reported by call_helper
- pass
+ try:
+ self.call_helper("makecache")
+ except ValueError:
+ # error reported by call_helper
+ pass
+ self._set_cache_writeable(False)
class YumSource(Source):