imgcreate/creator.py | 17 +- imgcreate/fs.py | 351 ++++++++++++++++++++++++++++++++++++------------- imgcreate/kickstart.py | 3 imgcreate/live.py | 6 4 files changed, 278 insertions(+), 99 deletions(-)
New commits: commit 5a3a91fe44795fb0d5c1f6215081b214d0af3f5b Merge: 2a57a06... 5279213... Author: Jeremy Katz <[EMAIL PROTECTED]> Date: Tue Aug 5 20:25:23 2008 -0400 Merge branch 'refactor-mount' diff --cc imgcreate/creator.py index e63e96d,5fbf554..d9fa711 --- a/imgcreate/creator.py +++ b/imgcreate/creator.py @@@ -905,14 -904,14 +909,13 @@@ class LoopImageCreator(ImageCreator) self.__imgdir = self._mkdtemp() if not base_on is None: - self.__base_on(base_on) - shutil.copyfile(base_on, self._image) + self._base_on(base_on) - self.__instloop = SparseExtLoopbackMount(self._image, - self._instroot, - self.__image_size, - self.__fstype, - self.__blocksize, - self.fslabel) + self.__instloop = ExtDiskMount(SparseLoopbackDisk(self._image, self.__image_size), + self._instroot, + self.__fstype, + self.__blocksize, + self.fslabel) try: self.__instloop.mount() diff --cc imgcreate/live.py index 49d524b,abea730..f98f76c --- a/imgcreate/live.py +++ b/imgcreate/live.py @@@ -129,9 -129,9 +129,9 @@@ class LiveImageCreatorBase(LoopImageCre # # Actual implementation # - def __base_on(self, base_on): + def _base_on(self, base_on): """helper function to extract ext3 file system from a live CD ISO""" - isoloop = LoopbackMount(base_on, self._mkdtemp()) + isoloop = Mount(LoopbackDisk(base_on), self._mkdtemp()) try: isoloop.mount() commit 5279213df3104c32b3cb08afc7e9698dceb1704d Author: David Huff <[EMAIL PROTECTED]> Date: Tue Jul 22 17:36:52 2008 -0400 Separate out generation of non-disk mounts from other things for /etc/fstab diff --git a/imgcreate/creator.py b/imgcreate/creator.py index 64898c5..5fbf554 100644 --- a/imgcreate/creator.py +++ b/imgcreate/creator.py @@ -209,7 +209,11 @@ class ImageCreator(object): """ s = "/dev/root / %s defaults,noatime 0 0\n" %(self._fstype) - s += "devpts /dev/pts devpts gid=5,mode=620 0 0\n" + s += self._get_fstab_special() + return s + + def _get_fstab_special(self): + s = "devpts /dev/pts devpts gid=5,mode=620 0 0\n" s += "tmpfs /dev/shm tmpfs defaults 0 0\n" s += "proc /proc proc defaults 0 0\n" s += "sysfs /sys sysfs defaults 0 0\n" commit 1f20b4ded9e18257de787c71b28e147f592c09be Author: David Huff <[EMAIL PROTECTED]> Date: Tue Jul 22 17:36:06 2008 -0400 Switch internal code to use new api diff --git a/imgcreate/creator.py b/imgcreate/creator.py index e61f034..64898c5 100644 --- a/imgcreate/creator.py +++ b/imgcreate/creator.py @@ -903,12 +903,11 @@ class LoopImageCreator(ImageCreator): self.__base_on(base_on) shutil.copyfile(base_on, self._image) - self.__instloop = SparseExtLoopbackMount(self._image, - self._instroot, - self.__image_size, - self.__fstype, - self.__blocksize, - self.fslabel) + self.__instloop = ExtDiskMount(SparseLoopbackDisk(self._image, self.__image_size), + self._instroot, + self.__fstype, + self.__blocksize, + self.fslabel) try: self.__instloop.mount() diff --git a/imgcreate/live.py b/imgcreate/live.py index e0bac09..abea730 100644 --- a/imgcreate/live.py +++ b/imgcreate/live.py @@ -131,7 +131,7 @@ class LiveImageCreatorBase(LoopImageCreator): # def __base_on(self, base_on): """helper function to extract ext3 file system from a live CD ISO""" - isoloop = LoopbackMount(base_on, self._mkdtemp()) + isoloop = Mount(LoopbackDisk(base_on), self._mkdtemp()) try: isoloop.mount() @@ -145,10 +145,10 @@ class LiveImageCreatorBase(LoopImageCreator): else: squashimg = isoloop.mountdir + "/LiveOS/squashfs.img" - squashloop = LoopbackMount(squashimg, self._mkdtemp(), "squashfs") + squashloop = Mount(LoopbackDisk(squashimg), self._mkdtemp(), "squashfs") try: - if not os.path.exists(squashloop.lofile): + if not squashloop.disk.exists(): raise CreatorError("'%s' is not a valid live CD ISO : " "squashfs.img doesn't exist" % base_on) commit 7024f2cc0041d8fd038844c789d869875e4977af Author: David Huff <[EMAIL PROTECTED]> Date: Mon Jul 28 14:22:00 2008 -0400 Added compat shims in fs.py for old api Added a compat layer for backwards compatibility. These compat classes internally create the new Disk objects, switching the old api (LoopbackMount, SparseLoopbackMount, SparseExtLoopbackMount) types to the new Disk and Mount classes diff --git a/imgcreate/fs.py b/imgcreate/fs.py index 0aca98d..4d8f87a 100644 --- a/imgcreate/fs.py +++ b/imgcreate/fs.py @@ -88,32 +88,16 @@ class BindChrootMount: self.mounted = False class LoopbackMount: + """LoopbackMount compatibility layer for old API""" def __init__(self, lofile, mountdir, fstype = None): - self.lofile = lofile - self.mountdir = mountdir - self.fstype = fstype - - self.mounted = False + self.diskmount = DiskMount(LoopbackDisk(lofile,size = 0),mountdir,fstype,rmmountdir = True) self.losetup = False - self.rmdir = False - self.loopdev = None - + def cleanup(self): - self.unmount() - self.lounsetup() + self.diskmount.cleanup() def unmount(self): - if self.mounted: - rc = subprocess.call(["/bin/umount", self.mountdir]) - if rc == 0: - self.mounted = False - - if self.rmdir and not self.mounted: - try: - os.rmdir(self.mountdir) - except OSError, e: - pass - self.rmdir = False + self.diskmount.unmount() def lounsetup(self): if self.losetup: @@ -143,152 +127,52 @@ class LoopbackMount: self.losetup = True def mount(self): - if self.mounted: - return - - self.loopsetup() - - if not os.path.isdir(self.mountdir): - os.makedirs(self.mountdir) - self.rmdir = True - - args = [ "/bin/mount", self.loopdev, self.mountdir ] - if self.fstype: - args.extend(["-t", self.fstype]) - - rc = subprocess.call(args) - if rc != 0: - raise MountError("Failed to mount '%s' to '%s'" % - (self.loopdev, self.mountdir)) - - self.mounted = True + self.diskmount.mount() class SparseLoopbackMount(LoopbackMount): + """SparseLoopbackMount compatibility layer for old API""" def __init__(self, lofile, mountdir, size, fstype = None): - LoopbackMount.__init__(self, lofile, mountdir, fstype) - self.size = size + self.diskmount = DiskMount(SparseLoopbackDisk(lofile,size),mountdir,fstype,rmmountdir = True) def expand(self, create = False, size = None): - flags = os.O_WRONLY - if create: - flags |= os.O_CREAT - makedirs(os.path.dirname(self.lofile)) - - if size is None: - size = self.size - - fd = os.open(self.lofile, flags) - - os.lseek(fd, size, 0) - os.write(fd, '\x00') - os.close(fd) + self.diskmount.disk.expand(create, size) def truncate(self, size = None): - if size is None: - size = self.size - fd = os.open(self.lofile, os.O_WRONLY) - os.ftruncate(fd, size) - os.close(fd) + self.diskmount.disk.truncate(size) def create(self): - self.expand(create = True) + self.diskmount.disk.create() class SparseExtLoopbackMount(SparseLoopbackMount): + """SparseExtLoopbackMount compatibility layer for old API""" def __init__(self, lofile, mountdir, size, fstype, blocksize, fslabel): - SparseLoopbackMount.__init__(self, lofile, mountdir, size, fstype) - self.blocksize = blocksize - self.fslabel = fslabel + self.diskmount = ExtDiskMount(SparseLoopbackDisk(lofile,size), mountdir, fstype, blocksize, fslabel, rmmountdir = True) + def __format_filesystem(self): - rc = subprocess.call(["/sbin/mkfs." + self.fstype, - "-F", "-L", self.fslabel, - "-m", "1", "-b", str(self.blocksize), - self.lofile, - str(self.size / self.blocksize)]) - if rc != 0: - raise MountError("Error creating %s filesystem" % (self.fstype,)) - subprocess.call(["/sbin/tune2fs", "-c0", "-i0", "-Odir_index", - "-ouser_xattr,acl", self.lofile]) + self.diskmount.__format_filesystem() def create(self): - SparseLoopbackMount.create(self) - self.__format_filesystem() + self.diskmount.disk.create() def resize(self, size = None): - current_size = os.stat(self.lofile)[stat.ST_SIZE] - - if size is None: - size = self.size - - if size == current_size: - return - - if size > current_size: - self.expand(size) - - self.__fsck() - - resize2fs(self.lofile, size) - - if size < current_size: - self.truncate(size) - return size + self.diskmount.__resize_filesystem(size) def mount(self): - if not os.path.isfile(self.lofile): - self.create() - else: - self.resize() - return SparseLoopbackMount.mount(self) - + self.diskmount.mount() + def __fsck(self): - subprocess.call(["/sbin/e2fsck", "-f", "-y", self.lofile]) + self.extdiskmount.__fsck() def __get_size_from_filesystem(self): - def parse_field(output, field): - for line in output.split("\n"): - if line.startswith(field + ":"): - return line[len(field) + 1:].strip() - - raise KeyError("Failed to find field '%s' in output" % field) - - dev_null = os.open("/dev/null", os.O_WRONLY) - try: - out = subprocess.Popen(['/sbin/dumpe2fs', '-h', self.lofile], - stdout = subprocess.PIPE, - stderr = dev_null).communicate()[0] - finally: - os.close(dev_null) - - return int(parse_field(out, "Block count")) * self.blocksize - + self.diskmount.__get_size_from_filesystem() + def __resize_to_minimal(self): - self.__fsck() - - # - # Use a binary search to find the minimal size - # we can resize the image to - # - bot = 0 - top = self.__get_size_from_filesystem() - while top != (bot + 1): - t = bot + ((top - bot) / 2) - - if not resize2fs(self.lofile, t): - top = t - else: - bot = t - return top - + self.diskmount.__resize_to_minimal() + def resparse(self, size = None): - self.cleanup() + return self.diskmount.resparse(size) - minsize = self.__resize_to_minimal() - - self.truncate(minsize) - self.resize(size) - return minsize - class Disk: """Generic base object for a disk commit 8d6b5166013b766f0fca163a52ddd0801568a557 Author: Jeremy Katz <[EMAIL PROTECTED]> Date: Tue Jul 22 17:15:29 2008 -0400 Clean up pydoc to be with the actual objects diff --git a/imgcreate/fs.py b/imgcreate/fs.py index 11348fa..0aca98d 100644 --- a/imgcreate/fs.py +++ b/imgcreate/fs.py @@ -290,28 +290,11 @@ class SparseExtLoopbackMount(SparseLoopbackMount): return minsize class Disk: - """ - With the new disk API the image being produced can be partitioned into - multiple chunks, with many filesystems. Furthermore, not all of them - require loopback mounts, as the partitions themselves are already - visible via /dev/mapper/ - - There are now classes which deal with accessing / creating disks: - - Disk - generic base for disks - RawDisk - a disk backed by a block device - LoopbackDisk - a disk backed by a file - SparseLoopbackDisk - a disk backed by a sparse file + """Generic base object for a disk The 'create' method must make the disk visible as a block device - eg by calling losetup. For RawDisk, this is obviously a no-op. The 'cleanup' method must undo the 'create' operation. - - There are then classes which deal with mounting things: - - Mount - generic base for mounts - DiskMount - able to mount a Disk object - ExtDiskMount - able to format/resize ext3 filesystems when mounting """ def __init__(self, size, device = None): self._device = device @@ -335,6 +318,9 @@ class Disk: class RawDisk(Disk): + """A Disk backed by a block device. + Note that create() is a no-op. + """ def __init__(self, size, device): Disk.__init__(self, size, device) @@ -345,6 +331,7 @@ class RawDisk(Disk): return True class LoopbackDisk(Disk): + """A Disk backed by a file via the loop module.""" def __init__(self, lofile, size): Disk.__init__(self, size) self.lofile = lofile @@ -386,6 +373,7 @@ class LoopbackDisk(Disk): class SparseLoopbackDisk(LoopbackDisk): + """A Disk backed by a sparse file via the loop module.""" def __init__(self, lofile, size): LoopbackDisk.__init__(self, lofile, size) @@ -419,6 +407,7 @@ class SparseLoopbackDisk(LoopbackDisk): LoopbackDisk.create(self) class Mount: + """A generic base class to deal with mounting things.""" def __init__(self, mountdir): self.mountdir = mountdir @@ -432,6 +421,7 @@ class Mount: pass class DiskMount(Mount): + """A Mount object that handles mounting of a Disk.""" def __init__(self, disk, mountdir, fstype = None, rmmountdir = True): Mount.__init__(self, mountdir) @@ -489,6 +479,7 @@ class DiskMount(Mount): self.mounted = True class ExtDiskMount(DiskMount): + """A DiskMount object that is able to format/resize ext[23] filesystems.""" def __init__(self, disk, mountdir, fstype, blocksize, fslabel, rmmountdir=True): DiskMount.__init__(self, disk, mountdir, fstype, rmmountdir) self.blocksize = blocksize commit 129083062fb7b21a49e5f84196d673fa1c37a5bc Author: David Huff <[EMAIL PROTECTED]> Date: Mon Jul 21 17:26:55 2008 -0400 Re-factor imgcreate/fs.py module Most of the change here involves re-factoring the imgcreate/fs.py module to separate the difference between a disk and a mount. So this patch separates the roles. There are now classes which deal with accessing / creating disks and classes which deal with mounting things. Also fixed comments to use the standard pydoc """ format. Based on a patch by Daniel Berrange <[EMAIL PROTECTED]> diff --git a/imgcreate/fs.py b/imgcreate/fs.py index 98c0db4..11348fa 100644 --- a/imgcreate/fs.py +++ b/imgcreate/fs.py @@ -24,6 +24,7 @@ import stat import subprocess import random import string +import logging from imgcreate.errors import * @@ -288,6 +289,303 @@ class SparseExtLoopbackMount(SparseLoopbackMount): self.resize(size) return minsize +class Disk: + """ + With the new disk API the image being produced can be partitioned into + multiple chunks, with many filesystems. Furthermore, not all of them + require loopback mounts, as the partitions themselves are already + visible via /dev/mapper/ + + There are now classes which deal with accessing / creating disks: + + Disk - generic base for disks + RawDisk - a disk backed by a block device + LoopbackDisk - a disk backed by a file + SparseLoopbackDisk - a disk backed by a sparse file + + The 'create' method must make the disk visible as a block device - eg + by calling losetup. For RawDisk, this is obviously a no-op. The 'cleanup' + method must undo the 'create' operation. + + There are then classes which deal with mounting things: + + Mount - generic base for mounts + DiskMount - able to mount a Disk object + ExtDiskMount - able to format/resize ext3 filesystems when mounting + """ + def __init__(self, size, device = None): + self._device = device + self._size = size + + def create(self): + pass + + def cleanup(self): + pass + + def get_device(self): + return self._device + def set_device(self, path): + self._device = path + device = property(get_device, set_device) + + def get_size(self): + return self._size + size = property(get_size) + + +class RawDisk(Disk): + def __init__(self, size, device): + Disk.__init__(self, size, device) + + def fixed(self): + return True + + def exists(self): + return True + +class LoopbackDisk(Disk): + def __init__(self, lofile, size): + Disk.__init__(self, size) + self.lofile = lofile + + def fixed(self): + return False + + def exists(self): + return os.path.exists(self.lofile) + + def create(self): + if self.device is not None: + return + + losetupProc = subprocess.Popen(["/sbin/losetup", "-f"], + stdout=subprocess.PIPE) + losetupOutput = losetupProc.communicate()[0] + + if losetupProc.returncode: + raise MountError("Failed to allocate loop device for '%s'" % + self.lofile) + + device = losetupOutput.split()[0] + + logging.debug("Losetup add %s mapping to %s" % (device, self.lofile)) + rc = subprocess.call(["/sbin/losetup", device, self.lofile]) + if rc != 0: + raise MountError("Failed to allocate loop device for '%s'" % + self.lofile) + self.device = device + + def cleanup(self): + if self.device is None: + return + logging.debug("Losetup remove %s" % self.device) + rc = subprocess.call(["/sbin/losetup", "-d", self.device]) + self.device = None + + + +class SparseLoopbackDisk(LoopbackDisk): + def __init__(self, lofile, size): + LoopbackDisk.__init__(self, lofile, size) + + def expand(self, create = False, size = None): + flags = os.O_WRONLY + if create: + flags |= os.O_CREAT + makedirs(os.path.dirname(self.lofile)) + + if size is None: + size = self.size + + logging.debug("Extending sparse file %s to %d" % (self.lofile, size)) + fd = os.open(self.lofile, flags) + + os.lseek(fd, size, 0) + os.write(fd, '\x00') + os.close(fd) + + def truncate(self, size = None): + if size is None: + size = self.size + + logging.debug("Truncating sparse file %s to %d" % (self.lofile, size)) + fd = os.open(self.lofile, os.O_WRONLY) + os.ftruncate(fd, size) + os.close(fd) + + def create(self): + self.expand(create = True) + LoopbackDisk.create(self) + +class Mount: + def __init__(self, mountdir): + self.mountdir = mountdir + + def cleanup(self): + self.unmount() + + def mount(self): + pass + + def unmount(self): + pass + +class DiskMount(Mount): + def __init__(self, disk, mountdir, fstype = None, rmmountdir = True): + Mount.__init__(self, mountdir) + + self.disk = disk + self.fstype = fstype + self.rmmountdir = rmmountdir + + self.mounted = False + self.rmdir = False + + def cleanup(self): + Mount.cleanup(self) + self.disk.cleanup() + + def unmount(self): + if self.mounted: + logging.debug("Unmounting directory %s" % self.mountdir) + rc = subprocess.call(["/bin/umount", self.mountdir]) + if rc == 0: + self.mounted = False + + if self.rmdir and not self.mounted: + try: + os.rmdir(self.mountdir) + except OSError, e: + pass + self.rmdir = False + + + def __create(self): + self.disk.create() + + + def mount(self): + if self.mounted: + return + + if not os.path.isdir(self.mountdir): + logging.debug("Creating mount point %s" % self.mountdir) + os.makedirs(self.mountdir) + self.rmdir = self.rmmountdir + + self.__create() + + logging.debug("Mounting %s at %s" % (self.disk.device, self.mountdir)) + args = [ "/bin/mount", self.disk.device, self.mountdir ] + if self.fstype: + args.extend(["-t", self.fstype]) + + rc = subprocess.call(args) + if rc != 0: + raise MountError("Failed to mount '%s' to '%s'" % + (self.disk.device, self.mountdir)) + + self.mounted = True + +class ExtDiskMount(DiskMount): + def __init__(self, disk, mountdir, fstype, blocksize, fslabel, rmmountdir=True): + DiskMount.__init__(self, disk, mountdir, fstype, rmmountdir) + self.blocksize = blocksize + self.fslabel = fslabel + + def __format_filesystem(self): + logging.debug("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) + rc = subprocess.call(["/sbin/mkfs." + self.fstype, + "-F", "-L", self.fslabel, + "-m", "1", "-b", str(self.blocksize), + self.disk.device]) + # str(self.disk.size / self.blocksize)]) + if rc != 0: + raise MountError("Error creating %s filesystem" % (self.fstype,)) + logging.debug("Tuning filesystem on %s" % self.disk.device) + subprocess.call(["/sbin/tune2fs", "-c0", "-i0", "-Odir_index", + "-ouser_xattr,acl", self.disk.device]) + + def __resize_filesystem(self, size = None): + current_size = os.stat(self.disk.lofile)[stat.ST_SIZE] + + if size is None: + size = self.size + + if size == current_size: + return + + if size > current_size: + self.expand(size) + + self.__fsck() + + resize2fs(self.disk.lofile, size) + return size + + def __create(self): + resize = False + if not self.disk.fixed() and self.disk.exists(): + resize = True + + self.disk.create() + + if resize: + self.__resize_filesystem() + else: + self.__format_filesystem() + + def mount(self): + self.__create() + DiskMount.mount(self) + + def __fsck(self): + logging.debug("Checking filesystem %s" % self.disk.lofile) + subprocess.call(["/sbin/e2fsck", "-f", "-y", self.disk.lofile]) + + def __get_size_from_filesystem(self): + def parse_field(output, field): + for line in output.split("\n"): + if line.startswith(field + ":"): + return line[len(field) + 1:].strip() + + raise KeyError("Failed to find field '%s' in output" % field) + + dev_null = os.open("/dev/null", os.O_WRONLY) + try: + out = subprocess.Popen(['/sbin/dumpe2fs', '-h', self.disk.lofile], + stdout = subprocess.PIPE, + stderr = dev_null).communicate()[0] + finally: + os.close(dev_null) + + return int(parse_field(out, "Block count")) * self.blocksize + + def __resize_to_minimal(self): + self.__fsck() + + # + # Use a binary search to find the minimal size + # we can resize the image to + # + bot = 0 + top = self.__get_size_from_filesystem() + while top != (bot + 1): + t = bot + ((top - bot) / 2) + + if not resize2fs(self.disk.lofile, t): + top = t + else: + bot = t + return top + + def resparse(self, size = None): + self.cleanup() + minsize = self.__resize_to_minimal() + self.disk.truncate(minsize) + return minsize + class DeviceMapperSnapshot(object): def __init__(self, imgloop, cowloop): self.imgloop = imgloop @@ -306,8 +604,8 @@ class DeviceMapperSnapshot(object): if self.__created: return - self.imgloop.loopsetup() - self.cowloop.loopsetup() + self.imgloop.create() + self.cowloop.create() self.__name = "imgcreate-%d-%d" % (os.getpid(), random.randint(0, 2**16)) @@ -315,8 +613,8 @@ class DeviceMapperSnapshot(object): size = os.stat(self.imgloop.lofile)[stat.ST_SIZE] table = "0 %d snapshot %s %s p 8" % (size / 512, - self.imgloop.loopdev, - self.cowloop.loopdev) + self.imgloop.device, + self.cowloop.device) args = ["/sbin/dmsetup", "create", self.__name, "--table", table] if subprocess.call(args) != 0: @@ -365,32 +663,31 @@ class DeviceMapperSnapshot(object): except ValueError: raise SnapshotError("Failed to parse dmsetup status: " + out) -# -# Builds a copy-on-write image which can be used to -# create a device-mapper snapshot of an image where -# the image's filesystem is as small as possible -# -# The steps taken are: -# 1) Create a sparse COW -# 2) Loopback mount the image and the COW -# 3) Create a device-mapper snapshot of the image -# using the COW -# 4) Resize the filesystem to the minimal size -# 5) Determine the amount of space used in the COW -# 6) Restroy the device-mapper snapshot -# 7) Truncate the COW, removing unused space -# 8) Create a squashfs of the COW -# def create_image_minimizer(path, image, minimal_size): - imgloop = LoopbackMount(image, "None") + """ + Builds a copy-on-write image which can be used to + create a device-mapper snapshot of an image where + the image's filesystem is as small as possible + + The steps taken are: + 1) Create a sparse COW + 2) Loopback mount the image and the COW + 3) Create a device-mapper snapshot of the image + using the COW + 4) Resize the filesystem to the minimal size + 5) Determine the amount of space used in the COW + 6) Restroy the device-mapper snapshot + 7) Truncate the COW, removing unused space + 8) Create a squashfs of the COW + """ + imgloop = LoopbackDisk(image, None) # Passing bogus size - doesn't matter - cowloop = SparseLoopbackMount(os.path.join(os.path.dirname(path), "osmin"), - None, 64L * 1024L * 1024L) + cowloop = SparseLoopbackDisk(os.path.join(os.path.dirname(path), "osmin"), + 64L * 1024L * 1024L) snapshot = DeviceMapperSnapshot(imgloop, cowloop) try: - cowloop.create() snapshot.create() resize2fs(snapshot.path, minimal_size) @@ -404,3 +701,4 @@ def create_image_minimizer(path, image, minimal_size): mksquashfs(cowloop.lofile, path) os.unlink(cowloop.lofile) + commit 8243a268c7791355832ba5efce6fff963a55f3f3 Author: David Huff <[EMAIL PROTECTED]> Date: Thu Jul 10 17:24:52 2008 -0400 Add method to get partitions from kickstart config diff --git a/imgcreate/kickstart.py b/imgcreate/kickstart.py index 451b133..e352e98 100644 --- a/imgcreate/kickstart.py +++ b/imgcreate/kickstart.py @@ -498,6 +498,9 @@ def get_groups(ks, required = []): def get_excluded(ks, required = []): return ks.handler.packages.excludedList + required +def get_partitions(ks, required = []): + return ks.handler.partition.partitions + def ignore_missing(ks): return ks.handler.packages.handleMissing == ksconstants.KS_MISSING_IGNORE -- Fedora-livecd-list mailing list Fedora-livecd-list@redhat.com https://www.redhat.com/mailman/listinfo/fedora-livecd-list