[Fedora-livecd-list] 2 commits - imgcreate/creator.py imgcreate/kickstart.py imgcreate/yuminst.py

Jeremy Katz katzj at fedoraproject.org
Sat Jun 7 00:42:03 UTC 2008


 imgcreate/creator.py   |   67 +++++++++++++++++++++++++++++++++++++++++++++----
 imgcreate/kickstart.py |    2 -
 imgcreate/yuminst.py   |   10 +++++++
 3 files changed, 73 insertions(+), 6 deletions(-)

New commits:
commit 49e71af9f2e2eb81254fc32c85481031cdc87343
Author: Eric Paris <eparis at redhat.com>
Date:   Fri Jun 6 16:11:54 2008 -0400

    LiveCD - add test for /sbin/lokkit if it is needed for selinux config
    
    This patch adds a new function ayum.installHasFile() which tells if the install
    image is going to contain a given file.  We then use this new function to make
    sure lokkit is going to be present so that we will be able to disable selinux
    inside the image if the kickstart was configured that way.  If we cannot
    accomidate the kickstart setting we error the build.
    
    Signed-off-by: Eric Paris <eparis at redhat.com>

diff --git a/imgcreate/creator.py b/imgcreate/creator.py
index f65f7d4..c9ed60c 100644
--- a/imgcreate/creator.py
+++ b/imgcreate/creator.py
@@ -594,7 +594,14 @@ class ImageCreator(object):
         for pkg in kickstart.get_excluded(self.ks,
                                           self._get_excluded_packages()):
             ayum.deselectPackage(pkg)
-        
+
+    # if the system is running selinux and the kickstart wants it disabled
+    # we need /usr/sbin/lokkit
+    def __can_handle_selinux(self, ayum):
+        file = "/usr/sbin/lokkit"
+        if not kickstart.selinux_enabled(self.ks) and os.path.exists("/selinux/enforce") and not ayum.installHasFile(file):
+            raise CreatorError("Unable to disable SELinux because the installed package set did not include the file %s" % (file))
+
     def install(self, repo_urls = {}):
         """Install packages into the install root.
 
@@ -630,6 +637,9 @@ class ImageCreator(object):
             self.__select_packages(ayum)
             self.__select_groups(ayum)
             self.__deselect_packages(ayum)
+
+            self.__can_handle_selinux(ayum)
+
             ayum.runInstall()
         except yum.Errors.RepoError, e:
             raise CreatorError("Unable to download from repo : %s" % (e,))
diff --git a/imgcreate/yuminst.py b/imgcreate/yuminst.py
index aebb822..dd5b189 100644
--- a/imgcreate/yuminst.py
+++ b/imgcreate/yuminst.py
@@ -139,6 +139,16 @@ class LiveCDYum(yum.YumBase):
         repo.setCallback(TextProgress())
         self.repos.add(repo)
         return repo
+
+    def installHasFile(self, file):
+        provides_pkg = self.whatProvides(file, None, None)
+        dlpkgs = map(lambda x: x.po, filter(lambda txmbr: txmbr.ts_state in ("i", "u"), self.tsInfo.getMembers()))
+        for p in dlpkgs:
+            for q in provides_pkg:
+                if (p == q):
+                    return True
+        return False
+
             
     def runInstall(self):
         os.environ["HOME"] = "/"


commit 05ca79403a42792ac775d93cc6b6d46cd9e57a17
Author: Eric Paris <eparis at redhat.com>
Date:   Fri Jun 6 16:11:53 2008 -0400

    LiveCD - Add fake /selinux so livecd can run in enforcing
    
    This patch adds a /selinux directory to a newly created livecd compose which
    will allow the tools inside the chroot to interoperate with the live system
    successfully.
    
    Signed-off-by: Eric Paris <eparis at redhat.com>

diff --git a/imgcreate/creator.py b/imgcreate/creator.py
index 5d010a1..f65f7d4 100644
--- a/imgcreate/creator.py
+++ b/imgcreate/creator.py
@@ -24,6 +24,7 @@ import tempfile
 import shutil
 import logging
 
+import selinux
 import yum
 import rpm
 
@@ -421,6 +422,52 @@ class ImageCreator(object):
         os.symlink('/proc/self/fd/2', self._instroot + "/dev/stderr")
         os.umask(origumask)
 
+    def __create_selinuxfs(self):
+        # if selinux exists on the host we need to lie to the chroot
+        if os.path.exists("/selinux/enforce"):
+            selinux_dir = self._instroot + "/selinux"
+
+            # enforce=0 tells the chroot selinux is not enforcing
+            # policyvers=999 tell the chroot to make the highest version of policy it can
+            files = (('/enforce', '0'),
+                     ('/policyvers', '999'))
+            for (file, value) in files:
+                fd = os.open(selinux_dir + file, os.O_WRONLY | os.O_TRUNC | os.O_CREAT)
+                os.write(fd, value)
+                os.close(fd)
+
+            # we steal mls from the host system for now, might be best to always set it to 1????
+            files = ("/mls",)
+            for file in files:
+                shutil.copyfile("/selinux" + file, selinux_dir + file)
+
+            # make /load -> /dev/null so chroot policy loads don't hurt anything
+            os.mknod(selinux_dir + "/load", 0666 | stat.S_IFCHR, os.makedev(1, 3))
+
+        # selinux is on in the kickstart, so clean up as best we can to start
+        if kickstart.selinux_enabled(self.ks):
+            # label the fs like it is a root before the bind mounting
+            arglist = ["/sbin/setfiles", "-F", "-r", self._instroot, selinux.selinux_file_context_path(), self._instroot]
+            subprocess.call(arglist, close_fds = True)
+            # these dumb things don't get magically fixed, so make the user generic
+            for f in ("/proc", "/sys", "/selinux"):
+                arglist = ["/usr/bin/chcon", "-u", "system_u", self._instroot + f]
+                subprocess.call(arglist, close_fds = True)
+
+    def __destroy_selinuxfs(self):
+        # if the system was running selinux clean up our lies
+        if os.path.exists("/selinux/enforce"):
+            files = ('/enforce',
+                     '/policyvers',
+                     '/mls',
+                     '/load')
+            for file in files:
+                try:
+                    os.unlink(self._instroot + "/selinux" + file)
+                except OSError:
+                    pass
+
+
     def mount(self, base_on = None, cachedir = None):
         """Setup the target filesystem in preparation for an install.
 
