summaryrefslogtreecommitdiffstats
path: root/scripts/lib/mic/utils
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib/mic/utils')
-rw-r--r--scripts/lib/mic/utils/fs_related.py30
-rw-r--r--scripts/lib/mic/utils/misc.py4
-rw-r--r--scripts/lib/mic/utils/oe/__init__.py22
-rw-r--r--scripts/lib/mic/utils/oe/misc.py108
-rw-r--r--scripts/lib/mic/utils/partitionedfs.py94
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
29from mic import msger 29from mic import msger
30from mic.utils import runner 30from mic.utils import runner
31from mic.utils.errors import * 31from mic.utils.errors import *
32 32from mic.utils.oe.misc import *
33 33
34def find_binary_inchroot(binary, chroot): 34def 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
284class 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
283class LoopbackDisk(Disk): 311class 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
515def mkdtemp(dir = "/var/tmp", prefix = "mic-tmp-"): 515def 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
28from mic import msger
29from mic.utils import runner
30
31def 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
59def 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
68def 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
88def 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
102wks_vars = dict()
103
104def get_wks_var(key):
105 return wks_vars[key]
106
107def 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
25from mic.utils.errors import MountError 25from mic.utils.errors import MountError
26from mic.utils.fs_related import * 26from mic.utils.fs_related import *
27from mic.utils.gpt_parser import GptParser 27from mic.utils.gpt_parser import GptParser
28from 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)
30MBR_OVERHEAD = 1 31MBR_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