diff options
| -rw-r--r-- | meta/lib/oeqa/selftest/cases/wic.py | 118 | ||||
| -rw-r--r-- | scripts/lib/wic/ksparser.py | 46 | ||||
| -rw-r--r-- | scripts/lib/wic/partition.py | 1 | ||||
| -rw-r--r-- | scripts/lib/wic/plugins/imager/direct.py | 15 |
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 | ||
| 54 | def sizetype(arg): | 54 | def 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 | ||
| 75 | def overheadtype(arg): | 80 | def 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 | ||
