summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/lib/oeqa/selftest/cases/wic.py118
-rw-r--r--scripts/lib/wic/ksparser.py46
-rw-r--r--scripts/lib/wic/partition.py1
-rw-r--r--scripts/lib/wic/plugins/imager/direct.py15
4 files changed, 135 insertions, 45 deletions
diff --git a/meta/lib/oeqa/selftest/cases/wic.py b/meta/lib/oeqa/selftest/cases/wic.py
index 626a217e69..6d4068a527 100644
--- a/meta/lib/oeqa/selftest/cases/wic.py
+++ b/meta/lib/oeqa/selftest/cases/wic.py
@@ -639,41 +639,50 @@ class Wic2(WicTestCase):
639 tempf.write("part " \ 639 tempf.write("part " \
640 "--source rootfs --ondisk hda --align 4 --fixed-size %d " 640 "--source rootfs --ondisk hda --align 4 --fixed-size %d "
641 "--fstype=ext4\n" % size) 641 "--fstype=ext4\n" % size)
642 wksname = os.path.splitext(os.path.basename(wkspath))[0]
643 642
644 return wkspath, wksname 643 return wkspath
645 644
646 def test_fixed_size(self): 645 def _get_wic_partitions(self, wkspath, native_sysroot=None, ignore_status=False):
647 """ 646 p = runCmd("wic create %s -e core-image-minimal -o %s" % (wkspath, self.resultdir),
648 Test creation of a simple image with partition size controlled through 647 ignore_status=ignore_status)
649 --fixed-size flag 648
650 """ 649 if p.status:
651 wkspath, wksname = Wic2._make_fixed_size_wks(200) 650 return (p, None)
651
652 wksname = os.path.splitext(os.path.basename(wkspath))[0]
652 653
653 runCmd("wic create %s -e core-image-minimal -o %s" \
654 % (wkspath, self.resultdir))
655 os.remove(wkspath)
656 wicout = glob(self.resultdir + "%s-*direct" % wksname) 654 wicout = glob(self.resultdir + "%s-*direct" % wksname)
657 self.assertEqual(1, len(wicout)) 655
656 if not wicout:
657 return (p, None)
658 658
659 wicimg = wicout[0] 659 wicimg = wicout[0]
660 660
661 native_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "wic-tools") 661 if not native_sysroot:
662 native_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "wic-tools")
662 663
663 # verify partition size with wic 664 # verify partition size with wic
664 res = runCmd("parted -m %s unit mib p 2>/dev/null" % wicimg, 665 res = runCmd("parted -m %s unit kib p 2>/dev/null" % wicimg,
665 native_sysroot=native_sysroot) 666 native_sysroot=native_sysroot)
666 667
667 # parse parted output which looks like this: 668 # parse parted output which looks like this:
668 # BYT;\n 669 # BYT;\n
669 # /var/tmp/wic/build/tmpfwvjjkf_-201611101222-hda.direct:200MiB:file:512:512:msdos::;\n 670 # /var/tmp/wic/build/tmpfwvjjkf_-201611101222-hda.direct:200MiB:file:512:512:msdos::;\n
670 # 1:0.00MiB:200MiB:200MiB:ext4::;\n 671 # 1:0.00MiB:200MiB:200MiB:ext4::;\n
671 partlns = res.output.splitlines()[2:] 672 return (p, res.output.splitlines()[2:])
672 673
673 self.assertEqual(1, len(partlns), 674 def test_fixed_size(self):
674 msg="Partition list '%s'" % res.output) 675 """
675 self.assertEqual("1:0.00MiB:200MiB:200MiB:ext4::;", partlns[0], 676 Test creation of a simple image with partition size controlled through
676 msg="Partition list '%s'" % res.output) 677 --fixed-size flag
678 """
679 wkspath = Wic2._make_fixed_size_wks(200)
680 _, partlns = self._get_wic_partitions(wkspath)
681 os.remove(wkspath)
682
683 self.assertEqual(partlns, [
684 "1:4.00kiB:204804kiB:204800kiB:ext4::;",
685 ])
677 686
678 def test_fixed_size_error(self): 687 def test_fixed_size_error(self):
679 """ 688 """
@@ -681,13 +690,72 @@ class Wic2(WicTestCase):
681 --fixed-size flag. The size of partition is intentionally set to 1MiB 690 --fixed-size flag. The size of partition is intentionally set to 1MiB
682 in order to trigger an error in wic. 691 in order to trigger an error in wic.
683 """ 692 """
684 wkspath, wksname = Wic2._make_fixed_size_wks(1) 693 wkspath = Wic2._make_fixed_size_wks(1)
685 694 p, _ = self._get_wic_partitions(wkspath, ignore_status=True)
686 self.assertEqual(1, runCmd("wic create %s -e core-image-minimal -o %s" \
687 % (wkspath, self.resultdir), ignore_status=True).status)
688 os.remove(wkspath) 695 os.remove(wkspath)
689 wicout = glob(self.resultdir + "%s-*direct" % wksname) 696
690 self.assertEqual(0, len(wicout)) 697 self.assertNotEqual(p.status, 0, "wic exited successfully when an error was expected:\n%s" % p.output)
698
699 def test_offset(self):
700 native_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "wic-tools")
701
702 with NamedTemporaryFile("w", suffix=".wks") as tempf:
703 # Test that partitions are placed at the correct offsets, default KB
704 tempf.write("bootloader --ptable gpt\n" \
705 "part / --source rootfs --ondisk hda --offset 32 --fixed-size 100M --fstype=ext4\n" \
706 "part /bar --ondisk hda --offset 102432 --fixed-size 100M --fstype=ext4\n")
707 tempf.flush()
708
709 _, partlns = self._get_wic_partitions(tempf.name, native_sysroot)
710 self.assertEqual(partlns, [
711 "1:32.0kiB:102432kiB:102400kiB:ext4:primary:;",
712 "2:102432kiB:204832kiB:102400kiB:ext4:primary:;",
713 ])
714
715 with NamedTemporaryFile("w", suffix=".wks") as tempf:
716 # Test that partitions are placed at the correct offsets, same with explicit KB
717 tempf.write("bootloader --ptable gpt\n" \
718 "part / --source rootfs --ondisk hda --offset 32K --fixed-size 100M --fstype=ext4\n" \
719 "part /bar --ondisk hda --offset 102432K --fixed-size 100M --fstype=ext4\n")
720 tempf.flush()
721
722 _, partlns = self._get_wic_partitions(tempf.name, native_sysroot)
723 self.assertEqual(partlns, [
724 "1:32.0kiB:102432kiB:102400kiB:ext4:primary:;",
725 "2:102432kiB:204832kiB:102400kiB:ext4:primary:;",
726 ])
727
728 with NamedTemporaryFile("w", suffix=".wks") as tempf:
729 # Test that partitions are placed at the correct offsets using MB
730 tempf.write("bootloader --ptable gpt\n" \
731 "part / --source rootfs --ondisk hda --offset 32K --fixed-size 100M --fstype=ext4\n" \
732 "part /bar --ondisk hda --offset 101M --fixed-size 100M --fstype=ext4\n")
733 tempf.flush()
734
735 _, partlns = self._get_wic_partitions(tempf.name, native_sysroot)
736 self.assertEqual(partlns, [
737 "1:32.0kiB:102432kiB:102400kiB:ext4:primary:;",
738 "2:103424kiB:205824kiB:102400kiB:ext4:primary:;",
739 ])
740
741 with NamedTemporaryFile("w", suffix=".wks") as tempf:
742 # Test that image creation fails if the partitions would overlap
743 tempf.write("bootloader --ptable gpt\n" \
744 "part / --source rootfs --ondisk hda --offset 32 --fixed-size 100M --fstype=ext4\n" \
745 "part /bar --ondisk hda --offset 102431 --fixed-size 100M --fstype=ext4\n")
746 tempf.flush()
747
748 p, _ = self._get_wic_partitions(tempf.name, ignore_status=True)
749 self.assertNotEqual(p.status, 0, "wic exited successfully when an error was expected:\n%s" % p.output)
750
751 with NamedTemporaryFile("w", suffix=".wks") as tempf:
752 # Test that partitions are not allowed to overlap with the booloader
753 tempf.write("bootloader --ptable gpt\n" \
754 "part / --source rootfs --ondisk hda --offset 8 --fixed-size 100M --fstype=ext4\n")
755 tempf.flush()
756
757 p, _ = self._get_wic_partitions(tempf.name, ignore_status=True)
758 self.assertNotEqual(p.status, 0, "wic exited successfully when an error was expected:\n%s" % p.output)
691 759
692 @only_for_arch(['i586', 'i686', 'x86_64']) 760 @only_for_arch(['i586', 'i686', 'x86_64'])
693 def test_rawcopy_plugin_qemu(self): 761 def test_rawcopy_plugin_qemu(self):
diff --git a/scripts/lib/wic/ksparser.py b/scripts/lib/wic/ksparser.py
index 650b976223..f32315c631 100644
--- a/scripts/lib/wic/ksparser.py
+++ b/scripts/lib/wic/ksparser.py
@@ -51,26 +51,31 @@ class KickStartParser(ArgumentParser):
51 def error(self, message): 51 def error(self, message):
52 raise ArgumentError(None, message) 52 raise ArgumentError(None, message)
53 53
54def sizetype(arg): 54def sizetype(default):
55 """ 55 def f(arg):
56 Custom type for ArgumentParser 56 """
57 Converts size string in <num>[K|k|M|G] format into the integer value 57 Custom type for ArgumentParser
58 """ 58 Converts size string in <num>[K|k|M|G] format into the integer value
59 if arg.isdigit(): 59 """
60 return int(arg) * 1024 60 try:
61 suffix = default
62 size = int(arg)
63 except ValueError:
64 try:
65 suffix = arg[-1:]
66 size = int(arg[:-1])
67 except ValueError:
68 raise ArgumentTypeError("Invalid size: %r" % arg)
69
70 if suffix == "k" or suffix == "K":
71 return size
72 if suffix == "M":
73 return size * 1024
74 if suffix == "G":
75 return size * 1024 * 1024
61 76
62 if not arg[:-1].isdigit():
63 raise ArgumentTypeError("Invalid size: %r" % arg) 77 raise ArgumentTypeError("Invalid size: %r" % arg)
64 78 return f
65 size = int(arg[:-1])
66 if arg.endswith("k") or arg.endswith("K"):
67 return size
68 if arg.endswith("M"):
69 return size * 1024
70 if arg.endswith("G"):
71 return size * 1024 * 1024
72
73 raise ArgumentTypeError("Invalid size: %r" % arg)
74 79
75def overheadtype(arg): 80def overheadtype(arg):
76 """ 81 """
@@ -136,6 +141,7 @@ class KickStart():
136 part.add_argument('mountpoint', nargs='?') 141 part.add_argument('mountpoint', nargs='?')
137 part.add_argument('--active', action='store_true') 142 part.add_argument('--active', action='store_true')
138 part.add_argument('--align', type=int) 143 part.add_argument('--align', type=int)
144 part.add_argument('--offset', type=sizetype("K"))
139 part.add_argument('--exclude-path', nargs='+') 145 part.add_argument('--exclude-path', nargs='+')
140 part.add_argument('--include-path', nargs='+') 146 part.add_argument('--include-path', nargs='+')
141 part.add_argument("--extra-space", type=sizetype) 147 part.add_argument("--extra-space", type=sizetype)
@@ -160,8 +166,8 @@ class KickStart():
160 # --error, but since nesting mutually exclusive groups does not work, 166 # --error, but since nesting mutually exclusive groups does not work,
161 # ----extra-space/--overhead-factor are handled later 167 # ----extra-space/--overhead-factor are handled later
162 sizeexcl = part.add_mutually_exclusive_group() 168 sizeexcl = part.add_mutually_exclusive_group()
163 sizeexcl.add_argument('--size', type=sizetype, default=0) 169 sizeexcl.add_argument('--size', type=sizetype("M"), default=0)
164 sizeexcl.add_argument('--fixed-size', type=sizetype, default=0) 170 sizeexcl.add_argument('--fixed-size', type=sizetype("M"), default=0)
165 171
166 part.add_argument('--source') 172 part.add_argument('--source')
167 part.add_argument('--sourceparams') 173 part.add_argument('--sourceparams')
diff --git a/scripts/lib/wic/partition.py b/scripts/lib/wic/partition.py
index 2d95f78439..3490b4e75d 100644
--- a/scripts/lib/wic/partition.py
+++ b/scripts/lib/wic/partition.py
@@ -39,6 +39,7 @@ class Partition():
39 self.mountpoint = args.mountpoint 39 self.mountpoint = args.mountpoint
40 self.no_table = args.no_table 40 self.no_table = args.no_table
41 self.num = None 41 self.num = None
42 self.offset = args.offset
42 self.overhead_factor = args.overhead_factor 43 self.overhead_factor = args.overhead_factor
43 self.part_name = args.part_name 44 self.part_name = args.part_name
44 self.part_type = args.part_type 45 self.part_type = args.part_type
diff --git a/scripts/lib/wic/plugins/imager/direct.py b/scripts/lib/wic/plugins/imager/direct.py
index 2d06c242b6..1f65a7afe5 100644
--- a/scripts/lib/wic/plugins/imager/direct.py
+++ b/scripts/lib/wic/plugins/imager/direct.py
@@ -428,6 +428,21 @@ class PartitionedImage():
428 # increase the offset so we actually start the partition on right alignment 428 # increase the offset so we actually start the partition on right alignment
429 self.offset += align_sectors 429 self.offset += align_sectors
430 430
431 if part.offset is not None:
432 offset = (part.offset * 1024) // self.sector_size
433
434 if offset * self.sector_size != part.offset * 1024:
435 raise WicError("Could not place %s%s at offset %dK with sector size %d" % (part.disk, self.numpart, part.offset, self.sector_size))
436
437 delta = offset - self.offset
438 if delta < 0:
439 raise WicError("Could not place %s%s at offset %dK: next free sector is %d (delta: %d)" % (part.disk, self.numpart, part.offset, offset, delta))
440
441 logger.debug("Skipping %d sectors to place %s%s at offset %dK",
442 delta, part.disk, self.numpart, part.offset)
443
444 self.offset = offset
445
431 part.start = self.offset 446 part.start = self.offset
432 self.offset += part.size_sec 447 self.offset += part.size_sec
433 448