summaryrefslogtreecommitdiffstats
path: root/build_tools/larch7/larch0/cli/media_common.py
diff options
context:
space:
mode:
Diffstat (limited to 'build_tools/larch7/larch0/cli/media_common.py')
-rw-r--r--build_tools/larch7/larch0/cli/media_common.py450
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()