diff options
Diffstat (limited to 'scripts/lib/mic/utils')
-rw-r--r-- | scripts/lib/mic/utils/fs_related.py | 30 | ||||
-rw-r--r-- | scripts/lib/mic/utils/misc.py | 4 | ||||
-rw-r--r-- | scripts/lib/mic/utils/oe/__init__.py | 22 | ||||
-rw-r--r-- | scripts/lib/mic/utils/oe/misc.py | 108 | ||||
-rw-r--r-- | scripts/lib/mic/utils/partitionedfs.py | 94 |
5 files changed, 201 insertions, 57 deletions
diff --git a/scripts/lib/mic/utils/fs_related.py b/scripts/lib/mic/utils/fs_related.py index b9b9a97175..61617353eb 100644 --- a/scripts/lib/mic/utils/fs_related.py +++ b/scripts/lib/mic/utils/fs_related.py | |||
@@ -29,7 +29,7 @@ import uuid | |||
29 | from mic import msger | 29 | from mic import msger |
30 | from mic.utils import runner | 30 | from mic.utils import runner |
31 | from mic.utils.errors import * | 31 | from mic.utils.errors import * |
32 | 32 | from mic.utils.oe.misc import * | |
33 | 33 | ||
34 | def find_binary_inchroot(binary, chroot): | 34 | def find_binary_inchroot(binary, chroot): |
35 | paths = ["/usr/sbin", | 35 | paths = ["/usr/sbin", |
@@ -280,6 +280,34 @@ class RawDisk(Disk): | |||
280 | def exists(self): | 280 | def exists(self): |
281 | return True | 281 | return True |
282 | 282 | ||
283 | |||
284 | class DiskImage(Disk): | ||
285 | """ | ||
286 | A Disk backed by a file. | ||
287 | """ | ||
288 | def __init__(self, image_file, size): | ||
289 | Disk.__init__(self, size) | ||
290 | self.image_file = image_file | ||
291 | |||
292 | def exists(self): | ||
293 | return os.path.exists(self.image_file) | ||
294 | |||
295 | def create(self): | ||
296 | if self.device is not None: | ||
297 | return | ||
298 | |||
299 | blocks = self.size / 1024 | ||
300 | if self.size - blocks * 1024: | ||
301 | blocks += 1 | ||
302 | |||
303 | # create disk image | ||
304 | dd_cmd = "dd if=/dev/zero of=%s bs=1024 seek=%d count=1" % \ | ||
305 | (self.image_file, blocks) | ||
306 | rc, out = exec_cmd(dd_cmd) | ||
307 | |||
308 | self.device = self.image_file | ||
309 | |||
310 | |||
283 | class LoopbackDisk(Disk): | 311 | class LoopbackDisk(Disk): |
284 | """A Disk backed by a file via the loop module.""" | 312 | """A Disk backed by a file via the loop module.""" |
285 | def __init__(self, lofile, size): | 313 | def __init__(self, lofile, size): |
diff --git a/scripts/lib/mic/utils/misc.py b/scripts/lib/mic/utils/misc.py index 63024346a9..67ddef2e44 100644 --- a/scripts/lib/mic/utils/misc.py +++ b/scripts/lib/mic/utils/misc.py | |||
@@ -512,8 +512,8 @@ def uncompress_squashfs(squashfsimg, outdir): | |||
512 | if (rc != 0): | 512 | if (rc != 0): |
513 | raise SquashfsError("Failed to uncompress %s." % squashfsimg) | 513 | raise SquashfsError("Failed to uncompress %s." % squashfsimg) |
514 | 514 | ||
515 | def mkdtemp(dir = "/var/tmp", prefix = "mic-tmp-"): | 515 | def mkdtemp(dir = "/var/tmp", prefix = "wic-tmp-"): |
516 | """ FIXME: use the dir in mic.conf instead """ | 516 | """ FIXME: use the dir in wic.conf instead """ |
517 | 517 | ||
518 | makedirs(dir) | 518 | makedirs(dir) |
519 | return tempfile.mkdtemp(dir = dir, prefix = prefix) | 519 | return tempfile.mkdtemp(dir = dir, prefix = prefix) |
diff --git a/scripts/lib/mic/utils/oe/__init__.py b/scripts/lib/mic/utils/oe/__init__.py new file mode 100644 index 0000000000..d10e802116 --- /dev/null +++ b/scripts/lib/mic/utils/oe/__init__.py | |||
@@ -0,0 +1,22 @@ | |||
1 | # | ||
2 | # OpenEmbedded mic utils library | ||
3 | # | ||
4 | # Copyright (c) 2013, Intel Corporation. | ||
5 | # All rights reserved. | ||
6 | # | ||
7 | # This program is free software; you can redistribute it and/or modify | ||
8 | # it under the terms of the GNU General Public License version 2 as | ||
9 | # published by the Free Software Foundation. | ||
10 | # | ||
11 | # This program is distributed in the hope that it will be useful, | ||
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | # GNU General Public License for more details. | ||
15 | # | ||
16 | # You should have received a copy of the GNU General Public License along | ||
17 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | # | ||
20 | # AUTHORS | ||
21 | # Tom Zanussi <tom.zanussi (at] linux.intel.com> | ||
22 | # | ||
diff --git a/scripts/lib/mic/utils/oe/misc.py b/scripts/lib/mic/utils/oe/misc.py new file mode 100644 index 0000000000..9edaa230e4 --- /dev/null +++ b/scripts/lib/mic/utils/oe/misc.py | |||
@@ -0,0 +1,108 @@ | |||
1 | # ex:ts=4:sw=4:sts=4:et | ||
2 | # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- | ||
3 | # | ||
4 | # Copyright (c) 2013, Intel Corporation. | ||
5 | # All rights reserved. | ||
6 | # | ||
7 | # This program is free software; you can redistribute it and/or modify | ||
8 | # it under the terms of the GNU General Public License version 2 as | ||
9 | # published by the Free Software Foundation. | ||
10 | # | ||
11 | # This program is distributed in the hope that it will be useful, | ||
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | # GNU General Public License for more details. | ||
15 | # | ||
16 | # You should have received a copy of the GNU General Public License along | ||
17 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | # | ||
20 | # DESCRIPTION | ||
21 | # This module provides a place to collect various mic-related utils | ||
22 | # for the OpenEmbedded Image Tools. | ||
23 | # | ||
24 | # AUTHORS | ||
25 | # Tom Zanussi <tom.zanussi (at] linux.intel.com> | ||
26 | # | ||
27 | |||
28 | from mic import msger | ||
29 | from mic.utils import runner | ||
30 | |||
31 | def exec_cmd(cmd_and_args, as_shell = False, catch = 3): | ||
32 | """ | ||
33 | Execute command, catching stderr, stdout | ||
34 | |||
35 | Need to execute as_shell if the command uses wildcards | ||
36 | """ | ||
37 | msger.debug("exec_cmd: %s" % cmd_and_args) | ||
38 | args = cmd_and_args.split() | ||
39 | msger.debug(args) | ||
40 | |||
41 | if (as_shell): | ||
42 | rc, out = runner.runtool(cmd_and_args, catch) | ||
43 | else: | ||
44 | rc, out = runner.runtool(args, catch) | ||
45 | out = out.strip() | ||
46 | msger.debug("exec_cmd: output for %s (rc = %d): %s" % \ | ||
47 | (cmd_and_args, rc, out)) | ||
48 | |||
49 | if rc != 0: | ||
50 | # We don't throw exception when return code is not 0, because | ||
51 | # parted always fails to reload part table with loop devices. This | ||
52 | # prevents us from distinguishing real errors based on return | ||
53 | # code. | ||
54 | msger.debug("WARNING: %s returned '%s' instead of 0" % (args[0], rc)) | ||
55 | |||
56 | return (rc, out) | ||
57 | |||
58 | |||
59 | def exec_cmd_quiet(cmd_and_args, as_shell = False): | ||
60 | """ | ||
61 | Execute command, catching nothing in the output | ||
62 | |||
63 | Need to execute as_shell if the command uses wildcards | ||
64 | """ | ||
65 | return exec_cmd(cmd_and_args, as_shell, 0) | ||
66 | |||
67 | |||
68 | def exec_native_cmd(cmd_and_args, native_sysroot, catch = 3): | ||
69 | """ | ||
70 | Execute native command, catching stderr, stdout | ||
71 | |||
72 | Need to execute as_shell if the command uses wildcards | ||
73 | |||
74 | Always need to execute native commands as_shell | ||
75 | """ | ||
76 | native_paths = \ | ||
77 | "export PATH=%s/sbin:PATH=%s/usr/sbin:PATH=%s/usr/bin:$PATH" % \ | ||
78 | (native_sysroot, native_sysroot, native_sysroot) | ||
79 | native_cmd_and_args = "%s;%s" % (native_paths, cmd_and_args) | ||
80 | msger.debug("exec_native_cmd: %s" % cmd_and_args) | ||
81 | |||
82 | args = cmd_and_args.split() | ||
83 | msger.debug(args) | ||
84 | |||
85 | return exec_cmd(native_cmd_and_args, True, catch) | ||
86 | |||
87 | |||
88 | def exec_native_cmd_quiet(cmd_and_args, native_sysroot): | ||
89 | """ | ||
90 | Execute native command, catching nothing in the output | ||
91 | |||
92 | Need to execute as_shell if the command uses wildcards | ||
93 | |||
94 | Always need to execute native commands as_shell | ||
95 | """ | ||
96 | return exec_native_cmd(cmd_and_args, native_sysroot, 0) | ||
97 | |||
98 | |||
99 | # kickstart doesn't support variable substution in commands, so this | ||
100 | # is our current simplistic scheme for supporting that | ||
101 | |||
102 | wks_vars = dict() | ||
103 | |||
104 | def get_wks_var(key): | ||
105 | return wks_vars[key] | ||
106 | |||
107 | def add_wks_var(key, val): | ||
108 | wks_vars[key] = val | ||
diff --git a/scripts/lib/mic/utils/partitionedfs.py b/scripts/lib/mic/utils/partitionedfs.py index 04758440e1..e8cded26e0 100644 --- a/scripts/lib/mic/utils/partitionedfs.py +++ b/scripts/lib/mic/utils/partitionedfs.py | |||
@@ -25,6 +25,7 @@ from mic.utils import runner | |||
25 | from mic.utils.errors import MountError | 25 | from mic.utils.errors import MountError |
26 | from mic.utils.fs_related import * | 26 | from mic.utils.fs_related import * |
27 | from mic.utils.gpt_parser import GptParser | 27 | from mic.utils.gpt_parser import GptParser |
28 | from mic.utils.oe.misc import * | ||
28 | 29 | ||
29 | # Overhead of the MBR partitioning scheme (just one sector) | 30 | # Overhead of the MBR partitioning scheme (just one sector) |
30 | MBR_OVERHEAD = 1 | 31 | MBR_OVERHEAD = 1 |
@@ -93,7 +94,7 @@ class PartitionedMount(Mount): | |||
93 | self.partitions.append(part) | 94 | self.partitions.append(part) |
94 | self.__add_disk(part['disk_name']) | 95 | self.__add_disk(part['disk_name']) |
95 | 96 | ||
96 | def add_partition(self, size, disk_name, mountpoint, fstype = None, | 97 | def add_partition(self, size, disk_name, mountpoint, source_file = None, fstype = None, |
97 | label=None, fsopts = None, boot = False, align = None, | 98 | label=None, fsopts = None, boot = False, align = None, |
98 | part_type = None): | 99 | part_type = None): |
99 | """ Add the next partition. Prtitions have to be added in the | 100 | """ Add the next partition. Prtitions have to be added in the |
@@ -141,6 +142,7 @@ class PartitionedMount(Mount): | |||
141 | part = { 'ks_pnum' : ks_pnum, # Partition number in the KS file | 142 | part = { 'ks_pnum' : ks_pnum, # Partition number in the KS file |
142 | 'size': size, # In sectors | 143 | 'size': size, # In sectors |
143 | 'mountpoint': mountpoint, # Mount relative to chroot | 144 | 'mountpoint': mountpoint, # Mount relative to chroot |
145 | 'source_file': source_file, # partition contents | ||
144 | 'fstype': fstype, # Filesystem type | 146 | 'fstype': fstype, # Filesystem type |
145 | 'fsopts': fsopts, # Filesystem mount options | 147 | 'fsopts': fsopts, # Filesystem mount options |
146 | 'label': label, # Partition label | 148 | 'label': label, # Partition label |
@@ -723,67 +725,51 @@ class PartitionedMount(Mount): | |||
723 | 725 | ||
724 | self.snapshot_created = True | 726 | self.snapshot_created = True |
725 | 727 | ||
728 | def __install_partition(self, num, source_file, start, size): | ||
729 | """ | ||
730 | Install source_file contents into a partition. | ||
731 | """ | ||
732 | if not source_file: # nothing to install | ||
733 | return | ||
734 | |||
735 | # Start is included in the size so need to substract one from the end. | ||
736 | end = start + size - 1 | ||
737 | msger.debug("Installed %s in partition %d, sectors %d-%d, size %d sectors" % (source_file, num, start, end, size)) | ||
738 | |||
739 | dd_cmd = "dd if=%s of=%s bs=%d seek=%d count=%d conv=notrunc" % \ | ||
740 | (source_file, self.image_file, self.sector_size, start, size) | ||
741 | rc, out = exec_cmd(dd_cmd) | ||
742 | |||
743 | |||
744 | def install(self, image_file): | ||
745 | msger.debug("Installing partitions") | ||
746 | |||
747 | self.image_file = image_file | ||
748 | |||
749 | for p in self.partitions: | ||
750 | d = self.disks[p['disk_name']] | ||
751 | if d['ptable_format'] == "msdos" and p['num'] == 5: | ||
752 | # The last sector of the 3rd partition was reserved for the EBR | ||
753 | # of the first _logical_ partition. This is why the extended | ||
754 | # partition should start one sector before the first logical | ||
755 | # partition. | ||
756 | self.__install_partition(p['num'], p['source_file'], | ||
757 | p['start'] - 1, | ||
758 | d['offset'] - p['start']) | ||
759 | |||
760 | self.__install_partition(p['num'], p['source_file'], | ||
761 | p['start'], p['size']) | ||
762 | |||
726 | def mount(self): | 763 | def mount(self): |
727 | for dev in self.disks.keys(): | 764 | for dev in self.disks.keys(): |
728 | d = self.disks[dev] | 765 | d = self.disks[dev] |
729 | d['disk'].create() | 766 | d['disk'].create() |
730 | 767 | ||
731 | self.__format_disks() | 768 | self.__format_disks() |
732 | self.__map_partitions() | ||
733 | self.__calculate_mountorder() | ||
734 | 769 | ||
735 | for mp in self.mountOrder: | 770 | self.__calculate_mountorder() |
736 | p = None | ||
737 | for p1 in self.partitions: | ||
738 | if p1['mountpoint'] == mp: | ||
739 | p = p1 | ||
740 | break | ||
741 | |||
742 | if not p['label']: | ||
743 | if p['mountpoint'] == "/": | ||
744 | p['label'] = 'platform' | ||
745 | else: | ||
746 | p['label'] = mp.split('/')[-1] | ||
747 | |||
748 | if mp == 'swap': | ||
749 | import uuid | ||
750 | p['uuid'] = str(uuid.uuid1()) | ||
751 | runner.show([self.mkswap, | ||
752 | '-L', p['label'], | ||
753 | '-U', p['uuid'], | ||
754 | p['device']]) | ||
755 | continue | ||
756 | 771 | ||
757 | rmmountdir = False | 772 | return |
758 | if p['mountpoint'] == "/": | ||
759 | rmmountdir = True | ||
760 | if p['fstype'] == "vfat" or p['fstype'] == "msdos": | ||
761 | myDiskMount = VfatDiskMount | ||
762 | elif p['fstype'] in ("ext2", "ext3", "ext4"): | ||
763 | myDiskMount = ExtDiskMount | ||
764 | elif p['fstype'] == "btrfs": | ||
765 | myDiskMount = BtrfsDiskMount | ||
766 | else: | ||
767 | raise MountError("Fail to support file system " + p['fstype']) | ||
768 | |||
769 | if p['fstype'] == "btrfs" and not p['fsopts']: | ||
770 | p['fsopts'] = "subvolid=0" | ||
771 | |||
772 | pdisk = myDiskMount(RawDisk(p['size'] * self.sector_size, p['device']), | ||
773 | self.mountdir + p['mountpoint'], | ||
774 | p['fstype'], | ||
775 | 4096, | ||
776 | p['label'], | ||
777 | rmmountdir, | ||
778 | self.skipformat, | ||
779 | fsopts = p['fsopts']) | ||
780 | pdisk.mount(pdisk.fsopts) | ||
781 | if p['fstype'] == "btrfs" and p['mountpoint'] == "/": | ||
782 | if not self.skipformat: | ||
783 | self.__create_subvolumes(p, pdisk) | ||
784 | self.__mount_subvolumes(p, pdisk) | ||
785 | p['mount'] = pdisk | ||
786 | p['uuid'] = pdisk.uuid | ||
787 | 773 | ||
788 | def resparse(self, size = None): | 774 | def resparse(self, size = None): |
789 | # Can't re-sparse a disk image - too hard | 775 | # Can't re-sparse a disk image - too hard |