@@ -446,7 +493,7 @@ class ImageCreator(object):
 
         self._mount_instroot(base_on)
 
-        for d in ("/dev/pts", "/etc", "/boot", "/var/log", "/var/cache/yum"):
+        for d in ("/dev/pts", "/etc", "/boot", "/var/log", "/var/cache/yum", "/sys", "/proc", "/selinux"):
             makedirs(self._instroot + d)
 
         cachesrc = cachedir or (self.__builddir + "/yum-cache")
@@ -458,9 +505,7 @@ class ImageCreator(object):
                           (cachesrc, "/var/cache/yum")]:
             self.__bindmounts.append(BindChrootMount(f, self._instroot, dest))
 
-        # /selinux should only be mounted if selinux is enabled (enforcing or permissive)
-        if kickstart.selinux_enabled(self.ks):
-            self.__bindmounts.append(BindChrootMount("/selinux", self._instroot, None))
+        self.__create_selinuxfs()
 
         self._do_bindmounts()
 
@@ -483,6 +528,8 @@ class ImageCreator(object):
         except OSError:
             pass
 
+        self.__destroy_selinuxfs()
+
         self._undo_bindmounts()
 
         self._unmount_instroot()
diff --git a/imgcreate/kickstart.py b/imgcreate/kickstart.py
index c83e795..180cea2 100644
--- a/imgcreate/kickstart.py
+++ b/imgcreate/kickstart.py
@@ -389,7 +389,7 @@ class SelinuxConfig(KickstartConfig):
         if not os.path.exists(self.path("/sbin/restorecon")):
             return
 
-        self.call(["/sbin/restorecon", "-l", "-v", "-r", "/"])
+        self.call(["/sbin/restorecon", "-l", "-v", "-r", "-F", "-e", "/proc", "-e", "/sys", "-e", "/dev", "-e", "/selinux", "/"])
 
     def apply(self, ksselinux):
         if os.path.exists(self.path("/usr/sbin/lokkit")):





More information about the Fedora-livecd-list mailing list