diff options
Diffstat (limited to 'build_tools/larch8/larch0/cli/medium.py')
-rwxr-xr-x | build_tools/larch8/larch0/cli/medium.py | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/build_tools/larch8/larch0/cli/medium.py b/build_tools/larch8/larch0/cli/medium.py new file mode 100755 index 0000000..94cb0c9 --- /dev/null +++ b/build_tools/larch8/larch0/cli/medium.py @@ -0,0 +1,277 @@ +#!/usr/bin/env python2 +# +# medium.py +# +# (c) Copyright 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.11.09 + +"""This is a command line script to place a larch system on a medium. +It can handle a larchified Arch installation for the initial creation of +a larch medium (source=""), but it can also copy from one existing +medium to another, or create a boot-iso for an existing larch medium +(only relevant for partitions). +The source can be a CD/DVD, an iso file or a partition (unmounted), the +output can be an iso file or another (unmounted) partition. In the latter +case the partition detection mode can be selected and data persistence +can be enabled (or disabled). In addition, the volume label of the +destination device can be set. +Parameters are passed as options and arguments. + +A further source possiblity is an already mounted larch system, this being +specified by a source path starting with '/' (except '/dev/...'). This +option is provided for use with a running live system. +""" + + +import os +from backend import * +from media_common import * + +def build_medium(options, device): + """Copy an existing larch medium, specified by the option 'source' to + the partition specified as argument. + 'device' is the name (e.g. '/dev/sdb1') of the partition to + receive the larch image. + """ + # Basic initialisation of the larchified source + medium = Medium(options) + build = medium.build + medium_dir = medium.medium_dir + + if device: # for destination partition (not iso) + # This handles the bulk of the destination medium setup + medium.setup_destination(device) + + if options.testmedium: + return + + if options.bootiso: + unmount() + # Get bootloader configuration file + fconf = build + '/boot/isolinux/syslinux.cfg' + if not os.path.isfile(fconf): + fconf = build + '/boot/isolinux/extlinux.conf' + ok, res = runcmd('mv %s %s/boot/isolinux/isolinux.cfg' % (fconf, build)) + if not ok: + errout(_("Couldn't find boot configuration file")) + medium.mkiso() + + else: # Now not boot iso! + runcmd('rm -f %s/boot/isolinux/syslinux.cfg' % build) + runcmd('rm -f %s/boot/isolinux/extlinux.conf' % build) + + # Now, need to test for overlay.medium and/or mods.sqf - the presence + # of both is not supported here (although the larch initramfs hook + # can cope with it). + if os.path.isfile('%s/larch/overlay.medium' % medium_dir): + if os.path.isfile('%s/larch/mods.sqf' % medium_dir): + errout(_("Copying of devices with both 'overlay.medium' and 'mods.sqf'\n" + "is not supported.")) + if device and options.persist and (medium.fstype != 'vfat'): + # Copy the overlay files to the destination medium + for fd in os.listdir(medium_dir): + if (fd[0] != '.') and (fd not in IGNOREDIRS.split()): + runcmd('cp -a %s/%s %s' % (medium_dir, fd, MPD)) + + else: + # Create a modifications archive, mods.sqf + if device: + modsdst = MPD + else: + modsdst = build + runcomd('mkdir -p %s/larch' % modsdst) + if not runcmd('%s/boot/support/support mksquashfs %s %s/larch/mods.sqf' + ' -wildcards -e %s' + % (build, medium_dir, modsdst, IGNOREDIRS), + filter=mksquashfs_filter_gen())[0]: + errout(_("Squashing mods.sqf failed")) + # remove execute attrib + runcmd('chmod oga-x %s/mods.sqf' % modsdst) + + elif device and options.persist and (medium.fstype != 'vfat'): + # mods.sqf must be unpacked onto the medium + modsfile = medium_dir + '/larch/mods.sqf' + if os.path.isfile(modsfile): + runcmd('rm %s/larch/mods.sqf' % MPD) + runcmd('%s/boot/support/support unsquashfs -d %s/.mods %s/larch/mods.sqf' + % (build, MPD, medium_dir)) + if not os.path.isdir(MPD + '/.mods'): + errout(_("Unpacking of modifications archive failed, see log")) + runcmd('bash -c "mv %s/.mods/* %s"' % (MPD, MPD)) + runcmd('rm -rf %s/.mods' % MPD) + writefile("The presence of the file 'larch/overlay.medium' causes\n" + "the medium to be used as a writeable, persistent overlay\n" + "for the larch root file-system.\n", + MPD + '/larch/overlay.medium') + + if device: + # To boot in 'search' mode the file larch/larchboot must be present. + runcmd('rm -f %s/larch/larchboot' % MPD) + if options.larchboot: + add_larchboot(MPD) + + if medium.fstype != 'vfat': + # extlinux is installed to a mounted partition. + # The configuration file must be called extlinux.conf: + runcmd('mv %s/boot/isolinux/isolinux.cfg %s/boot/isolinux/extlinux.conf' + % (MPD, MPD)) + # Install extlinux + runcmd('%s/boot/support/support extlinux -i %s/boot/isolinux' + % (build, MPD)) + # Unmount device(s) + unmount() + + else: + # syslinux is installed to an unmounted partition. + # The configuration file must be called syslinux.cfg: + runcmd('mv %s/boot/isolinux/isolinux.cfg %s/boot/isolinux/syslinux.cfg' + % (MPD, MPD)) + unmount() + # Install syslinux + runcmd('%s/boot/support/support syslinux -d /boot/isolinux -i %s' + % (build, device)) + + comment(" *** %s ***" % (_("Completed writing to %s") % device)) + + else: # iso + # Write bootloader configuration file + bootconfig(build) + # At present the 'larchboot' file is not necessary for booting from + # optical media, but it should probably be present anyway. + if not os.path.isfile(medium_dir + '/larch/larchboot'): + add_larchboot(build) + + medium.mkiso(' -x %s/boot %s' % (medium_dir, medium_dir)) + unmount() + + runcmd('rm -rf %s' % build) + + + +if __name__ == '__main__': + from optparse import OptionParser, OptionGroup + parser = OptionParser(usage=_("usage: %prog [options] [partition (e.g. /dev/sdb1)]")) + + parser.add_option('-S', '--source', action='store', type="string", + dest='source', default='', + help=_("Specify source medium, an iso-file (path ending '.iso'), device" + " (starting '/dev/') or volume label")) + parser.add_option("-l", "--label", action="store", type="string", + default="", dest="label", + help=_("Volume label for boot medium (default: %s - or %s if boot iso)") + % (LABEL, BOOTISOLABEL)) + parser.add_option("-b", "--bootiso", action="store_true", + dest="bootiso", default=False, + help=_("Build a boot iso for the source partition")) + + # Options for building from larchified installation (no -S) + parser.add_option("-p", "--profile", action="store", type="string", + default="", dest="profile", + help=_("Profile: 'user:profile-name' or path to profile directory")) + parser.add_option("-i", "--installation-dir", action="store", type="string", + default="", dest="idir", + help=_("Path to larchified directory (default %s)") % INSTALLATION) + + # Options for iso output + parser.add_option("-o", "--isofile", action="store", type="string", + default="", dest="isofile", + help=_("Specify the output file (default: '%s' in the current " + "directory - or '%s' if boot iso)") % (ISOFILE, BOOTISO)) + + # Options for writing to partition + parser.add_option("-d", "--detect", action="store", type="string", + default="label", dest="detection", + help=(_("Method for boot partition detection: %s (default: label)") + % detection_methods)) + parser.add_option("-n", "--nosearchboot", action="store_false", + dest="larchboot", default=True, + help=_("Don't generate 'larch/larchboot' file")) + parser.add_option("-F", "--noformat", action="store_false", + default=True, dest="format", + help=_("Don't format the medium (WARNING: Only for experts)")) + parser.add_option("-P", "--persist", action="store_true", + dest="persist", default=False, + help=_("Enable data persistence (using medium as writeable" + " file-system). Default: disabled")) + parser.add_option("-m", "--noboot", action="store_false", + dest="mbr", default=True, + help=_("Don't install the bootloader (to the MBR)")) + parser.add_option("-j", "--nojournal", action="store_true", dest="nojournal", + default=False, help=_("Don't use journalling on boot medium" + " (default: journalling enabled)")) + + # General minor options + parser.add_option("-q", "--quiet", action="store_true", dest="quiet", + default=False, help=_("Suppress output messages, except errors" + " (no effect if -s specified)")) + parser.add_option("-s", "--slave", action="store_true", dest="slave", + default=False, help=_("Run as a slave from a controlling program" + " (e.g. from a gui)")) + parser.add_option('-T', '--testmedium', action='store_true', + dest='testmedium', default=False, + help=_("Test source or destination medium only (used by gui)")) + + (options, args) = parser.parse_args() + options.force = False + + if options.bootiso: + if args: + errout(_("Unexpected argument: %s") % args[0]) + if not options.source: + errout(_("No source specified for boot iso")) + if not options.isofile: + options.isofile = BOOTISO + if not options.label: + options.label = BOOTISOLABEL + greet = _("Generating larch boot iso file: %s\n") + else: + if not options.isofile: + options.isofile = ISOFILE + if not options.label: + options.label = LABEL + greet = _("Generating larch iso file: %s\n") + + # Location for the resulting iso, forcing a '.iso' suffix + if not options.isofile.endswith('.iso'): + options.isofile += '.iso' + + if args: + device = args[0] + if device.startswith('/dev/'): + print '##', ((_("Testing output medium: %s\n") + if options.testmedium + else _("Creating larch medium on: %s\n")) % device) + else: + print '##', (_("Invalid partition: '%s'") % device) + sys.exit(1) + else: + options.isofile = os.path.join(os.getcwd(), options.isofile) + print '##', ((_("Testing source medium: %s\n") % options.source) + if options.testmedium + else (greet % options.isofile)) + device = '' + + if os.getuid() != 0: + print _("This application must be run as root") + sys.exit(1) + + init('live_medium', options) + build_medium(options, device) |