[LORAX 1/6] Changes needed for livecd creation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Brian C. Lane" <bcl@xxxxxxxxxx>

Allow passing of size to create_runtime, add PartitionMount context
to use kpartx to mount partitioned file images. Add resetting the
selinux context on the newly created rootfs.
---
 src/pylorax/imgutils.py    |   64 ++++++++++++++++++++++++++++++++++++++++++++
 src/pylorax/treebuilder.py |   11 ++++++-
 2 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/src/pylorax/imgutils.py b/src/pylorax/imgutils.py
index e7526b0..3dd6460 100644
--- a/src/pylorax/imgutils.py
+++ b/src/pylorax/imgutils.py
@@ -24,6 +24,7 @@ import os, tempfile
 from os.path import join, dirname
 from pylorax.sysutils import cpfile
 from subprocess import *
+import traceback
 
 ######## Functions for making container images (cpio, squashfs) ##########
 
@@ -191,6 +192,69 @@ class Mount(object):
     def __exit__(self, exc_type, exc_value, traceback):
         umount(self.mnt)
 
+class PartitionMount(object):
+    """ Mount a partitioned image file using kpartx """
+    def __init__(self, disk_img, mount_ok=None):
+        """
+        disk_img is the full path to a partitioned disk image
+        mount_ok is a function that is passed the mount point and
+        returns True if it should be mounted.
+        """
+        self.mount_dir = None
+        self.disk_img = disk_img
+        self.mount_ok = mount_ok
+
+        # Default is to mount partition with /etc/passwd
+        if not self.mount_ok:
+            self.mount_ok = lambda mount_dir: os.path.isfile(mount_dir+"/etc/passwd")
+
+        # Example kpartx output
+        # kpartx -p p -v -a /tmp/diskV2DiCW.im
+        # add map loop2p1 (253:2): 0 3481600 linear /dev/loop2 2048
+        # add map loop2p2 (253:3): 0 614400 linear /dev/loop2 3483648
+        cmd = [ "kpartx", "-v", "-p", "p", "-a", self.disk_img ]
+        logger.debug(cmd)
+        kpartx_output = check_output(cmd)
+        logger.debug(kpartx_output)
+
+        # list of (deviceName, sizeInBytes)
+        self.loop_devices = []
+        for line in kpartx_output.splitlines():
+            # add map loop2p3 (253:4): 0 7139328 linear /dev/loop2 528384
+            # 3rd element is size in 512 byte blocks
+            if line.startswith("add map "):
+                fields = line[8:].split()
+                self.loop_devices.append( (fields[0], int(fields[3])*512) )
+
+    def __enter__(self):
+        # Mount the device selected by mount_ok, if possible
+        mount_dir = tempfile.mkdtemp()
+        for dev, size in self.loop_devices:
+            try:
+                mount( "/dev/mapper/"+dev, mnt=mount_dir )
+                if self.mount_ok(mount_dir):
+                    self.mount_dir = mount_dir
+                    self.mount_dev = dev
+                    self.mount_size = size
+                    break
+                umount( mount_dir )
+            except CalledProcessError:
+                logging.debug(traceback.format_exc())
+        if self.mount_dir:
+            logging.info("Partition mounted on {0} size={1}".format(self.mount_dir, self.mount_size))
+        else:
+            logging.debug("Unable to mount anything from {0}".format(self.disk_img))
+            os.rmdir(mount_dir)
+        return self
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        if self.mount_dir:
+            umount( self.mount_dir )
+            os.rmdir(self.mount_dir)
+            self.mount_dir = None
+        call(["kpartx", "-d", self.disk_img])
+
+
 ######## Functions for making filesystem images ##########################
 
 def mkfsimage(fstype, rootdir, outfile, size=None, mkfsargs=[], mountargs="", graft={}):
diff --git a/src/pylorax/treebuilder.py b/src/pylorax/treebuilder.py
index 57cf530..b1b5b0c 100644
--- a/src/pylorax/treebuilder.py
+++ b/src/pylorax/treebuilder.py
@@ -127,13 +127,20 @@ class RuntimeBuilder(object):
             check_call(["depmod", "-a", "-F", ksyms, "-b", root, kver])
             generate_module_info(moddir+kver, outfile=moddir+"module-info")
 
-    def create_runtime(self, outfile="/tmp/squashfs.img", compression="xz", compressargs=[]):
+    def create_runtime(self, outfile="/tmp/squashfs.img", compression="xz", compressargs=[], size=2):
         # make live rootfs image - must be named "LiveOS/rootfs.img" for dracut
         workdir = joinpaths(os.path.dirname(outfile), "runtime-workdir")
-        fssize = 2 * (1024*1024*1024) # 2GB sparse file compresses down to nothin'
+        fssize = size * (1024*1024*1024) # 2GB sparse file compresses down to nothin'
         os.makedirs(joinpaths(workdir, "LiveOS"))
         imgutils.mkext4img(self.vars.root, joinpaths(workdir, "LiveOS/rootfs.img"),
                            label="Anaconda", size=fssize)
+
+        # Reset selinux context on new rootfs
+        with imgutils.LoopDev( joinpaths(workdir, "LiveOS/rootfs.img") ) as loopdev:
+            with imgutils.Mount(loopdev) as mnt:
+                cmd = ["chroot", mnt, "setfiles", "-e", "/proc", "-e", "/sys", "-e", "/dev", "-e", "/selinux", "/etc/selinux/targeted/contexts/files/file_contexts", "/"]
+                check_call(cmd)
+
         # squash the live rootfs and clean up workdir
         imgutils.mksquashfs(workdir, outfile, compression, compressargs)
         remove(workdir)
-- 
1.7.6.4

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list


[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux