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 from mic import msger from mic.utils import runner from mic.utils.errors import * - +from mic.utils.oe.misc import * def find_binary_inchroot(binary, chroot): paths = ["/usr/sbin", @@ -280,6 +280,34 @@ class RawDisk(Disk): def exists(self): return True + +class DiskImage(Disk): + """ + A Disk backed by a file. + """ + def __init__(self, image_file, size): + Disk.__init__(self, size) + self.image_file = image_file + + def exists(self): + return os.path.exists(self.image_file) + + def create(self): + if self.device is not None: + return + + blocks = self.size / 1024 + if self.size - blocks * 1024: + blocks += 1 + + # create disk image + dd_cmd = "dd if=/dev/zero of=%s bs=1024 seek=%d count=1" % \ + (self.image_file, blocks) + rc, out = exec_cmd(dd_cmd) + + self.device = self.image_file + + class LoopbackDisk(Disk): """A Disk backed by a file via the loop module.""" 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): if (rc != 0): raise SquashfsError("Failed to uncompress %s." % squashfsimg) -def mkdtemp(dir = "/var/tmp", prefix = "mic-tmp-"): - """ FIXME: use the dir in mic.conf instead """ +def mkdtemp(dir = "/var/tmp", prefix = "wic-tmp-"): + """ FIXME: use the dir in wic.conf instead """ makedirs(dir) 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 @@ +# +# OpenEmbedded mic utils library +# +# Copyright (c) 2013, Intel Corporation. +# All rights reserved. +# +# 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. +# +# AUTHORS +# Tom Zanussi <tom.zanussi (at] linux.intel.com> +# 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 @@ +# ex:ts=4:sw=4:sts=4:et +# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- +# +# Copyright (c) 2013, Intel Corporation. +# All rights reserved. +# +# 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. +# +# DESCRIPTION +# This module provides a place to collect various mic-related utils +# for the OpenEmbedded Image Tools. +# +# AUTHORS +# Tom Zanussi <tom.zanussi (at] linux.intel.com> +# + +from mic import msger +from mic.utils import runner + +def exec_cmd(cmd_and_args, as_shell = False, catch = 3): + """ + Execute command, catching stderr, stdout + + Need to execute as_shell if the command uses wildcards + """ + msger.debug("exec_cmd: %s" % cmd_and_args) + args = cmd_and_args.split() + msger.debug(args) + + if (as_shell): + rc, out = runner.runtool(cmd_and_args, catch) + else: + rc, out = runner.runtool(args, catch) + out = out.strip() + msger.debug("exec_cmd: output for %s (rc = %d): %s" % \ + (cmd_and_args, rc, out)) + + if rc != 0: + # We don't throw exception when return code is not 0, because + # parted always fails to reload part table with loop devices. This + # prevents us from distinguishing real errors based on return + # code. + msger.debug("WARNING: %s returned '%s' instead of 0" % (args[0], rc)) + + return (rc, out) + + +def exec_cmd_quiet(cmd_and_args, as_shell = False): + """ + Execute command, catching nothing in the output + + Need to execute as_shell if the command uses wildcards + """ + return exec_cmd(cmd_and_args, as_shell, 0) + + +def exec_native_cmd(cmd_and_args, native_sysroot, catch = 3): + """ + Execute native command, catching stderr, stdout + + Need to execute as_shell if the command uses wildcards + + Always need to execute native commands as_shell + """ + native_paths = \ + "export PATH=%s/sbin:PATH=%s/usr/sbin:PATH=%s/usr/bin:$PATH" % \ + (native_sysroot, native_sysroot, native_sysroot) + native_cmd_and_args = "%s;%s" % (native_paths, cmd_and_args) + msger.debug("exec_native_cmd: %s" % cmd_and_args) + + args = cmd_and_args.split() + msger.debug(args) + + return exec_cmd(native_cmd_and_args, True, catch) + + +def exec_native_cmd_quiet(cmd_and_args, native_sysroot): + """ + Execute native command, catching nothing in the output + + Need to execute as_shell if the command uses wildcards + + Always need to execute native commands as_shell + """ + return exec_native_cmd(cmd_and_args, native_sysroot, 0) + + +# kickstart doesn't support variable substution in commands, so this +# is our current simplistic scheme for supporting that + +wks_vars = dict() + +def get_wks_var(key): + return wks_vars[key] + +def add_wks_var(key, val): + 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 from mic.utils.errors import MountError from mic.utils.fs_related import * from mic.utils.gpt_parser import GptParser +from mic.utils.oe.misc import * # Overhead of the MBR partitioning scheme (just one sector) MBR_OVERHEAD = 1 @@ -93,7 +94,7 @@ class PartitionedMount(Mount): self.partitions.append(part) self.__add_disk(part['disk_name']) - def add_partition(self, size, disk_name, mountpoint, fstype = None, + def add_partition(self, size, disk_name, mountpoint, source_file = None, fstype = None, label=None, fsopts = None, boot = False, align = None, part_type = None): """ Add the next partition. Prtitions have to be added in the @@ -141,6 +142,7 @@ class PartitionedMount(Mount): part = { 'ks_pnum' : ks_pnum, # Partition number in the KS file 'size': size, # In sectors 'mountpoint': mountpoint, # Mount relative to chroot + 'source_file': source_file, # partition contents 'fstype': fstype, # Filesystem type 'fsopts': fsopts, # Filesystem mount options 'label': label, # Partition label @@ -723,67 +725,51 @@ class PartitionedMount(Mount): self.snapshot_created = True + def __install_partition(self, num, source_file, start, size): + """ + Install source_file contents into a partition. + """ + if not source_file: # nothing to install + return + + # Start is included in the size so need to substract one from the end. + end = start + size - 1 + msger.debug("Installed %s in partition %d, sectors %d-%d, size %d sectors" % (source_file, num, start, end, size)) + + dd_cmd = "dd if=%s of=%s bs=%d seek=%d count=%d conv=notrunc" % \ + (source_file, self.image_file, self.sector_size, start, size) + rc, out = exec_cmd(dd_cmd) + + + def install(self, image_file): + msger.debug("Installing partitions") + + self.image_file = image_file + + 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.__install_partition(p['num'], p['source_file'], + p['start'] - 1, + d['offset'] - p['start']) + + self.__install_partition(p['num'], p['source_file'], + p['start'], p['size']) + def mount(self): for dev in self.disks.keys(): d = self.disks[dev] d['disk'].create() self.__format_disks() - self.__map_partitions() - self.__calculate_mountorder() - for mp in self.mountOrder: - p = None - for p1 in self.partitions: - if p1['mountpoint'] == mp: - p = p1 - break - - if not p['label']: - if p['mountpoint'] == "/": - p['label'] = 'platform' - else: - p['label'] = mp.split('/')[-1] - - if mp == 'swap': - import uuid - p['uuid'] = str(uuid.uuid1()) - runner.show([self.mkswap, - '-L', p['label'], - '-U', p['uuid'], - p['device']]) - continue + self.__calculate_mountorder() - rmmountdir = False - if p['mountpoint'] == "/": - rmmountdir = True - if p['fstype'] == "vfat" or p['fstype'] == "msdos": - myDiskMount = VfatDiskMount - elif p['fstype'] in ("ext2", "ext3", "ext4"): - myDiskMount = ExtDiskMount - elif p['fstype'] == "btrfs": - myDiskMount = BtrfsDiskMount - else: - raise MountError("Fail to support file system " + p['fstype']) - - if p['fstype'] == "btrfs" and not p['fsopts']: - p['fsopts'] = "subvolid=0" - - pdisk = myDiskMount(RawDisk(p['size'] * self.sector_size, p['device']), - self.mountdir + p['mountpoint'], - p['fstype'], - 4096, - p['label'], - rmmountdir, - self.skipformat, - fsopts = p['fsopts']) - pdisk.mount(pdisk.fsopts) - if p['fstype'] == "btrfs" and p['mountpoint'] == "/": - if not self.skipformat: - self.__create_subvolumes(p, pdisk) - self.__mount_subvolumes(p, pdisk) - p['mount'] = pdisk - p['uuid'] = pdisk.uuid + return def resparse(self, size = None): # Can't re-sparse a disk image - too hard |