diff options
Diffstat (limited to 'scripts/lib/wic')
-rw-r--r-- | scripts/lib/wic/3rdparty/pykickstart/commands/partition.py | 4 | ||||
-rw-r--r-- | scripts/lib/wic/3rdparty/pykickstart/options.py | 21 | ||||
-rw-r--r-- | scripts/lib/wic/imager/direct.py | 44 | ||||
-rw-r--r-- | scripts/lib/wic/kickstart/__init__.py | 11 | ||||
-rw-r--r-- | scripts/lib/wic/kickstart/custom_commands/micpartition.py | 2 | ||||
-rw-r--r-- | scripts/lib/wic/kickstart/custom_commands/partition.py | 132 | ||||
-rw-r--r-- | scripts/lib/wic/plugins/source/bootimg-efi.py | 2 | ||||
-rw-r--r-- | scripts/lib/wic/plugins/source/bootimg-partition.py | 45 | ||||
-rw-r--r-- | scripts/lib/wic/plugins/source/bootimg-pcbios.py | 2 | ||||
-rw-r--r-- | scripts/lib/wic/plugins/source/fsimage.py | 70 | ||||
-rw-r--r-- | scripts/lib/wic/plugins/source/rawcopy.py | 84 | ||||
-rw-r--r-- | scripts/lib/wic/utils/oe/misc.py | 2 | ||||
-rw-r--r-- | scripts/lib/wic/utils/partitionedfs.py | 71 |
13 files changed, 381 insertions, 109 deletions
diff --git a/scripts/lib/wic/3rdparty/pykickstart/commands/partition.py b/scripts/lib/wic/3rdparty/pykickstart/commands/partition.py index 56b91aa9d9..b564b1a7ab 100644 --- a/scripts/lib/wic/3rdparty/pykickstart/commands/partition.py +++ b/scripts/lib/wic/3rdparty/pykickstart/commands/partition.py @@ -78,7 +78,7 @@ class FC3_PartData(BaseData): if self.recommended: retval += " --recommended" if self.size and self.size != 0: - retval += " --size=%s" % self.size + retval += " --size=%sk" % self.size if hasattr(self, "start") and self.start != 0: retval += " --start=%s" % self.start @@ -216,7 +216,7 @@ class FC3_Partition(KickstartCommand): callback=part_cb, nargs=1, type="string") op.add_option("--recommended", dest="recommended", action="store_true", default=False) - op.add_option("--size", dest="size", action="store", type="int", + op.add_option("--size", dest="size", action="store", type="size", nargs=1) op.add_option("--start", dest="start", action="store", type="int", nargs=1) diff --git a/scripts/lib/wic/3rdparty/pykickstart/options.py b/scripts/lib/wic/3rdparty/pykickstart/options.py index 341c5d7298..b2d8e3e516 100644 --- a/scripts/lib/wic/3rdparty/pykickstart/options.py +++ b/scripts/lib/wic/3rdparty/pykickstart/options.py @@ -143,6 +143,24 @@ def _check_string(option, opt, value): else: return value +def _check_size(option, opt, value): + # Former default was MB + if (value.isdigit()): + return int(value) * 1024L + + mapping = {"opt": opt, "value": value} + if (not value[:-1].isdigit()): + raise OptionValueError(_("Option %(opt)s: invalid size value: %(value)r") % mapping) + + size = int(value[:-1]) + if (value.endswith("k") or value.endswith("K")): + return size + if (value.endswith("M")): + return size * 1024L + if (value.endswith("G")): + return size * 1024L * 1024L + raise OptionValueError(_("Option %(opt)s: invalid size value: %(value)r") % mapping) + # Creates a new Option class that supports several new attributes: # - required: any option with this attribute must be supplied or an exception # is thrown @@ -169,10 +187,11 @@ class KSOption (Option): ACTIONS = Option.ACTIONS + ("map", "map_extend",) STORE_ACTIONS = Option.STORE_ACTIONS + ("map", "map_extend",) - TYPES = Option.TYPES + ("ksboolean", "string") + TYPES = Option.TYPES + ("ksboolean", "string", "size") TYPE_CHECKER = copy(Option.TYPE_CHECKER) TYPE_CHECKER["ksboolean"] = _check_ksboolean TYPE_CHECKER["string"] = _check_string + TYPE_CHECKER["size"] = _check_size def _check_required(self): if self.required and not self.takes_value(): diff --git a/scripts/lib/wic/imager/direct.py b/scripts/lib/wic/imager/direct.py index 6b2ab3368e..d368401af4 100644 --- a/scripts/lib/wic/imager/direct.py +++ b/scripts/lib/wic/imager/direct.py @@ -74,6 +74,22 @@ class DirectImageCreator(BaseImageCreator): self.kernel_dir = kernel_dir self.native_sysroot = native_sysroot + def __get_part_num(self, num, parts): + """calculate the real partition number, accounting for partitions not + in the partition table and logical partitions + """ + realnum = 0 + for n, p in enumerate(parts, 1): + if not p.no_table: + realnum += 1 + if n == num: + if p.no_table: + return 0 + if self._ptable_format == 'msdos' and realnum > 3: + # account for logical partition numbering, ex. sda5.. + return realnum + 1 + return realnum + def __write_fstab(self, image_rootfs): """overriden to generate fstab (temporarily) in rootfs. This is called from _create, make sure it doesn't get called from @@ -98,12 +114,16 @@ class DirectImageCreator(BaseImageCreator): def _update_fstab(self, fstab_lines, parts): """Assume partition order same as in wks""" for num, p in enumerate(parts, 1): - if not p.mountpoint or p.mountpoint == "/" or p.mountpoint == "/boot": + pnum = self.__get_part_num(num, parts) + if not p.mountpoint or p.mountpoint == "/" or p.mountpoint == "/boot" or pnum == 0: continue - if self._ptable_format == 'msdos' and num > 3: - device_name = "/dev/" + p.disk + str(num + 1) - else: - device_name = "/dev/" + p.disk + str(num) + + part = '' + # mmc device partitions are named mmcblk0p1, mmcblk0p2.. + if p.disk.startswith('mmcblk'): + part = 'p' + + device_name = "/dev/" + p.disk + part + str(pnum) opts = "defaults" if p.fsopts: @@ -230,6 +250,8 @@ class DirectImageCreator(BaseImageCreator): if not self.ks.handler.bootloader.source and p.mountpoint == "/boot": self.ks.handler.bootloader.source = p.source + fstab = self.__write_fstab(self.rootfs_dir.get("ROOTFS_DIR")) + for p in parts: # need to create the filesystems in order to get their # sizes before we can add them and do the layout. @@ -238,12 +260,9 @@ class DirectImageCreator(BaseImageCreator): # self.assemble() calls Image.assemble() which calls # __write_partitition() for each partition to dd the fs # into the partitions. - fstab = self.__write_fstab(self.rootfs_dir.get("ROOTFS_DIR")) - p.prepare(self, self.workdir, self.oe_builddir, self.rootfs_dir, self.bootimg_dir, self.kernel_dir, self.native_sysroot) - self._restore_fstab(fstab) self.__image.add_partition(int(p.size), p.disk, @@ -254,8 +273,11 @@ class DirectImageCreator(BaseImageCreator): fsopts = p.fsopts, boot = p.active, align = p.align, + no_table = p.no_table, part_type = p.part_type) + self._restore_fstab(fstab) + self.__image.layout_partitions(self._ptable_format) self.__imgdir = self.workdir @@ -342,10 +364,8 @@ class DirectImageCreator(BaseImageCreator): if p.disk.startswith('mmcblk'): part = 'p' - if self._ptable_format == 'msdos' and num > 3: - rootdev = "/dev/%s%s%-d" % (p.disk, part, num + 1) - else: - rootdev = "/dev/%s%s%-d" % (p.disk, part, num) + pnum = self.__get_part_num(num, parts) + rootdev = "/dev/%s%s%-d" % (p.disk, part, pnum) root_part_uuid = p.part_type return (rootdev, root_part_uuid) diff --git a/scripts/lib/wic/kickstart/__init__.py b/scripts/lib/wic/kickstart/__init__.py index 600098293a..10959213d1 100644 --- a/scripts/lib/wic/kickstart/__init__.py +++ b/scripts/lib/wic/kickstart/__init__.py @@ -58,16 +58,13 @@ def read_kickstart(path): def __init__(self): superclass.__init__(self, mapping=commandMap[using_version]) - ks = ksparser.KickstartParser(KSHandlers(), errorsAreFatal=False) + ks = ksparser.KickstartParser(KSHandlers(), errorsAreFatal=True) try: ks.readKickstart(path) except (kserrors.KickstartParseError, kserrors.KickstartError), err: - if msger.ask("Errors occured on kickstart file, skip and continue?"): - msger.warning("%s" % err) - pass - else: - raise errors.KsError("%s" % err) + msger.warning("Errors occurred when parsing kickstart file: %s\n" % path) + msger.error("%s" % err) return ks @@ -77,7 +74,7 @@ def get_image_size(ks, default = None): if p.mountpoint == "/" and p.size: __size = p.size if __size > 0: - return int(__size) * 1024L * 1024L + return int(__size) * 1024L else: return default diff --git a/scripts/lib/wic/kickstart/custom_commands/micpartition.py b/scripts/lib/wic/kickstart/custom_commands/micpartition.py index 43d04f1294..d6be008ceb 100644 --- a/scripts/lib/wic/kickstart/custom_commands/micpartition.py +++ b/scripts/lib/wic/kickstart/custom_commands/micpartition.py @@ -32,7 +32,7 @@ class Mic_PartData(FC4_PartData): retval = FC4_PartData._getArgsAsStr(self) if self.align: - retval += " --align" + retval += " --align=%d" % self.align if self.extopts: retval += " --extoptions=%s" % self.extopts if self.part_type: diff --git a/scripts/lib/wic/kickstart/custom_commands/partition.py b/scripts/lib/wic/kickstart/custom_commands/partition.py index 54a494e033..f3d553b885 100644 --- a/scripts/lib/wic/kickstart/custom_commands/partition.py +++ b/scripts/lib/wic/kickstart/custom_commands/partition.py @@ -49,6 +49,9 @@ class Wic_PartData(Mic_PartData): self.source = kwargs.get("source", None) self.sourceparams = kwargs.get("sourceparams", None) self.rootfs = kwargs.get("rootfs-dir", None) + self.no_table = kwargs.get("no-table", False) + self.extra_space = kwargs.get("extra-space", "10M") + self.overhead_factor = kwargs.get("overhead-factor", 1.3) self.source_file = "" self.size = 0 @@ -61,6 +64,10 @@ class Wic_PartData(Mic_PartData): retval += " --sourceparams=%s" % self.sourceparams if self.rootfs: retval += " --rootfs-dir=%s" % self.rootfs + if self.no_table: + retval += " --no-table" + retval += " --extra-space=%d" % self.extra_space + retval += " --overhead-factor=%f" % self.overhead_factor return retval @@ -99,7 +106,7 @@ class Wic_PartData(Mic_PartData): def get_extra_block_count(self, current_blocks): """ - The --size param is reflected in self.size (in MB), and we already + The --size param is reflected in self.size (in kB), and we already have current_blocks (1k) blocks, calculate and return the number of (1k) blocks we need to add to get to --size, 0 if we're already there or beyond. @@ -110,7 +117,7 @@ class Wic_PartData(Mic_PartData): if not self.size: return 0 - requested_blocks = self.size * 1024 + requested_blocks = self.size msger.debug("Requested blocks %d, current_blocks %d" % \ (requested_blocks, current_blocks)) @@ -171,7 +178,7 @@ class Wic_PartData(Mic_PartData): Handle an already-created partition e.g. xxx.ext3 """ rootfs = oe_builddir - du_cmd = "du -Lbms %s" % rootfs + du_cmd = "du -Lbks %s" % rootfs out = exec_cmd(du_cmd) rootfs_size = out.split()[0] @@ -186,10 +193,15 @@ class Wic_PartData(Mic_PartData): Currently handles ext2/3/4, btrfs and vfat. """ - pseudo = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot - pseudo += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % rootfs_dir - pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir - pseudo += "export PSEUDO_NOSYMLINKEXP=1;" + p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot) + p_localstatedir = os.environ.get("PSEUDO_LOCALSTATEDIR", + "%s/../pseudo" % rootfs_dir) + p_passwd = os.environ.get("PSEUDO_PASSWD", rootfs_dir) + p_nosymlinkexp = os.environ.get("PSEUDO_NOSYMLINKEXP", "1") + pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix + pseudo += "export PSEUDO_LOCALSTATEDIR=%s;" % p_localstatedir + pseudo += "export PSEUDO_PASSWD=%s;" % p_passwd + pseudo += "export PSEUDO_NOSYMLINKEXP=%s;" % p_nosymlinkexp pseudo += "%s/usr/bin/pseudo " % native_sysroot if self.fstype.startswith("ext"): @@ -224,12 +236,11 @@ class Wic_PartData(Mic_PartData): actual_rootfs_size = int(out.split()[0]) extra_blocks = self.get_extra_block_count(actual_rootfs_size) - - if extra_blocks < IMAGE_EXTRA_SPACE: - extra_blocks = IMAGE_EXTRA_SPACE + if extra_blocks < self.extra_space: + extra_blocks = self.extra_space rootfs_size = actual_rootfs_size + extra_blocks - rootfs_size *= IMAGE_OVERHEAD_FACTOR + rootfs_size *= self.overhead_factor msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \ (extra_blocks, self.mountpoint, rootfs_size)) @@ -240,15 +251,19 @@ class Wic_PartData(Mic_PartData): extra_imagecmd = "-i 8192" - mkfs_cmd = "mkfs.%s -F %s %s -d %s" % \ - (self.fstype, extra_imagecmd, rootfs, image_rootfs) + label_str = "" + if (self.label): + label_str = "-L %s" % self.label + + mkfs_cmd = "mkfs.%s -F %s %s %s -d %s" % \ + (self.fstype, extra_imagecmd, rootfs, label_str, image_rootfs) (rc, out) = exec_native_cmd(pseudo + mkfs_cmd, native_sysroot) if rc: print "rootfs_dir: %s" % rootfs_dir msger.error("ERROR: mkfs.%s returned '%s' instead of 0 (which you probably don't want to ignore, use --debug for details) when creating filesystem from rootfs directory: %s" % (self.fstype, rc, rootfs_dir)) - # get the rootfs size in the right units for kickstart (Mb) - du_cmd = "du -Lbms %s" % rootfs + # get the rootfs size in the right units for kickstart (kB) + du_cmd = "du -Lbks %s" % rootfs out = exec_cmd(du_cmd) rootfs_size = out.split()[0] @@ -272,12 +287,11 @@ class Wic_PartData(Mic_PartData): actual_rootfs_size = int(out.split()[0]) extra_blocks = self.get_extra_block_count(actual_rootfs_size) - - if extra_blocks < IMAGE_EXTRA_SPACE: - extra_blocks = IMAGE_EXTRA_SPACE + if extra_blocks < self.extra_space: + extra_blocks = self.extra_space rootfs_size = actual_rootfs_size + extra_blocks - rootfs_size *= IMAGE_OVERHEAD_FACTOR + rootfs_size *= self.overhead_factor msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \ (extra_blocks, self.mountpoint, rootfs_size)) @@ -286,14 +300,18 @@ class Wic_PartData(Mic_PartData): (rootfs, rootfs_size) exec_cmd(dd_cmd) - mkfs_cmd = "mkfs.%s -b %d -r %s %s" % \ - (self.fstype, rootfs_size * 1024, image_rootfs, rootfs) + label_str = "" + if (self.label): + label_str = "-L %s" % self.label + + mkfs_cmd = "mkfs.%s -b %d -r %s %s %s" % \ + (self.fstype, rootfs_size * 1024, image_rootfs, label_str, rootfs) (rc, out) = exec_native_cmd(pseudo + mkfs_cmd, native_sysroot) if rc: msger.error("ERROR: mkfs.%s returned '%s' instead of 0 (which you probably don't want to ignore, use --debug for details) when creating filesystem from rootfs directory: %s" % (self.fstype, rc, rootfs_dir)) - # get the rootfs size in the right units for kickstart (Mb) - du_cmd = "du -Lbms %s" % rootfs + # get the rootfs size in the right units for kickstart (kB) + du_cmd = "du -Lbks %s" % rootfs out = exec_cmd(du_cmd) rootfs_size = out.split()[0] @@ -313,9 +331,8 @@ class Wic_PartData(Mic_PartData): blocks = int(out.split()[0]) extra_blocks = self.get_extra_block_count(blocks) - - if extra_blocks < IMAGE_EXTRA_SPACE: - extra_blocks = IMAGE_EXTRA_SPACE + if extra_blocks < self.extra_space: + extra_blocks = self.extra_space blocks += extra_blocks @@ -330,7 +347,11 @@ class Wic_PartData(Mic_PartData): if blocks % 16 != 0: blocks += (16 - (blocks % 16)) - dosfs_cmd = "mkdosfs -n boot -S 512 -C %s %d" % (rootfs, blocks) + label_str = "-n boot" + if (self.label): + label_str = "-n %s" % self.label + + dosfs_cmd = "mkdosfs %s -S 512 -C %s %d" % (label_str, rootfs, blocks) exec_native_cmd(dosfs_cmd, native_sysroot) mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, image_rootfs) @@ -341,8 +362,8 @@ class Wic_PartData(Mic_PartData): chmod_cmd = "chmod 644 %s" % rootfs exec_cmd(chmod_cmd) - # get the rootfs size in the right units for kickstart (Mb) - du_cmd = "du -Lbms %s" % rootfs + # get the rootfs size in the right units for kickstart (kB) + du_cmd = "du -Lbks %s" % rootfs out = exec_cmd(du_cmd) rootfs_size = out.split()[0] @@ -361,8 +382,8 @@ class Wic_PartData(Mic_PartData): (image_rootfs, rootfs) exec_native_cmd(pseudo + squashfs_cmd, native_sysroot) - # get the rootfs size in the right units for kickstart (Mb) - du_cmd = "du -Lbms %s" % rootfs + # get the rootfs size in the right units for kickstart (kB) + du_cmd = "du -Lbks %s" % rootfs out = exec_cmd(du_cmd) rootfs_size = out.split()[0] @@ -395,13 +416,18 @@ class Wic_PartData(Mic_PartData): """ fs = "%s/fs_%s.%s" % (cr_workdir, self.label, self.fstype) - dd_cmd = "dd if=/dev/zero of=%s bs=1M seek=%d count=0" % \ + dd_cmd = "dd if=/dev/zero of=%s bs=1k seek=%d count=0" % \ (fs, self.size) exec_cmd(dd_cmd) extra_imagecmd = "-i 8192" - mkfs_cmd = "mkfs.%s -F %s %s" % (self.fstype, extra_imagecmd, fs) + label_str = "" + if (self.label): + label_str = "-L %s" % self.label + + mkfs_cmd = "mkfs.%s -F %s %s %s" % \ + (self.fstype, extra_imagecmd, label_str, fs) (rc, out) = exec_native_cmd(mkfs_cmd, native_sysroot) if rc: msger.error("ERROR: mkfs.%s returned '%s' instead of 0 (which you probably don't want to ignore, use --debug for details)" % (self.fstype, rc)) @@ -417,16 +443,16 @@ class Wic_PartData(Mic_PartData): """ fs = "%s/fs_%s.%s" % (cr_workdir, self.label, self.fstype) - dd_cmd = "dd if=/dev/zero of=%s bs=1M seek=%d count=0" % \ + dd_cmd = "dd if=/dev/zero of=%s bs=1k seek=%d count=0" % \ (fs, self.size) exec_cmd(dd_cmd) - mkfs_cmd = "mkfs.%s -b %d %s" % (self.fstype, self.size * 1024, rootfs) - (rc, out) = exec_native_cmd(mkfs_cmd, native_sysroot) - if rc: - msger.error("ERROR: mkfs.%s returned '%s' instead of 0 (which you probably don't want to ignore, use --debug for details)" % (self.fstype, rc)) + label_str = "" + if (self.label): + label_str = "-L %s" % self.label - mkfs_cmd = "mkfs.%s -F %s %s" % (self.fstype, extra_imagecmd, fs) + mkfs_cmd = "mkfs.%s -b %d %s %s" % \ + (self.fstype, self.size * 1024, label_str, fs) (rc, out) = exec_native_cmd(mkfs_cmd, native_sysroot) if rc: msger.error("ERROR: mkfs.%s returned '%s' instead of 0 (which you probably don't want to ignore, use --debug for details)" % (self.fstype, rc)) @@ -442,9 +468,13 @@ class Wic_PartData(Mic_PartData): """ fs = "%s/fs_%s.%s" % (cr_workdir, self.label, self.fstype) - blocks = self.size * 1024 + blocks = self.size - dosfs_cmd = "mkdosfs -n boot -S 512 -C %s %d" % (fs, blocks) + label_str = "-n boot" + if (self.label): + label_str = "-n %s" % self.label + + dosfs_cmd = "mkdosfs %s -S 512 -C %s %d" % (label_str, fs, blocks) exec_native_cmd(dosfs_cmd, native_sysroot) chmod_cmd = "chmod 644 %s" % fs @@ -474,8 +504,8 @@ class Wic_PartData(Mic_PartData): os.rmdir(tmpdir) - # get the rootfs size in the right units for kickstart (Mb) - du_cmd = "du -Lbms %s" % fs + # get the rootfs size in the right units for kickstart (kB) + du_cmd = "du -Lbks %s" % fs out = exec_cmd(du_cmd) fs_size = out.split()[0] @@ -490,7 +520,7 @@ class Wic_PartData(Mic_PartData): """ fs = "%s/fs.%s" % (cr_workdir, self.fstype) - dd_cmd = "dd if=/dev/zero of=%s bs=1M seek=%d count=0" % \ + dd_cmd = "dd if=/dev/zero of=%s bs=1k seek=%d count=0" % \ (fs, self.size) exec_cmd(dd_cmd) @@ -510,6 +540,11 @@ class Wic_Partition(Mic_Partition): removedAttrs = Mic_Partition.removedAttrs def _getParser(self): + def overhead_cb (option, opt_str, value, parser): + if (value < 1): + raise OptionValueError("Option %s: invalid value: %r" % (option, value)) + setattr(parser.values, option.dest, value) + op = Mic_Partition._getParser(self) # use specified source file to fill the partition # and calculate partition size @@ -521,4 +556,13 @@ class Wic_Partition(Mic_Partition): # use specified rootfs path to fill the partition op.add_option("--rootfs-dir", type="string", action="store", dest="rootfs", default=None) + # wether to add the partition in the partition table + op.add_option("--no-table", dest="no_table", action="store_true", + default=False) + # extra space beyond the partition size + op.add_option("--extra-space", dest="extra_space", action="store", + type="size", nargs=1, default="10M") + op.add_option("--overhead-factor", dest="overhead_factor", + action="callback", callback=overhead_cb, type="float", + nargs=1, default=1.3) return op diff --git a/scripts/lib/wic/plugins/source/bootimg-efi.py b/scripts/lib/wic/plugins/source/bootimg-efi.py index e4067b6dbf..ee57881e90 100644 --- a/scripts/lib/wic/plugins/source/bootimg-efi.py +++ b/scripts/lib/wic/plugins/source/bootimg-efi.py @@ -228,7 +228,7 @@ class BootimgEFIPlugin(SourcePlugin): chmod_cmd = "chmod 644 %s" % bootimg exec_cmd(chmod_cmd) - du_cmd = "du -Lbms %s" % bootimg + du_cmd = "du -Lbks %s" % bootimg out = exec_cmd(du_cmd) bootimg_size = out.split()[0] diff --git a/scripts/lib/wic/plugins/source/bootimg-partition.py b/scripts/lib/wic/plugins/source/bootimg-partition.py index abf24942e8..c5eb7b8b80 100644 --- a/scripts/lib/wic/plugins/source/bootimg-partition.py +++ b/scripts/lib/wic/plugins/source/bootimg-partition.py @@ -29,6 +29,7 @@ import re from wic import msger from wic.pluginbase import SourcePlugin from wic.utils.oe.misc import * +from glob import glob class BootimgPartitionPlugin(SourcePlugin): name = 'bootimg-partition' @@ -65,7 +66,7 @@ class BootimgPartitionPlugin(SourcePlugin): - copies all files listed in IMAGE_BOOT_FILES variable """ hdddir = "%s/boot" % cr_workdir - rm_cmd = "rm -rf %s" % cr_workdir + rm_cmd = "rm -rf %s/boot" % cr_workdir exec_cmd(rm_cmd) install_cmd = "install -d %s" % hdddir @@ -87,9 +88,11 @@ class BootimgPartitionPlugin(SourcePlugin): # list of tuples (src_name, dst_name) deploy_files = [] - for src_entry in re.findall(r'[\w;\-\./]+', boot_files): + for src_entry in re.findall(r'[\w;\-\./\*]+', boot_files): if ';' in src_entry: dst_entry = tuple(src_entry.split(';')) + if not dst_entry[0] or not dst_entry[1]: + msger.error('Malformed boot file entry: %s' % (src_entry)) else: dst_entry = (src_entry, src_entry) @@ -98,14 +101,36 @@ class BootimgPartitionPlugin(SourcePlugin): for deploy_entry in deploy_files: src, dst = deploy_entry - src_path = os.path.join(bootimg_dir, src) - dst_path = os.path.join(hdddir, dst) - - msger.debug('Install %s as %s' % (os.path.basename(src_path), - dst_path)) - install_cmd = "install -m 0644 -D %s %s" \ - % (src_path, dst_path) - exec_cmd(install_cmd) + install_task = [] + if '*' in src: + # by default install files under their basename + entry_name_fn = os.path.basename + if dst != src: + # unless a target name was given, then treat name + # as a directory and append a basename + entry_name_fn = lambda name: \ + os.path.join(dst, + os.path.basename(name)) + + srcs = glob(os.path.join(bootimg_dir, src)) + + msger.debug('Globbed sources: %s' % (', '.join(srcs))) + for entry in srcs: + entry_dst_name = entry_name_fn(entry) + install_task.append((entry, + os.path.join(hdddir, + entry_dst_name))) + else: + install_task = [(os.path.join(bootimg_dir, src), + os.path.join(hdddir, dst))] + + for task in install_task: + src_path, dst_path = task + msger.debug('Install %s as %s' % (os.path.basename(src_path), + dst_path)) + install_cmd = "install -m 0644 -D %s %s" \ + % (src_path, dst_path) + exec_cmd(install_cmd) msger.debug('Prepare boot partition using rootfs in %s' % (hdddir)) part.prepare_rootfs(cr_workdir, oe_builddir, hdddir, diff --git a/scripts/lib/wic/plugins/source/bootimg-pcbios.py b/scripts/lib/wic/plugins/source/bootimg-pcbios.py index 8a1aca1ad1..c4786a6e0e 100644 --- a/scripts/lib/wic/plugins/source/bootimg-pcbios.py +++ b/scripts/lib/wic/plugins/source/bootimg-pcbios.py @@ -190,7 +190,7 @@ class BootimgPcbiosPlugin(SourcePlugin): chmod_cmd = "chmod 644 %s" % bootimg exec_cmd(chmod_cmd) - du_cmd = "du -Lbms %s" % bootimg + du_cmd = "du -Lbks %s" % bootimg out = exec_cmd(du_cmd) bootimg_size = out.split()[0] diff --git a/scripts/lib/wic/plugins/source/fsimage.py b/scripts/lib/wic/plugins/source/fsimage.py new file mode 100644 index 0000000000..0967883afa --- /dev/null +++ b/scripts/lib/wic/plugins/source/fsimage.py @@ -0,0 +1,70 @@ +# ex:ts=4:sw=4:sts=4:et +# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +import os +import re + +from wic import msger +from wic.pluginbase import SourcePlugin +from wic.utils.oe.misc import * + +class FSImagePlugin(SourcePlugin): + name = 'fsimage' + + @classmethod + def do_install_disk(self, disk, disk_name, cr, workdir, oe_builddir, + bootimg_dir, kernel_dir, native_sysroot): + """ + Called after all partitions have been prepared and assembled into a + disk image. Do nothing. + """ + pass + + @classmethod + def do_configure_partition(self, part, source_params, cr, cr_workdir, + oe_builddir, bootimg_dir, kernel_dir, + native_sysroot): + """ + Called before do_prepare_partition(). Possibly prepare + configuration files of some sort. + """ + pass + + @classmethod + def do_prepare_partition(self, part, source_params, cr, cr_workdir, + oe_builddir, bootimg_dir, kernel_dir, + rootfs_dir, native_sysroot): + """ + Called to do the actual content population for a partition i.e. it + 'prepares' the partition to be incorporated into the image. + """ + if not bootimg_dir: + bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") + if not bootimg_dir: + msger.error("Couldn't find DEPLOY_DIR_IMAGE, exiting\n") + + msger.debug('Bootimg dir: %s' % bootimg_dir) + + if ('file' not in source_params): + msger.error("No file specified\n") + return + + src = os.path.join(bootimg_dir, source_params['file']) + + + msger.debug('Preparing partition using image %s' % (src)) + part.prepare_rootfs_from_fs_image(cr_workdir, src, "") diff --git a/scripts/lib/wic/plugins/source/rawcopy.py b/scripts/lib/wic/plugins/source/rawcopy.py new file mode 100644 index 0000000000..cf6236a04f --- /dev/null +++ b/scripts/lib/wic/plugins/source/rawcopy.py @@ -0,0 +1,84 @@ +# ex:ts=4:sw=4:sts=4:et +# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +import os +import re + +from wic import msger +from wic.pluginbase import SourcePlugin +from wic.utils.oe.misc import * + +class RawCopyPlugin(SourcePlugin): + name = 'rawcopy' + + @classmethod + def do_install_disk(self, disk, disk_name, cr, workdir, oe_builddir, + bootimg_dir, kernel_dir, native_sysroot): + """ + Called after all partitions have been prepared and assembled into a + disk image. Do nothing. + """ + pass + + @classmethod + def do_configure_partition(self, part, source_params, cr, cr_workdir, + oe_builddir, bootimg_dir, kernel_dir, + native_sysroot): + """ + Called before do_prepare_partition(). Possibly prepare + configuration files of some sort. + """ + pass + + @classmethod + def do_prepare_partition(self, part, source_params, cr, cr_workdir, + oe_builddir, bootimg_dir, kernel_dir, + rootfs_dir, native_sysroot): + """ + Called to do the actual content population for a partition i.e. it + 'prepares' the partition to be incorporated into the image. + """ + if not bootimg_dir: + bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") + if not bootimg_dir: + msger.error("Couldn't find DEPLOY_DIR_IMAGE, exiting\n") + + msger.debug('Bootimg dir: %s' % bootimg_dir) + + if ('file' not in source_params): + msger.error("No file specified\n") + return + + src = os.path.join(bootimg_dir, source_params['file']) + dst = src + + if ('skip' in source_params): + dst = os.path.join(cr_workdir, source_params['file']) + dd_cmd = "dd if=%s of=%s ibs=%s skip=1 conv=notrunc" % \ + (src, dst, source_params['skip']) + exec_cmd(dd_cmd) + + # get the size in the right units for kickstart (kB) + du_cmd = "du -Lbks %s" % dst + out = exec_cmd(du_cmd) + filesize = out.split()[0] + + if filesize > part.size: + part.size = filesize + + part.source_file = dst + diff --git a/scripts/lib/wic/utils/oe/misc.py b/scripts/lib/wic/utils/oe/misc.py index b0b5baab73..ea9b6e8ec4 100644 --- a/scripts/lib/wic/utils/oe/misc.py +++ b/scripts/lib/wic/utils/oe/misc.py @@ -122,8 +122,6 @@ def add_wks_var(key, val): wks_vars[key] = val BOOTDD_EXTRA_SPACE = 16384 -IMAGE_EXTRA_SPACE = 10240 -IMAGE_OVERHEAD_FACTOR = 1.3 __bitbake_env_lines = "" diff --git a/scripts/lib/wic/utils/partitionedfs.py b/scripts/lib/wic/utils/partitionedfs.py index fb95cc790e..162f8e1b9c 100644 --- a/scripts/lib/wic/utils/partitionedfs.py +++ b/scripts/lib/wic/utils/partitionedfs.py @@ -29,6 +29,9 @@ from wic.utils.oe.misc import * # Overhead of the MBR partitioning scheme (just one sector) MBR_OVERHEAD = 1 +# Overhead of the GPT partitioning scheme +GPT_OVERHEAD = 34 + # Size of a sector in bytes SECTOR_SIZE = 512 @@ -61,6 +64,7 @@ class Image: self.disks[disk_name] = \ { 'disk': None, # Disk object 'numpart': 0, # Number of allocate partitions + 'realpart': 0, # Number of partitions in the partition table 'partitions': [], # Indexes to self.partitions 'offset': 0, # Offset of next partition (in sectors) # Minimum required disk size to fit all partitions (in bytes) @@ -85,15 +89,15 @@ class Image: self.__add_disk(part['disk_name']) def add_partition(self, size, disk_name, mountpoint, source_file = None, fstype = None, - label=None, fsopts = None, boot = False, align = None, + label=None, fsopts = None, boot = False, align = None, no_table=False, part_type = None): """ Add the next partition. Prtitions have to be added in the first-to-last order. """ ks_pnum = len(self.partitions) - # Converting MB to sectors for parted - size = size * 1024 * 1024 / self.sector_size + # Converting kB to sectors for parted + size = size * 1024 / self.sector_size # We still need partition for "/" or non-subvolume if mountpoint == "/" or not fsopts: @@ -109,6 +113,7 @@ class Image: 'num': None, # Partition number 'boot': boot, # Bootable flag 'align': align, # Partition alignment + 'no_table' : no_table, # Partition does not appear in partition table 'part_type' : part_type } # Partition type self.__add_partition(part) @@ -120,7 +125,7 @@ class Image: msger.debug("Assigning %s partitions to disks" % ptable_format) - if ptable_format not in ('msdos'): + if ptable_format not in ('msdos', 'gpt'): raise ImageError("Unknown partition table format '%s', supported " \ "formats are: 'msdos'" % ptable_format) @@ -147,15 +152,26 @@ class Image: # Get the disk where the partition is located d = self.disks[p['disk_name']] d['numpart'] += 1 + if not p['no_table']: + d['realpart'] += 1 d['ptable_format'] = ptable_format if d['numpart'] == 1: if ptable_format == "msdos": overhead = MBR_OVERHEAD + elif ptable_format == "gpt": + overhead = GPT_OVERHEAD # Skip one sector required for the partitioning scheme overhead d['offset'] += overhead + if d['realpart'] > 3: + # Reserve a sector for EBR for every logical partition + # before alignment is performed. + if ptable_format == "msdos": + d['offset'] += 1 + + if p['align']: # If not first partition and we do have alignment set we need # to align the partition. @@ -182,20 +198,15 @@ class Image: d['offset'] += p['size'] p['type'] = 'primary' - p['num'] = d['numpart'] + if not p['no_table']: + p['num'] = d['realpart'] + else: + p['num'] = 0 if d['ptable_format'] == "msdos": - if d['numpart'] > 2: - # Every logical partition requires an additional sector for - # the EBR, so steal the last sector from the end of each - # partition starting from the 3rd one for the EBR. This - # will make sure the logical partitions are aligned - # correctly. - p['size'] -= 1 - - if d['numpart'] > 3: + if d['realpart'] > 3: p['type'] = 'logical' - p['num'] = d['numpart'] + 1 + p['num'] = d['realpart'] + 1 d['partitions'].append(n) msger.debug("Assigned %s to %s%d, sectors range %d-%d size %d " @@ -208,6 +219,8 @@ class Image: # minumim disk sizes. for disk_name, d in self.disks.items(): d['min_size'] = d['offset'] + if d['ptable_format'] == "gpt": + d['min_size'] += GPT_OVERHEAD d['min_size'] *= self.sector_size @@ -257,15 +270,25 @@ class Image: msger.debug("Creating partitions") for p in self.partitions: + if p['num'] == 0: + continue + d = self.disks[p['disk_name']] if d['ptable_format'] == "msdos" and p['num'] == 5: - # The last sector of the 3rd partition was reserved for the EBR - # of the first _logical_ partition. This is why the extended - # partition should start one sector before the first logical - # partition. + # Create an extended partition (note: extended + # partition is described in MBR and contains all + # logical partitions). The logical partitions save a + # sector for an EBR just before the start of a + # partition. The extended partition must start one + # sector before the start of the first logical + # partition. This way the first EBR is inside of the + # extended partition. Since the extended partitions + # starts a sector before the first logical partition, + # add a sector at the back, so that there is enough + # room for all logical partitions. self.__create_partition(d['disk'].device, "extended", None, p['start'] - 1, - d['offset'] - p['start']) + d['offset'] - p['start'] + 1) if p['fstype'] == "swap": parted_fs_type = "linux-swap" @@ -338,14 +361,6 @@ class Image: for p in self.partitions: d = self.disks[p['disk_name']] - if d['ptable_format'] == "msdos" and p['num'] == 5: - # The last sector of the 3rd partition was reserved for the EBR - # of the first _logical_ partition. This is why the extended - # partition should start one sector before the first logical - # partition. - self.__write_partition(p['num'], p['source_file'], - p['start'] - 1, - d['offset'] - p['start']) self.__write_partition(p['num'], p['source_file'], p['start'], p['size']) |