summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Vcelak <jvcelak@redhat.com>2010-07-30 16:14:55 -0500
committerClark Williams <williams@redhat.com>2010-07-30 16:14:55 -0500
commit0aac2d3d8804271eaca33f93650b04f1bd8b249c (patch)
tree475c86cc11cbd22d138687fe3136d1c8a6871a9c
parentca78692e0f1b3a0401db6f8e64a9bdd282229568 (diff)
downloadmock-0aac2d3d8804271eaca33f93650b04f1bd8b249c.tar.gz
mock-0aac2d3d8804271eaca33f93650b04f1bd8b249c.tar.xz
mock-0aac2d3d8804271eaca33f93650b04f1bd8b249c.zip
add selinux plugin
This patch adds an selinux plugin that sets up an environment with selinux turned *off* in the build chroot. How does this work? From the author's description: It is done the same as the patch sent by Thomas Liu in bz 614440 does. Actually, this proceeding was suggested by Dan Walsh in bz 573111. 1.) Fake /proc/filesystems is created in conf["cachedir"]. It includes the same content as the same file in host environment, except line with selinuxfs. This file is bind mounted into build environment. 2.) Option '--setopt=tsflags=nocontext' is added to yum commands. This is done by wrapping mock.util.do with _selinuxDoYum in "preyum" hook. This function just adds the option and passes the command to original mock.util.do function. The wrapping is removed in "postyum" hook. I didn't find cleaner method, without modifying main code. Signed-off-by: Clark Williams <williams@redhat.com>
-rw-r--r--Makefile.am4
-rwxr-xr-xpy/mock.py4
-rw-r--r--py/mock/plugins/selinux.py97
3 files changed, 103 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index ca05ec6..b9ef2fa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -47,7 +47,9 @@ plugins_PYTHON = \
py/mock/plugins/ccache.py \
py/mock/plugins/root_cache.py \
py/mock/plugins/tmpfs.py \
- py/mock/plugins/yum_cache.py
+ py/mock/plugins/yum_cache.py \
+ py/mock/plugins/selinux.py
+
pkgpython_PYTHON = \
py/mock/__init__.py \
diff --git a/py/mock.py b/py/mock.py
index dd002de..a0e585d 100755
--- a/py/mock.py
+++ b/py/mock.py
@@ -244,7 +244,7 @@ def setup_default_config_opts(config_opts, unprivUid):
# root_cache next.
# after that, any plugins that must create dirs (yum_cache)
# any plugins without preinit hooks should be last.
- config_opts['plugins'] = ('tmpfs', 'root_cache', 'yum_cache', 'bind_mount', 'ccache')
+ config_opts['plugins'] = ('tmpfs', 'root_cache', 'yum_cache', 'bind_mount', 'ccache', 'selinux')
config_opts['plugin_dir'] = os.path.join(PKGPYTHONDIR, "plugins")
config_opts['plugin_conf'] = {
'ccache_enable': True,
@@ -273,6 +273,8 @@ def setup_default_config_opts(config_opts, unprivUid):
'tmpfs_opts': {
'required_ram_mb': 900,
'max_fs_size': None},
+ 'selinux_enable': True,
+ 'selinux_opts': {},
}
# dependent on guest OS
diff --git a/py/mock/plugins/selinux.py b/py/mock/plugins/selinux.py
new file mode 100644
index 0000000..6d15a94
--- /dev/null
+++ b/py/mock/plugins/selinux.py
@@ -0,0 +1,97 @@
+# vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=python:textwidth=0:
+# License: GPL2 or later see COPYING
+# Written by Jan Vcelak
+# Copyright (C) 2010 Jan Vcelak <jvcelak@redhat.com>
+
+# python library imports
+import os
+import sys
+
+# our imports
+from mock.trace_decorator import decorate, traceLog, getLog
+import mock.util
+
+requires_api_version = "1.0"
+
+# plugin entry point
+decorate(traceLog())
+def init(rootObj, conf):
+ if mock.util.selinuxEnabled():
+ getLog().info("selinux enabled")
+ SELinux(rootObj, conf)
+ else:
+ getLog().info("selinux disabled")
+
+# classes
+class SELinux(object):
+ """On SELinux enabled box, this plugin will pretend, that SELinux is disabled in build environment.
+
+ - fake /proc/filesystems is mounted into build enviroment, excluding selinuxfs
+ - option '--setopt=tsflags=nocontext' is appended to each 'yum' command
+ """
+
+ decorate(traceLog())
+ def __init__(self, rootObj, conf):
+ self.rootObj = rootObj
+ self.conf = conf
+
+ self.filesystems = os.path.join(conf["cachedir"], "filesystems")
+ self.chrootFilesystems = rootObj.makeChrootPath("/proc/filesystems")
+
+ rootObj.addHook("preinit", self._selinuxPreInitHook)
+ rootObj.addHook("postbuild", self._selinuxPostBuildHook)
+ rootObj.addHook("initfailed", self._selinuxPostBuildHook)
+ if self._selinuxYumIsSetoptSupported():
+ rootObj.addHook("preyum", self._selinuxPreYumHook)
+ rootObj.addHook("postyum", self._selinuxPostYumHook)
+ else:
+ getLog().warn("selinux: 'yum' does not support '--setopt' option")
+
+ decorate(traceLog())
+ def _selinuxPreInitHook(self):
+ host = open("/proc/filesystems")
+ build = open(self.filesystems, "w")
+
+ for line in host:
+ if not "selinuxfs" in line:
+ build.write(line)
+
+ build.close()
+ host.close()
+
+ self.rootObj.mountCmds.append("mount -n --bind %s %s" % (self.filesystems, self.chrootFilesystems))
+ self.rootObj.umountCmds.insert(0, "umount -n %s" % self.chrootFilesystems)
+
+ decorate(traceLog())
+ def _selinuxPostBuildHook(self):
+ os.unlink(self.filesystems)
+
+ decorate(traceLog())
+ def _selinuxPreYumHook(self):
+ self._originalUtilDo = mock.util.do
+ mock.util.do = self._selinuxDoYum
+
+ decorate(traceLog())
+ def _selinuxPostYumHook(self):
+ mock.util.do = self._originalUtilDo
+
+ decorate(traceLog())
+ def _selinuxDoYum(self, command, *args, **kargs):
+ option = "--setopt=tsflags=nocontexts"
+
+ if type(command) is list:
+ command.append(option)
+ elif type(command) is str:
+ command += " %s" % option
+
+ return self._originalUtilDo(command, *args, **kargs)
+
+ decorate(traceLog())
+ def _selinuxYumIsSetoptSupported(self):
+ # ugly hack: discover, whether yum supports --setopt option
+ sys.path.insert(0, '/usr/share/yum-cli')
+ import cli
+ supported = hasattr(cli.YumBaseCli, "_parseSetOpts")
+ sys.path.pop(0)
+
+ return supported