diff options
Diffstat (limited to 'build_tools/larch7/larch0/cli/media_common.py')
-rw-r--r-- | build_tools/larch7/larch0/cli/media_common.py | 450 |
1 files changed, 0 insertions, 450 deletions
diff --git a/build_tools/larch7/larch0/cli/media_common.py b/build_tools/larch7/larch0/cli/media_common.py deleted file mode 100644 index b39e67d..0000000 --- a/build_tools/larch7/larch0/cli/media_common.py +++ /dev/null @@ -1,450 +0,0 @@ -#!/usr/bin/env python -# -# media_common.py -# -# (c) Copyright 2009 - 2010 Michael Towers (larch42 at googlemail dot com) -# -# This file is part of the larch project. -# -# larch is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# larch 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 larch; if not, write to the Free Software Foundation, Inc., -# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# -#---------------------------------------------------------------------------- -# 2010.07.14 - -"""This code is used by both iso generator and partition creator modules. -The larch medium creation stage first uses the Medium class to prepare the -bootloader directories. build_iso and build_partition can also be used to -rebuild media starting from existing larch media, e.g. for conversions from -CD to usb-stick and vice-versa. Even a switch of bootloader is possible as -the bootloader configs for both GRUB and syslinux/isolinux are normally -included on the medium. -If not using a larch installation directory, the bootloader and/or mkisofs -must be supported by the host (according to medium and bootloader). -""" - -import os -from config import * -from backend import * - -class Medium: - """This class represents a boot medium image. - It checks the options for conflicts. - If necessary (no -S option provided on the command line) it - converts a larchified system to a boot medium image, by preparing - the bootloader directories and adding customization stuff - from the profile, but it does not write to any medium. - """ - def __init__(self, options): - self.options = options - if options.setdir: - try: - wd = os.path.realpath(options.setdir) - os.chdir(wd) - except: - errout(_("Couldn't switch directory to '%s'") % wd) - self.iso = False - self.installation_dir = get_installation_dir() - self.installation0 = (self.installation_dir - if self.installation_dir != '/' else '') - - # Check options - if options.chroot and options.nochroot: - errout(_("Option -C conflicts with -c")) - - if options.source: - # Using a specified source image - if options.profile: - errout(_("Option -S conflicts with -p")) - - # Use chroot? - self.chrootpath = self.installation0 if options.chroot else '' - - else: - # Using the larch build system - - # Use chroot? - self.chrootpath = '' if options.nochroot else self.installation0 - - # Mount point for source, if necessary - self.mps = self.chrootpath + SOURCEMOUNT - runcmd('rm -rf %s' % self.mps) - runcmd('mkdir -p %s' % self.mps) - - # Create a temporary work area - self.build = self.chrootpath + BUILD0 - runcmd('rm -rf %s' % self.build) - runcmd('mkdir -p %s' % self.build) - - if options.source: - # Location of medium - self.medium_dir = self._get_source(options.source, - options.syslinux, self.chrootpath, test=options.testmedium) - - else: - # Location for the live medium image - self.medium_dir = self.installation0 + CHROOT_DIR_MEDIUM - self._check_larchimage(self.medium_dir) - self.profile_dir = get_profile() - - self._bootdir(options.syslinux) - self._customizelarchdir() - - # The boot directory needs to be outside of the medium directory - # for some of the next steps - runcmd('cp -a %s/boot %s' % (self.medium_dir, self.build)) - - - def unmount(self): - if self.medium_dir == self.mps: - unmount(self.mps) - - if self.iso: - if self.chrootpath: - unmount(self.chrootpath + ISOBUILDMNT) - # Change owner of iso to match current directory - cwdstat = os.stat(os.getcwd()) - os.lchown(self.iso, cwdstat.st_uid, cwdstat.st_gid) - - - def get_device_label(self, device): - l = runcmd('blkid -c /dev/null -o value -s LABEL %s' - % device)[1][0] - if self.options.detection not in detection_methods.split('|'): - errout(_("Invalid detection method (-d option)")) - return l - - - def chroot_medium_dir(self): - """Get the medium path relative within the (possible) chroot. - """ - return self.medium_dir[len(self.chrootpath):] - - - def iso_path(self): - """If building an iso within a chroot the build directory must - be bind-mounted into the accessible area. - """ - self.iso = self.options.isofile.replace('/', '_') - basedir = os.getcwd() - if self.chrootpath: - runcmd('mkdir -p %s' % (self.chrootpath + ISOBUILDMNT)) - if not mount(basedir, self.chrootpath + ISOBUILDMNT, '--bind'): - errout(_("Couldn't bind-mount current directory")) - basedir = ISOBUILDMNT - return os.path.join(basedir, self.iso) - - - def _check_larchimage(self, mediumdir): - testfile = mediumdir + '/larch/system.sqf' - if not os.path.isfile(testfile): - errout(_("File '%s' doesn't exist, '%s' is not a larch medium") - % (testfile, mediumdir)) - - - def _get_source(self, source, syslinux, ipath='', test=False): - source = os.path.realpath(source) - testcode = 64 if test else 0 # For various tests, below - - # Is source an iso? - if os.path.isfile(source): - # Mount it - if mount(source, self.mps, '-o loop'): - source = self.mps - else: - errout(_("Couldn't mount '%s'. Not an iso?") % source) - - # Is source a device? - elif source.startswith('/dev/'): - mp = _get_mountpoint(source) - if mp: - source = mp - elif mount(source, self.mps): - source = self.mps - else: - errout(_("Couldn't mount '%s'") % source) - - # Simple check that it is really a larch image - self._check_larchimage(source) - - # Check bootloader support - if not (os.path.isdir(source + '/boot/isolinux') - or os.path.isdir(source + '/boot/syslinux')): - if test or syslinux: - errout(_("Source doesn't support syslinux"), 0) - testcode += 8 - if not os.path.isdir(source + '/boot/grub'): - if test or not syslinux: - errout(_("Source doesn't support GRUB"), 0) - testcode += 16 - - if testcode: - if os.path.isfile(source + 'larch/nosave'): - testcode += 2 - - unmount() - sys.exit(testcode) - return None - - # Is source within the chroot directory? - if ipath and not source.startswith(ipath + '/'): - if mount(source, self.mps, '--bind'): - source = self.mps - else: - errout(_("Couldn't bind-mount '%s'") % source) - - # Copy boot files - runcmd('cp -a %s/boot %s' % (source, self.build)) - - # Remove old config files - runcmd('rm -f %s/boot/syslinux/syslinux.cfg' % self.build) - runcmd('rm -f %s/boot/isolinux/isolinux.cfg' % self.build) - runcmd('rm -f %s/boot/grub/menu.lst' % self.build) - runcmd('rm -f %s/boot/isolinux/isolinux.bin' % self.build) - runcmd('rm -f %s/boot/isolinux/isolinux.boot' % self.build) - - # Rename the syslinux boot directory if necessary - if os.path.isdir(self.build + '/boot/syslinux'): - runcmd('mv %s/boot/syslinux %s/boot/isolinux' - % (self.build, self.build)) - - return source - - - def _bootdir(self, syslinux): - """Prepare boot directories for the various bootloaders. The - bootloader configuration files are not generated yet, as these - depend on the medium. - """ - comment("Fetch kernel and initramfs") - if not runcmd('cp -r %s/boot %s' % (self.medium_dir, self.build))[0]: - errout(_("No kernel and/or initramfs")) - - comment("Preparing bootloader directories") - # Only include the directories if the corresponding bootloader - # package ('grub' and/or 'syslinux') is installed - grub = os.path.isfile(self.installation0 + GRUBDIR - + '/stage2_eltorito') - isolinux = os.path.isfile(self.installation0 + SYSLINUXDIR - + '/isolinux.bin') - # Check bootloader support - if syslinux: - if not isolinux: - errout(_("Installation doesn't support syslinux")) - elif not grub: - errout(_("Installation doesn't support GRUB")) - - # Bootloader independent files are provided in larch at - # cd-root/boot0. The contents of this directory are placed in the - # medium's 'boot' directory. - # Individual files can be added or substituted by - # supplying them in the profile at cd-root/boot. - # It is also possible to completely replace the basic boot directory - # by having cd-root/boot0 in the profile - then the default - # larch version will not be used. - source0 = '%s/cd-root/boot0' % self.profile_dir - if not os.path.isdir(source0): - source0 = '%s/cd-root/boot0' % base_dir - runcmd('bash -c "cp -r %s/* %s/boot"' % (source0, self.build)) - # Copy any additional profile stuff - psource = '%s/cd-root/boot' % self.profile_dir - if os.path.isdir(psource): - runcmd('cp -rf %s/* %s' % (psource, self.build)) - # Get the boot options file - bootlines = self.profile_dir + '/bootlines' - if not os.path.isfile(bootlines): - bootlines = base_dir + '/data/bootlines' - runcmd('cp -f %s %s/boot' % (bootlines, self.build)) - - # The idea is that a basic boot directory for each boot-loader is - # provided in larch at cd-root/{grub0,isolinux0}. These are copied - # to the medium as 'boot/grub' and 'boot/isolinux'. Individual files - # can be added or substituted by supplying them in the profile at - # cd-root/{grub,isolinux}. - # It is also possible to completely replace the basic boot directory - # by having cd-root/{grub0,isolinux0} in the profile - then the default - # larch versions will not be used. - for ok, boot_dir in ((grub, 'grub'), (isolinux, 'isolinux')): - if ok: - # Copy bootloader specific stuff - source0 = '%s/cd-root/%s0' % (self.profile_dir, boot_dir) - if not os.path.isdir(source0): - source0 = '%s/cd-root/%s0' % (base_dir, boot_dir) - runcmd('cp -rf %s %s/boot/%s' - % (source0, self.build, boot_dir)) - - # Copy any additional profile stuff - psource = '%s/cd-root/%s' % (self.profile_dir, boot_dir) - if os.path.isdir(psource): - runcmd('cp -rf %s %s/boot' - % (psource, self.build)) - - # Copy the grub boot files to the medium's grub directory - # and rename base config file - if grub: - runcmd('bash -c "cp %s/* %s/boot/grub"' % - (self.installation0 + GRUBDIR, self.build)) - runcmd('mv %s/boot/grub/menu.lst %s/boot/grub/menu.lst_0' - % (self.build, self.build)) - - # Copy mbr.bin, vesamenu.c32 and isolinux.bin (renamed) - # to the boot directory and rename base config file - if isolinux: - runcmd('cp %s/mbr.bin %s/boot/isolinux' % - (self.installation0 + SYSLINUXDIR, self.build)) - runcmd('cp %s/vesamenu.c32 %s/boot/isolinux' % - (self.installation0 + SYSLINUXDIR, self.build)) - runcmd('cp %s/isolinux.bin %s/boot/isolinux/isolinux.bin0' % - (self.installation0 + SYSLINUXDIR, self.build)) - runcmd(('mv %s/boot/isolinux/isolinux.cfg' - ' %s/boot/isolinux/isolinux.cfg_0') - % (self.build, self.build)) - - - def _customizelarchdir(self): - # Replace any existing larch/copy directory - runcmd('rm -rf %s/larch/copy' % self.medium_dir) - if os.path.isdir(self.profile_dir + '/cd-root/larch/copy'): - runcmd('cp -r %s/cd-root/larch/copy %s/larch' % - (self.profile_dir, self.medium_dir)) - - # Replace any existing larch/extra directory - runcmd('rm -rf %s/larch/extra' % self.medium_dir) - if os.path.isdir(self.profile_dir + '/cd-root/larch/extra'): - runcmd('cp -r %s/cd-root/larch/extra %s/larch' % - (self.profile_dir, self.medium_dir)) - - # Handle existence of larch/nosave - runcmd('rm -f %s/larch/nosave' % self.medium_dir) - if os.path.isfile(self.profile_dir + '/nosave'): - runcmd('cp %s/nosave %s/larch' % - (self.profile_dir, self.medium_dir)) - - - -def _get_mountpoint(path): - ok, lines = runcmd('cat /etc/mtab') - for l in lines: - ll = l.split() - if (len(ll) > 4) and (ll[1] == path): - return ll[0] - return '' - - -def check_label(l, n): - if isinstance(l, unicode): - l = l.encode('utf8') - if len(l) > n: - if query_yn(_("The volume label is too long. Use the default (%s)?") - % LABEL): - return LABEL - else: - errout(_("Cancelled")) - return l - - -def add_larchboot(idir): - writefile("The presence of the file 'larch/larchboot' enables\n" - "booting the device in 'search' mode.\n", idir + '/larch/larchboot') - - -def bootconfig(medium, syslinux, label='', device='', detection=''): - """Convert and complete the bootlines file. - """ - # - add boot partition to options - if detection == 'uuid': - bootp = ('uuid=' + - runcmd('blkid -c /dev/null -o value -s UUID %s' - % device)[1][0].strip()) - elif detection == 'label': - if not label: - errout(_("Can't boot to label - device has no label")) - bootp = 'label=' + label - elif detection == 'partition': - bootp = 'root=' + device - else: - bootp = '' - - # - convert bootfiles to the correct format, - # inserting necessary info - bootconf = medium + '/boot/bootlines' - if not os.path.isfile(bootconf): - errout(_("Boot configuration file '%s' not found") % bootconf) - fhi = open(bootconf) - insert = '' - i = 0 - block = '' - title = '' - opts = '' - for line in fhi: - line = line.strip() - if not line: - if title: - i += 1 - # A block is ready - - if syslinux: - # isolinux/syslinux - block += 'label %02d\n' % i - block += 'MENU LABEL %s\n' % title - block += 'kernel /boot/larch.kernel\n' - block += ('append initrd=/boot/larch.img %s %s\n' - % (bootp, opts)) - - else: - # GRUB - block += 'title %s\n' % title - block += ('kernel /boot/larch.kernel %s %s\n' - % (bootp, opts)) - block += 'initrd /boot/larch.img\n' - - if i > 1: - insert += '\n' - insert += block - block = '' - title = '' - opts = '' - - elif line.startswith('comment:'): - block += '#%s\n' % (line.split(':', 1)[1]) - - elif line.startswith('title:'): - title = line.split(':', 1)[1].lstrip() - - elif line.startswith('options:'): - opts = line.split(':', 1)[1].lstrip() - fhi.close() - - # - insert the resulting string into the bootloader config file - if syslinux: - boot_dir = ('isolinux' if os.path.isdir(medium + '/boot/isolinux') - else 'syslinux') - configfile0 = 'isolinux.cfg_0' - configfile = boot_dir + '.cfg' - else: - boot_dir = 'grub' - configfile0 = 'menu.lst_0' - configfile = 'menu.lst' - configpath = '%s/boot/%s/%s' % (medium, boot_dir, configfile0) - if not os.path.isfile(configpath): - errout(_("Base configuration file (%s) not found") % configpath) - fhi = open(configpath) - fho = open('%s/boot/%s/%s' % (medium, boot_dir, configfile), 'w') - for line in fhi: - if line.startswith("###LARCH"): - fho.write(insert) - else: - fho.write(line) - fhi.close() - fho.close() |