summaryrefslogtreecommitdiffstats
path: root/scripts/lib/wic
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib/wic')
-rw-r--r--scripts/lib/wic/3rdparty/pykickstart/commands/partition.py4
-rw-r--r--scripts/lib/wic/3rdparty/pykickstart/options.py21
-rw-r--r--scripts/lib/wic/imager/direct.py44
-rw-r--r--scripts/lib/wic/kickstart/__init__.py11
-rw-r--r--scripts/lib/wic/kickstart/custom_commands/micpartition.py2
-rw-r--r--scripts/lib/wic/kickstart/custom_commands/partition.py132
-rw-r--r--scripts/lib/wic/plugins/source/bootimg-efi.py2
-rw-r--r--scripts/lib/wic/plugins/source/bootimg-partition.py45
-rw-r--r--scripts/lib/wic/plugins/source/bootimg-pcbios.py2
-rw-r--r--scripts/lib/wic/plugins/source/fsimage.py70
-rw-r--r--scripts/lib/wic/plugins/source/rawcopy.py84
-rw-r--r--scripts/lib/wic/utils/oe/misc.py2
-rw-r--r--scripts/lib/wic/utils/partitionedfs.py71
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'])