diff options
Diffstat (limited to 'build_tools/larch7/larch0/cli')
-rwxr-xr-x | build_tools/larch7/larch0/cli/archin.py | 441 | ||||
-rwxr-xr-x | build_tools/larch7/larch0/cli/archin.py.orig | 378 | ||||
-rw-r--r-- | build_tools/larch7/larch0/cli/backend.py | 444 | ||||
-rwxr-xr-x | build_tools/larch7/larch0/cli/boot_iso.py | 154 | ||||
-rw-r--r-- | build_tools/larch7/larch0/cli/config.py | 92 | ||||
-rwxr-xr-x | build_tools/larch7/larch0/cli/larchify.py | 589 | ||||
-rwxr-xr-x | build_tools/larch7/larch0/cli/live_iso.py | 154 | ||||
-rwxr-xr-x | build_tools/larch7/larch0/cli/live_part.py | 221 | ||||
-rw-r--r-- | build_tools/larch7/larch0/cli/media_common.py | 450 | ||||
-rwxr-xr-x | build_tools/larch7/larch0/cli/test.py | 42 | ||||
-rw-r--r-- | build_tools/larch7/larch0/cli/userinfo.py | 93 |
11 files changed, 0 insertions, 3058 deletions
diff --git a/build_tools/larch7/larch0/cli/archin.py b/build_tools/larch7/larch0/cli/archin.py deleted file mode 100755 index 832d883..0000000 --- a/build_tools/larch7/larch0/cli/archin.py +++ /dev/null @@ -1,441 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# archin.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.07.19 - -# This is a command line script to perform an Arch Linux installation -# based on a list of packages. All needed parameters are passed as options. - -import os -from glob import glob -from config import * -from backend import * - -class Installation: - def __init__(self, options): - self.options = options - self.installation_dir = get_installation_dir() - if self.installation_dir == '/': - errout(_("Operations on '/' are not supported ...")) - - self.profile_dir = get_profile() - self.pacman_cmd = self.make_pacman_command() - self.make_pacman_conf() - - - def make_pacman_command(self): - """Construct pacman command. Return the command, including options. - This includes options for installation path, cache directory and - for suppressing the progress bar. It assumes a temporary location - for pacman.conf, which must also be set up. - If there is no pacman executable in the system PATH, check that - it is available in the larch directory. - """ - pacman = runcmd('bash -c "which pacman || echo _FAIL_"')[1][-1].strip() - if pacman == '_FAIL_': - # If the host is not Arch, there will probably be no pacman - # (if there is some other program called 'pacman' that's - # a real spanner in the works). - # The alternative is to provide it in the larch directory. - pacman = base_dir + '/pacman' - if not os.path.isfile(pacman): - errout(_("No pacman executable found")) - - pacman += (' -r %s --config %s --noconfirm' - % (self.installation_dir, PACMAN_CONF)) - if self.options.noprogress: - pacman += ' --noprogressbar' - if self.options.cache: - pacman += ' --cachedir ' + self.options.cache - return pacman - - - def make_pacman_conf(self, final=False): - """Construct the pacman.conf file used by larch. - To make it a little easier to manage upstream changes to the default - pacman.conf, a separate file (pacman.conf.repos) is used to specify - the repositories to use. The contents of this file are used to modify - the basic pacman.conf file, which may be the default version or one - provided in the profile. - The 'final' parameter determines whether the version for the resulting - live system (True) or for the installation process (False) is - generated. If generating the installation version, it is possible - to specify alternative repositories, via the 'repofile' option, - which allows the pacman.conf used for the installation to be - different from the version in the resulting live system. - The return value is a list of the names of the repositories which - are included. - It is also possible to specify just a customized mirrorlist for the - installation by placing it in the working directory. - """ - # Allow use of '*platform*' in pacman.conf.repos - platform = os.uname()[4] - if platform != 'x86_64': - platform = 'i686' - - # Get pacman.conf header part - pc0 = self.profile_dir + '/pacman.conf.options' - if not os.path.isfile(pc0): - pc0 = base_dir + '/data/pacman.conf' - pacmanconf = self.pacmanoptions(readfile(pc0)) - - # Get file with repository entries - pc1 = self.profile_dir + '/pacman.conf.repos' - if not os.path.isfile(pc1): - pc1 = base_dir + '/data/pacman.conf.repos' - if self.options.repofile and not final: - pc1 = os.path.realpath(self.options.repofile) - - # Get repository path - if final: - default = 'Include = /etc/pacman.d/mirrorlist' - else: - mlist = cwd + '/mirrorlist' - if not os.path.isfile(mlist): - mlist = '/etc/pacman.d/mirrorlist' - if not os.path.isfile(mlist): - mlist = base_dir + '/data/mirrorlist' - default = 'Include = ' + mlist - - # Read repository entries - repos = [] - for line in readfile(pc1).splitlines(): - line = line.strip() - if (not line) or (line[0] == '#'): - continue - r, s = [t.strip() for t in line.split(':', 1)] - repos.append(r) - s = s.replace('*default*', default) - pacmanconf += ('\n[%s]\n%s\n' - % (r, s.replace('*platform*', platform))) - - - writefile(pacmanconf, self.installation_dir + '/etc/pacman.conf' - if final else PACMAN_CONF) - return repos - - - def install(self): - """Clear the chosen installation directory and install the base - set of packages, together with any additional ones listed in the - file 'addedpacks' (in the profile), removing the packages in - 'vetopacks' from the list. - """ - if not query_yn(_("Install Arch to '%s'?") % self.installation_dir): - return False - # Can't delete the whole directory because it might be a mount point - if os.path.isdir(self.installation_dir): - if script('cleardir %s' % self.installation_dir): - return False - - # Ensure installation directory exists and check that device nodes - # can be created (creating /dev/null is also a workaround for an - # Arch bug - which may have been fixed, but this does no harm) - if not (runcmd('bash -c "mkdir -p %s/{dev,proc,sys}"' - % self.installation_dir)[0] - and runcmd('mknod -m 666 %s/dev/null c 1 3' - % self.installation_dir)[0]): - errout(_("Couldn't write to the installation path (%s)") - % self.installation_dir) - if not runcmd('bash -c "echo test >%s/dev/null"' - % self.installation_dir)[0]: - errout(_("The installation path (%s) is mounted 'nodev'.") - % self.installation_dir) - - # I should also check that it is possible to run stuff in the - # installation directory. - runcmd('bash -c "cp $( which echo ) %s"' % self.installation_dir) - if not runcmd('%s/echo "yes"' % self.installation_dir)[0]: - errout(_("The installation path (%s) is mounted 'noexec'.") - % self.installation_dir) - runcmd('rm %s/echo' % self.installation_dir) - - # Fetch package database - runcmd('mkdir -p %s/var/lib/pacman' % self.installation_dir) - self.refresh() - - # Get list of vetoed packages. - self.packages = [] - self.veto_packages = [] - self.add_packsfile(self.profile_dir, 'vetopacks', must=False) - self.veto_packages = self.packages - - # Include 'required' packages (these can still be vetoed, but - # in some cases that will mean a larch system cannot be built) - self.packages = [] - self.add_packsfile(base_dir + '/data', 'requiredpacks') - - # Add additional packages and groups, from 'addedpacks' file. - self.add_packsfile(self.profile_dir, 'addedpacks') - - # Now do the actual installation. - ok = self.pacmancall('-Sf', ' '.join(self.packages)) - if not ok: - errout(_("Package installation failed")) - - #cachepacks goes here - self.cache_packages=[] - cache_packs = self.add_cache_packsfile(self.profile_dir, 'cachepacks') - cachedir = "%s/var/cache/pacman/pkg/" % self.installation_dir - print cachedir - comment(" *** %s ***" % _("Installing Cache Packages")) - ok = self.pacmancall('-Sw --cachedir='+cachedir , ' '.join(self.cache_packages)) - if not ok: - errout(_("Package installation failed")) - - # Some chroot scripts might need /etc/mtab - runcmd('bash -c ":> %s/etc/mtab"' % self.installation_dir) - - # Build the final version of pacman.conf - self.make_pacman_conf(True) - - #post_process goes here - comment(" *** %s ***" % _("Start of post processing")) - post_process_file="%s/post-process.sh" %self.profile_dir - #try: - if os.path.isfile(post_process_file): - cmd = "%s %s %s" %(post_process_file,self.installation_dir,self.profile_dir) - print "this is my cmd: %s" %cmd - runcmd(cmd) - else: - #except: - comment(" *** %s ***" % _("Post processing file not found")) - # pass - ##run script to post-process the new installation - #if [ -f ${PROFILE}/post-process.sh ] - #then - # ${PROFILE}/post-process.sh ${INSTLDIR} ${PROFILE} - # echo ${PROFILE}/post-process.sh ${INSTLDIR} ${PROFILE} - #fi - # - - comment(" *** %s ***" % _("Arch installation completed")) - return True - - - def add_packsfile(self, dir, packs_file, must=True): - path = dir + '/' + packs_file - if must and not os.path.isfile(path): - errout(_("No '%s' file") % path) - fh = open(path) - for line in fh: - line = line.strip() - if line and (line[0] != '#'): - if line[0] == '*': - self.add_group(line[1:].split()[0]) - elif line[0] == '+': - # Include directive - line = line[1:].split()[0] - if line[0] != '/': - line = dir + '/' + line - d, pf = line.rsplit('/', 1) - if not d: - errout(_("Invalid package file include: %s")) - self.add_packsfile(d, pf) - elif line.startswith('!!!'): - # Ignore everything (!) entered previously. - # Allows requiredpacks to be overridden in addedpacks. - self.packages = [] - else: - line = line.split()[0] - if ((line not in self.packages) - and (line not in self.veto_packages)): - self.packages.append(line) - fh.close() - - def add_cache_packsfile(self, dir, packs_file, must=True): - path = dir + '/' + packs_file - if must and not os.path.isfile(path): - errout(_("No '%s' file") % path) - fh = open(path) - for line in fh: - line = line.strip() - if line and (line[0] != '#'): - if line[0] == '*': - self.add_group(line[1:].split()[0]) - elif line[0] == '+': - # Include directive - line = line[1:].split()[0] - if line[0] != '/': - line = dir + '/' + line - d, pf = line.rsplit('/', 1) - if not d: - errout(_("Invalid package file include: %s")) - print "calling myself with %s %s" %(d,pf) - self.add_cache_packsfile(d, pf) - - elif line.startswith('!!!'): - # Ignore everything (!) entered previously. - # Allows requiredpacks to be overridden in addedpacks. - self.cache_packages = [] - else: - line = line.split()[0] - if ((line not in self.cache_packages) and (line not in self.veto_packages)): - self.cache_packages.append(line) - fh.close() - - - def add_group(self, gname): - """Add the packages belonging to a group to the installaion list, - removing any in the veto list. - """ - # In the next line the call could be done as a normal user. - for line in runcmd('%s -Sg %s' % (self.pacman_cmd, gname))[1]: - l = line.split() - if l and (l[0] == gname) and (l[1] not in self.veto_packages): - self.packages.append(l[1]) - - - def refresh(self): - """This updates or creates the pacman-db in the installation. - This is done using using 'pacman ... -Sy' together with the - customized pacman.conf file. - """ - if not runcmd(self.pacman_cmd + ' -Sy', - filter=pacman_filter_gen())[0]: - errout(_("Couldn't synchronize pacman database (pacman -Sy)")) - return True - - - def pacmancall(self, op, arg): - """Mount-bind the sys and proc directories before calling the - pacman command built by make_pacman_command to perform operation - 'op' (e.g. '-S') with argument(s) 'arg' (a string). - Then unmount sys and proc and return True if the command succeeded. - """ - # (a) Prepare the destination environment (bind mounts) - mount("/sys", "%s/sys" % self.installation_dir, "--bind") - mount("/proc", "%s/proc" % self.installation_dir, "--bind") - - # (b) Call pacman - ok = runcmd("%s %s %s" % (self.pacman_cmd, op, arg), - filter=pacman_filter_gen())[0] - - # (c) Remove bound mounts - unmount(("%s/sys" % self.installation_dir, - "%s/proc" % self.installation_dir)) - return ok - - - def pacmanoptions(self, text): - """A filter for pacman.conf to remove the repository info. - """ - texto = "" - block = "" - for line in text.splitlines(): - block += line + "\n" - if line.startswith("#["): - break - if line.startswith("[") and not line.startswith("[options]"): - break - if not line.strip(): - texto += block - block = "" - return texto - - - def sync(self, *packs): - return self.pacmancall('-S', ' '.join(packs)) - - - def update(self, *files): - return self.pacmancall('-U', ' '.join(files)) - - - def remove(self, *packs): - return self.pacmancall('-Rs', ' '.join(packs)) - - - -if __name__ == "__main__": - start_translator() - cwd = os.getcwd() - - operations = 'install|sync|update|remove|refresh' - from optparse import OptionParser, OptionGroup - parser = OptionParser(usage=(_("usage: %%prog [options] %s [packages]") - % operations)) - - 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 directory to be larchified (default %s)") - % INSTALLATION) - 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("-q", "--quiet", action="store_true", dest="quiet", - default=False, help=_("Suppress output messages, except errors" - " (no effect if -s specified)")) - - - parser.add_option("-f", "--force", action="store_true", dest="force", - default=False, help=_("Don't ask for confirmation")) - - parser.add_option("-r", "--repofile", action="store", type="string", - default="", dest="repofile", - help=_("Supply a substitute repository list (pacman.conf.repos)" - " for the installation only")) - parser.add_option("-c", "--cache-dir", action="store", type="string", - default="", dest="cache", - help=_("pacman cache directory (default /var/cache/pacman/pkg)")) - parser.add_option("-n", "--noprogress", action="store_true", - dest="noprogress", - default=False, help=_("Don't show pacman's progress bar")) -## I think pacman is going to get support for something like '$arch', at -## which stage I could again consider architecture switching support in larch. -# parser.add_option("-a", "--arch", action="store", type="string", -# default="", dest="arch", -# help=_("processor architecture (x86_64|i686) - defaults to" -# " that of the host." -# " This is an untested feature, which is probably only partially" -# " implemented and may well not work.")) - - (options, args) = parser.parse_args() - if not args: - print _("You must specify which operation to perform:\n") - parser.print_help() - sys.exit(1) - - if os.getuid() != 0: - print _("This application must be run as root") - sys.exit(1) - - init('archin', options) - op = args[0] - if op not in operations.split('|'): - print (_("Invalid operation: '%s'\n") % op) - parser.print_help() - sys.exit(1) - - installation = Installation(options) - method = getattr(installation, op) - - if method(*args[1:]): - sys.exit(0) - else: - sys.exit(1) - diff --git a/build_tools/larch7/larch0/cli/archin.py.orig b/build_tools/larch7/larch0/cli/archin.py.orig deleted file mode 100755 index 7e00831..0000000 --- a/build_tools/larch7/larch0/cli/archin.py.orig +++ /dev/null @@ -1,378 +0,0 @@ -#!/usr/bin/env python -# -# archin.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.07.19 - -# This is a command line script to perform an Arch Linux installation -# based on a list of packages. All needed parameters are passed as options. - -import os -from glob import glob -from config import * -from backend import * - -class Installation: - def __init__(self, options): - self.options = options - self.installation_dir = get_installation_dir() - if self.installation_dir == '/': - errout(_("Operations on '/' are not supported ...")) - - self.profile_dir = get_profile() - self.pacman_cmd = self.make_pacman_command() - self.make_pacman_conf() - - - def make_pacman_command(self): - """Construct pacman command. Return the command, including options. - This includes options for installation path, cache directory and - for suppressing the progress bar. It assumes a temporary location - for pacman.conf, which must also be set up. - If there is no pacman executable in the system PATH, check that - it is available in the larch directory. - """ - pacman = runcmd('bash -c "which pacman || echo _FAIL_"')[1][-1].strip() - if pacman == '_FAIL_': - # If the host is not Arch, there will probably be no pacman - # (if there is some other program called 'pacman' that's - # a real spanner in the works). - # The alternative is to provide it in the larch directory. - pacman = base_dir + '/pacman' - if not os.path.isfile(pacman): - errout(_("No pacman executable found")) - - pacman += (' -r %s --config %s --noconfirm' - % (self.installation_dir, PACMAN_CONF)) - if self.options.noprogress: - pacman += ' --noprogressbar' - if self.options.cache: - pacman += ' --cachedir ' + self.options.cache - return pacman - - - def make_pacman_conf(self, final=False): - """Construct the pacman.conf file used by larch. - To make it a little easier to manage upstream changes to the default - pacman.conf, a separate file (pacman.conf.repos) is used to specify - the repositories to use. The contents of this file are used to modify - the basic pacman.conf file, which may be the default version or one - provided in the profile. - The 'final' parameter determines whether the version for the resulting - live system (True) or for the installation process (False) is - generated. If generating the installation version, it is possible - to specify alternative repositories, via the 'repofile' option, - which allows the pacman.conf used for the installation to be - different from the version in the resulting live system. - The return value is a list of the names of the repositories which - are included. - It is also possible to specify just a customized mirrorlist for the - installation by placing it in the working directory. - """ - # Allow use of '*platform*' in pacman.conf.repos - platform = os.uname()[4] - if platform != 'x86_64': - platform = 'i686' - - # Get pacman.conf header part - pc0 = self.profile_dir + '/pacman.conf.options' - if not os.path.isfile(pc0): - pc0 = base_dir + '/data/pacman.conf' - pacmanconf = self.pacmanoptions(readfile(pc0)) - - # Get file with repository entries - pc1 = self.profile_dir + '/pacman.conf.repos' - if not os.path.isfile(pc1): - pc1 = base_dir + '/data/pacman.conf.repos' - if self.options.repofile and not final: - pc1 = os.path.realpath(self.options.repofile) - - # Get repository path - if final: - default = 'Include = /etc/pacman.d/mirrorlist' - else: - mlist = cwd + '/mirrorlist' - if not os.path.isfile(mlist): - mlist = '/etc/pacman.d/mirrorlist' - if not os.path.isfile(mlist): - mlist = base_dir + '/data/mirrorlist' - default = 'Include = ' + mlist - - # Read repository entries - repos = [] - for line in readfile(pc1).splitlines(): - line = line.strip() - if (not line) or (line[0] == '#'): - continue - r, s = [t.strip() for t in line.split(':', 1)] - repos.append(r) - s = s.replace('*default*', default) - pacmanconf += ('\n[%s]\n%s\n' - % (r, s.replace('*platform*', platform))) - - - writefile(pacmanconf, self.installation_dir + '/etc/pacman.conf' - if final else PACMAN_CONF) - return repos - - - def install(self): - """Clear the chosen installation directory and install the base - set of packages, together with any additional ones listed in the - file 'addedpacks' (in the profile), removing the packages in - 'vetopacks' from the list. - """ - if not query_yn(_("Install Arch to '%s'?") % self.installation_dir): - return False - # Can't delete the whole directory because it might be a mount point - if os.path.isdir(self.installation_dir): - if script('cleardir %s' % self.installation_dir): - return False - - # Ensure installation directory exists and check that device nodes - # can be created (creating /dev/null is also a workaround for an - # Arch bug - which may have been fixed, but this does no harm) - if not (runcmd('bash -c "mkdir -p %s/{dev,proc,sys}"' - % self.installation_dir)[0] - and runcmd('mknod -m 666 %s/dev/null c 1 3' - % self.installation_dir)[0]): - errout(_("Couldn't write to the installation path (%s)") - % self.installation_dir) - if not runcmd('bash -c "echo test >%s/dev/null"' - % self.installation_dir)[0]: - errout(_("The installation path (%s) is mounted 'nodev'.") - % self.installation_dir) - - # I should also check that it is possible to run stuff in the - # installation directory. - runcmd('bash -c "cp $( which echo ) %s"' % self.installation_dir) - if not runcmd('%s/echo "yes"' % self.installation_dir)[0]: - errout(_("The installation path (%s) is mounted 'noexec'.") - % self.installation_dir) - runcmd('rm %s/echo' % self.installation_dir) - - # Fetch package database - runcmd('mkdir -p %s/var/lib/pacman' % self.installation_dir) - self.refresh() - - # Get list of vetoed packages. - self.packages = [] - self.veto_packages = [] - self.add_packsfile(self.profile_dir, 'vetopacks', must=False) - self.veto_packages = self.packages - - # Include 'required' packages (these can still be vetoed, but - # in some cases that will mean a larch system cannot be built) - self.packages = [] - self.add_packsfile(base_dir + '/data', 'requiredpacks') - - # Add additional packages and groups, from 'addedpacks' file. - self.add_packsfile(self.profile_dir, 'addedpacks') - - # Now do the actual installation. - ok = self.pacmancall('-Sf', ' '.join(self.packages)) - if not ok: - errout(_("Package installation failed")) - - # Some chroot scripts might need /etc/mtab - runcmd('bash -c ":> %s/etc/mtab"' % self.installation_dir) - - # Build the final version of pacman.conf - self.make_pacman_conf(True) - comment(" *** %s ***" % _("Arch installation completed")) - return True - - - def add_packsfile(self, dir, packs_file, must=True): - path = dir + '/' + packs_file - if must and not os.path.isfile(path): - errout(_("No '%s' file") % path) - fh = open(path) - for line in fh: - line = line.strip() - if line and (line[0] != '#'): - if line[0] == '*': - self.add_group(line[1:].split()[0]) - elif line[0] == '+': - # Include directive - line = line[1:].split()[0] - if line[0] != '/': - line = dir + '/' + line - d, pf = line.rsplit('/', 1) - if not d: - errout(_("Invalid package file include: %s")) - self.add_packsfile(d, pf) - elif line.startswith('!!!'): - # Ignore everything (!) entered previously. - # Allows requiredpacks to be overridden in addedpacks. - self.packages = [] - else: - line = line.split()[0] - if ((line not in self.packages) - and (line not in self.veto_packages)): - self.packages.append(line) - fh.close() - - - def add_group(self, gname): - """Add the packages belonging to a group to the installaion list, - removing any in the veto list. - """ - # In the next line the call could be done as a normal user. - for line in runcmd('%s -Sg %s' % (self.pacman_cmd, gname))[1]: - l = line.split() - if l and (l[0] == gname) and (l[1] not in self.veto_packages): - self.packages.append(l[1]) - - - def refresh(self): - """This updates or creates the pacman-db in the installation. - This is done using using 'pacman ... -Sy' together with the - customized pacman.conf file. - """ - if not runcmd(self.pacman_cmd + ' -Sy', - filter=pacman_filter_gen())[0]: - errout(_("Couldn't synchronize pacman database (pacman -Sy)")) - return True - - - def pacmancall(self, op, arg): - """Mount-bind the sys and proc directories before calling the - pacman command built by make_pacman_command to perform operation - 'op' (e.g. '-S') with argument(s) 'arg' (a string). - Then unmount sys and proc and return True if the command succeeded. - """ - # (a) Prepare the destination environment (bind mounts) - mount("/sys", "%s/sys" % self.installation_dir, "--bind") - mount("/proc", "%s/proc" % self.installation_dir, "--bind") - - # (b) Call pacman - ok = runcmd("%s %s %s" % (self.pacman_cmd, op, arg), - filter=pacman_filter_gen())[0] - - # (c) Remove bound mounts - unmount(("%s/sys" % self.installation_dir, - "%s/proc" % self.installation_dir)) - return ok - - - def pacmanoptions(self, text): - """A filter for pacman.conf to remove the repository info. - """ - texto = "" - block = "" - for line in text.splitlines(): - block += line + "\n" - if line.startswith("#["): - break - if line.startswith("[") and not line.startswith("[options]"): - break - if not line.strip(): - texto += block - block = "" - return texto - - - def sync(self, *packs): - return self.pacmancall('-S', ' '.join(packs)) - - - def update(self, *files): - return self.pacmancall('-U', ' '.join(files)) - - - def remove(self, *packs): - return self.pacmancall('-Rs', ' '.join(packs)) - - - -if __name__ == "__main__": - start_translator() - cwd = os.getcwd() - - operations = 'install|sync|update|remove|refresh' - from optparse import OptionParser, OptionGroup - parser = OptionParser(usage=(_("usage: %%prog [options] %s [packages]") - % operations)) - - 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 directory to be larchified (default %s)") - % INSTALLATION) - 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("-q", "--quiet", action="store_true", dest="quiet", - default=False, help=_("Suppress output messages, except errors" - " (no effect if -s specified)")) - - - parser.add_option("-f", "--force", action="store_true", dest="force", - default=False, help=_("Don't ask for confirmation")) - - parser.add_option("-r", "--repofile", action="store", type="string", - default="", dest="repofile", - help=_("Supply a substitute repository list (pacman.conf.repos)" - " for the installation only")) - parser.add_option("-c", "--cache-dir", action="store", type="string", - default="", dest="cache", - help=_("pacman cache directory (default /var/cache/pacman/pkg)")) - parser.add_option("-n", "--noprogress", action="store_true", - dest="noprogress", - default=False, help=_("Don't show pacman's progress bar")) -## I think pacman is going to get support for something like '$arch', at -## which stage I could again consider architecture switching support in larch. -# parser.add_option("-a", "--arch", action="store", type="string", -# default="", dest="arch", -# help=_("processor architecture (x86_64|i686) - defaults to" -# " that of the host." -# " This is an untested feature, which is probably only partially" -# " implemented and may well not work.")) - - (options, args) = parser.parse_args() - if not args: - print _("You must specify which operation to perform:\n") - parser.print_help() - sys.exit(1) - - if os.getuid() != 0: - print _("This application must be run as root") - sys.exit(1) - - init('archin', options) - op = args[0] - if op not in operations.split('|'): - print (_("Invalid operation: '%s'\n") % op) - parser.print_help() - sys.exit(1) - - installation = Installation(options) - method = getattr(installation, op) - - if method(*args[1:]): - sys.exit(0) - else: - sys.exit(1) - diff --git a/build_tools/larch7/larch0/cli/backend.py b/build_tools/larch7/larch0/cli/backend.py deleted file mode 100644 index 95b01bd..0000000 --- a/build_tools/larch7/larch0/cli/backend.py +++ /dev/null @@ -1,444 +0,0 @@ -# backend.py - for the cli modules: handles processes and io -# -# (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.07.14 - -# There was also the vague idea of a web interface, using a sort of state- -# based approach. Connecting to a running larch process would then require -# the ability to get the logging history, but presumably not the whole -# history on every ui update, which would need to be incremental. -# The logging function would need to be modified to accommodate this. - -import os, sys, signal, atexit, __builtin__ -import traceback, pwd -from subprocess import Popen, PIPE, STDOUT -import pexpect -try: - import json as serialize -except: - import simplejson as serialize -from config import * - -def init(app, options, app_quit=None): - global _options, _quit_function, _log, _controlled, _dontask, _quiet - _options = options - _quit_function = app_quit - _controlled = options.slave - _dontask = options.force - _log = None - _quiet = False if _controlled else options.quiet - - atexit.register(sys_quit) - - - def sigint(num, frame): - """A handler for SIGINT. Tidy up properly and quit. - """ - errout("INTERRUPTED - killing subprocesses", 0) - if _sub_process and _sub_process.pid: - Popen(["pkill", "-g", str(_sub_process.pid)], - stdout=PIPE).communicate() - errout("QUITTING", 2) - signal.signal(signal.SIGINT, sigint) - - - # Check no other instance of the script is running - if os.path.isfile(LOCKFILE): - app0 = readfile(LOCKFILE) - if not query_yn(_( - "larch (%s) seems to be running already." - "\nIf you are absolutely sure this is not the case," - "\nyou may continue. Otherwise you should cancel." - "\n\nShall I continue?") % app0): - sys.exit(102) - writefile(app, LOCKFILE) - _log = open(LOGFILE + app, 'w') - - # For systems without /sbin and /usr/sbin in the normal PATH - p = os.environ['PATH'] - ps = p.split(':') - for px in ('/sbin', '/usr/sbin'): - if px not in ps: - p = px + ':' + p - os.environ['PATH'] = p - - -def _out(text, force=False): - """Send the string to standard output. - How it is output depends on the '-s' command line option (whether the - script is being run on the console or as a subprocess of another script). - In the latter case the text will be slightly encoded - to avoid newline - characters - and sent as a single unit. - Otherwise output the lines as they are, but all lines except - the first get a '--' prefix. - """ - lines = text.encode('utf-8').splitlines() - if _log: - _log.write(lines[0] + '\n') - for l in lines[1:]: - _log.write('--' + l + '\n') - - if force or not _quiet: - if _controlled: - sys.stdout.write(serialize.dumps(text) + '\n') - else: - prefix = '' - for line in lines: - sys.stdout.write(prefix + line + '\n') - prefix = '--' - sys.stdout.flush() - - -def sys_quit(): - unmount() - if _quit_function: - _quit_function() - if _errorcount: - _out('!! ' + (_("The backend reported %d failed calls," - " you may want to investigate") % _errorcount)) - if _log: - _log.close() - os.remove(LOCKFILE) - - -def comment(text): - _out('##' + text) - - -def query_yn(message, default=False): - _out('?>' + message) - result = default - if _dontask: - result = True - elif not _quiet: - if _controlled: - result = (raw_input().strip() == '??YES') - - else: - # The character after '_' is the response key - # The default will be capitalized automatically - prompt = _("_yes|_no").split('|') - promptkey = [word[word.index('_') + 1] for word in prompt] - if default: - py = prompt[0].upper() - pn = prompt[1] - else: - py = prompt[0] - pn = prompt[1].upper() - resp = raw_input(" [ %s / %s ]: " % (py, pn)).strip() - if resp: - testkey = promptkey[1] if default else promptkey[0] - resp == resp.lower() - if resp == prompt[0]: - result = True - elif resp == prompt[1]: - result = False - elif testkey in resp: - result = not default - - _out('#>%s' % ('Yes' if result else 'No')) - return result - - -def errout(message="ERROR", quit=1): - _out('!>' + message, True) - if quit: - sys_quit() - os._exit(quit) - - -def error0(message): - errout(message, 0) -__builtin__.error0 = error0 - - -# Catch all unhandled errors. -def errortrap(type, value, tb): - etext = "".join(traceback.format_exception(type, value, tb)) - errout(_("Something went wrong:\n") + etext, 100) -sys.excepthook = errortrap - - -_sub_process = None -_errorcount = 0 -def runcmd(cmd, filter=None): - global _sub_process, _errorcount - _out('>>' + cmd) - _sub_process = pexpect.spawn(cmd) - result = [] - line0 = '' - # A normal end-of-line is '\r\n', so split on '\r' but don't - # process a line until the next character is available. - while True: - try: - line0 += _sub_process.read_nonblocking(size=256, timeout=None) - except: - break - - while True: - lines = line0.split('\r', 1) - if (len(lines) > 1) and lines[1]: - line = lines[0] - line0 = lines[1] - nl = (line0[0] == '\n') - if nl: - # Strip the '\n' - line0 = line0[1:] - if filter: - line = filter(line, nl) - if line == '/*/': - continue - if nl: - line = line.rstrip() - _out('>_' + line) - result.append(line) - else: - # Probably a progress line - if _controlled: - _out('>-' + line) - else: - sys.stdout.write(line + '\r') - sys.stdout.flush() - - else: - break - - _sub_process.close() - rc = _sub_process.exitstatus - ok = (rc == 0) - if not ok: - _errorcount += 1 - _out(('>?%s' % repr(rc)) + ('' if ok else (' $$$ %s $$$' % cmd))) - return (ok, result) - - -def script(cmd): - s = runcmd("%s/%s" % (script_dir, cmd)) - if s[0]: - return "" - else: - return "SCRIPT ERROR: (%s)\n" % cmd + "".join(s[1]) - - -def chroot(ip, cmd, mnts=[], filter=None): - if ip: - for m in mnts: - mount("/" + m, "%s/%s" % (ip, m), "--bind") - cmd = "chroot %s %s" % (ip, cmd) - - s = runcmd(cmd, filter) - - if ip: - unmount(["%s/%s" % (ip, m) for m in mnts]) - - if s[0]: - if s[1]: - return s[1] - else: - return True - return False - - -_mounts = [] -def mount(src, dst, opts=""): - if runcmd("mount %s %s %s" % (opts, src, dst))[0]: - _mounts.append(dst) - return True - return False - - -def unmount(dst=None): - if dst == None: - mnts = list(_mounts) - elif type(dst) in (list, tuple): - mnts = list(dst) - else: - mnts = [dst] - - r = True - for m in mnts: - if runcmd("umount %s" % m)[0]: - _mounts.remove(m) - else: - r = False - return r - - -def get_installation_dir(): - return os.path.realpath(_options.idir if _options.idir - else INSTALLATION) - - -def get_profile(): - """Get the absolute path to the profile folder given its path in any - acceptable form, including 'user:profile-name' - """ - pd = (_options.profile if _options.profile - else base_dir + '/profiles/default') - p = pd.split(':') - if len(p) == 1: - pd = os.path.realpath(pd) - else: - try: - pd = (pwd.getpwnam(p[0])[5] + PROFILE_DIR - + '/' + p[1]) - except: - errout(_("Invalid profile: %s") % pd, quit=0) - raise - if not os.path.isfile(pd + '/addedpacks'): - errout(_("Invalid profile folder: %s") % pd) - return pd - - - -#+++++++++++++++++++++++++++++++++++++++++ -#Regular expression search strings for progress reports -import re -#lit: give []() a \-prefix -#grp: surround string in () -#opt: surround string in [] - -def _lit(s): - for c in r'[()]': - s = s.replace(c, '\\' + c) - return s - -def _grp(s, x=''): - return '(' + s + ')' + x - -def _grp0(s, x=''): - return '(?:' + s + ')' + x - -def _opt(s, x=''): - return '[' + s + ']' + x - - -_re_pacman = re.compile( _grp0(_lit('(') + - _grp(_opt('^/', '+') + '/' + _opt('^)', '+')) + - _lit(')'), '?') + - _grp('.*?') + - _lit('[') + _grp(_opt('-#', '+')) + _lit(r']\s+') + - _grp(_opt('0-9', '+')) + - '%' - ) - -_re_mksquashfs = re.compile(_lit('[.*]') + - _grp('.* ' + - _grp(_opt('0-9', '+')) + - '%') - ) - -_re_mkisofs = re.compile(_opt(' 1') + _opt(' \d') + '\d\.\d\d%') - -#----------------------------------------- -class pacman_filter_gen: - """Return a function to detect and process the progress output of - pacman. - """ - def __init__(self): - self.progress = '' - - def __call__(self, line, nl): - ms = _re_pacman.match(line) - if ms: - p = ms.group(3) - if (self.progress != p) or nl: - self.progress = p - if _controlled: - xfromy = ms.group(1) - if not xfromy: - xfromy = '' - return 'pacman:%s|%s|%s' % (xfromy, ms.group(2), - ms.group(4)) - if nl: - sys.stdout.write(' '*80 + '\r') - return line.rsplit(None, 1)[0] - else: - return '/*/' - return line - - -class mksquashfs_filter_gen: - """Return a function to detect and process the progress output of - mksquashfs. - """ - def __init__(self): - self.progress = '' - - def __call__(self, line, nl): - ms = _re_mksquashfs.match(line) - if ms: - percent = ms.group(2) - if (self.progress != percent) or nl: - self.progress = percent - if _controlled: - return 'mksquashfs:' + ms.group(1) - return re.sub(r'=[-\\/|]', '= ', line) - else: - return '/*/' - return line - - -class mkisofs_filter_gen: - """Return a function to detect and process the progress output of - mkisofs. - """ - def __call__(self, line, nl): - ms = _re_mkisofs.match(line) - if ms: - if _controlled: - return 'mkisofs:' + line - sys.stdout.write(line + '\r') - sys.stdout.flush() - return '/*/' - return line - - -def readdata(filename): - return readfile(base_dir + '/data/' + filename) - - -def readfile(fpath): - try: - fh = open(fpath) - text = fh.read() - fh.close() - except: - errout(_("Couldn't read file: %s") % fpath) - return None - return text - - -def writefile(text, path): - try: - pd = os.path.dirname(path) - if not os.path.isdir(pd): - os.makedirs(pd) - fh = None - fh = open(path, 'w') - fh.write(text) - return True - except: - return False - finally: - if fh: - fh.close() - diff --git a/build_tools/larch7/larch0/cli/boot_iso.py b/build_tools/larch7/larch0/cli/boot_iso.py deleted file mode 100755 index 19c3510..0000000 --- a/build_tools/larch7/larch0/cli/boot_iso.py +++ /dev/null @@ -1,154 +0,0 @@ -#!/usr/bin/env python -# -# live_part.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.12 - -"""This is a command line script to prepare a boot 'iso' for a USB larch -device, to make this bootable via CD on systems which cannot boot from USB -devices. -Parameters are passed as options and arguments. -""" - -import os -from config import * -from backend import * -from media_common import * - -def build_bootiso(options, devicename): - """Create a boot iso for the specified medium. - 'devicename' is the name (e.g. 'sdb1', without '/dev/') of the - source partition. - """ - # Check device - device = '/dev/' + devicename - if not os.path.exists(device): - errout(_("Invalid device: %s") % device) - options.source = device - medium = Medium(options) - ipath = medium.chrootpath - build = medium.build - - # Need to get the label - label = medium.get_device_label(device) - - # Write bootloader configuration file - bootconfig(build, options.syslinux, label, device, options.detection) - - # Select bootloader - if options.syslinux: - # Get fresh isolinux.bin - runcmd('cp %s/boot/isolinux/isolinux.bin0 %s/boot/isolinux/isolinux.bin' - % (build, build)) - parms = '-b boot/isolinux/isolinux.bin -c boot/isolinux/isolinux.boot' - # Select bootloader - else: - parms = '-b boot/grub/stage2_eltorito' - - # Need to adjust paths to cater for chroot! - source0 = medium.chroot_medium_dir() - isopath0 = medium.iso_path() - - # Actually the volume label can be 32 bytes, but 16 is compatible - # with ext2 (though a little longer than vfat) - label = check_label(options.label, 16) - # Build iso - if not chroot(ipath, ('mkisofs -R -l %s -no-emul-boot -boot-load-size 4' - ' -boot-info-table -input-charset=UTF-8' - ' -V "%s"' - ' -o "%s"' - ' "%s"') % (parms, label, isopath0, BUILD0), - filter=mkisofs_filter_gen()): - - errout(_("iso build failed")) - - medium.unmount() - runcmd('rm -rf %s' % build) - - comment(" *** %s ***" % (_("%s was successfully created") - % (options.isofile))) - - - -if __name__ == '__main__': - start_translator() - - from optparse import OptionParser, OptionGroup - parser = OptionParser(usage=_("usage: %prog [options] partition" - " (e.g. sdb1)")) - - parser.add_option("-o", "--isofile", action="store", type="string", - default=BOOTISO, dest="isofile", - help=_("Specify the output file (default '%s'). It will be" - " generated to the current directory.") % BOOTISO) - parser.add_option("-D", "--setdir", action="store", type="string", - dest='setdir', default='', - help=_("Set current directory," - " so that the 'iso' can be placed there")) - 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("-b", "--syslinux", action="store_true", dest="syslinux", - default=False, help=_("Use the syslinux bootloader" - " (the default is GRUB)")) - - parser.add_option("-i", "--installation-dir", action="store", type="string", - default="", dest="idir", - help=_("Path to larchified directory (default %s)") % INSTALLATION) - 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("-q", "--quiet", action="store_true", dest="quiet", - default=False, help=_("Suppress output messages, except errors" - " (no effect if -s specified)")) - - parser.add_option("-f", "--force", action="store_true", dest="force", - default=False, help=_("Don't ask for confirmation")) - - parser.add_option("-l", "--label", action="store", type="string", - default=ISOLABEL, dest="label", - help=_("Volume label for boot iso (default %s)") - % ISOLABEL) - parser.add_option("-C", "--chroot", action="store_true", - dest="chroot", default=False, - help=_("Use chroot for build")) - - - (options, args) = parser.parse_args() - if not args: - print _("You must specify the source partition\n") - parser.print_help() - sys.exit(1) - - if os.getuid() != 0: - print _("This application must be run as root") - sys.exit(1) - - init('live_part', options) - - # To avoid error messages - options.profile = None - options.nochroot = None - options.testmedium = False - - build_bootiso(options, devicename=args[0]) diff --git a/build_tools/larch7/larch0/cli/config.py b/build_tools/larch7/larch0/cli/config.py deleted file mode 100644 index 14f3329..0000000 --- a/build_tools/larch7/larch0/cli/config.py +++ /dev/null @@ -1,92 +0,0 @@ -# config.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.07.13 - -# Basic (default) configuration information for larch -# Some of these can be changed ...???? - -# Default volume label -LABEL = 'LARCH-7.2' -# Default iso file -ISOFILE = 'linhes.iso' -# Default volume label for boot iso -ISOLABEL = 'LARCH-7-BOOT' -# Default boot iso file -BOOTISO = 'larch7boot.iso' -# Used as a mount point -MP = '/tmp/larch_mnt' -# Mount point (within chroot) for bind-mounting iso build directory -ISOBUILDMNT = '/tmp/isodir_mnt' -# Mount point for medium sources -SOURCEMOUNT = '/tmp/larch_mntsrc' -# Temporary directory for building medium boot directory -BUILD0 = '/tmp/larch_build' - -SYSLINUXDIR = '/usr/lib/syslinux' -GRUBDIR = '/usr/lib/grub/i386-pc' - -# A customized pacman.conf file is used for the installation, generated -# dynamically according to the options and the profile. -PACMAN_CONF = '/tmp/larch_pacman.conf' - -# Medium detection alternatives -detection_methods = 'label|uuid|device|search' - -# Some basic paths -import os, sys -module_dir = os.path.dirname(os.path.realpath(__file__)) -base_dir = os.path.dirname(module_dir) -script_dir = base_dir + '/buildscripts' - -# File to prevent two instances of larch from running -LOCKFILE = '/tmp/larch_lock' -# File (stem) for log -LOGFILE = '/tmp/larch_log_' -# The path to the Arch installation which is to be larchified -INSTALLATION = '/home/larchbuild' - -# These paths are intended for use in 'chroot installation_dir', etc. -# The base directory of the larchified stuff -CHROOT_DIR_BUILD = '/.larch' -# This is the base of all stuff to be cleared on a rerun of larchify -CHROOT_DIR_LARCHIFY = CHROOT_DIR_BUILD + '/larchify' -# The base directory of the medium building area -CHROOT_DIR_MEDIUM = CHROOT_DIR_LARCHIFY + '/medium' -# Area for building the (mods.sqf) overlay -CHROOT_DIR_OVERLAY = CHROOT_DIR_LARCHIFY + '/overlay' -# Location for saving the system.sqf (outside of the larchify area) -CHROOT_SYSTEMSQF = CHROOT_DIR_BUILD + '/system.sqf' - -def debug(text): - sys.stderr.write("DEBUG: " + text.strip() + "\n") - sys.stderr.flush() - -def start_translator(switchC=True): - import gettext, __builtin__ - gettext.install('larch', base_dir+'/i18n', unicode=1) - __builtin__.lang = (os.environ.get("LANGUAGE") or os.environ.get("LC_ALL") - or os.environ.get("LC_MESSAGES") or os.environ.get("LANG")) - if switchC: - # If subprocesses must be run without i18n because the text - # output is parsed. - os.environ["LANGUAGE"] = "C" - diff --git a/build_tools/larch7/larch0/cli/larchify.py b/build_tools/larch7/larch0/cli/larchify.py deleted file mode 100755 index 5f3e472..0000000 --- a/build_tools/larch7/larch0/cli/larchify.py +++ /dev/null @@ -1,589 +0,0 @@ -#!/usr/bin/env python -# -# larchify.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.13 - -# This is a command line script to prepare a larch live system from an -# Arch Linux installation. All needed parameters are passed as options. - -import os, sys -from config import * -from backend import * -from userinfo import Userinfo -from glob import glob -import random, crypt -from subprocess import Popen, PIPE, STDOUT - - -class Builder: - """This class manages 'larchifying' an Arch Linux installation. - """ - def __init__(self, options): - self.installation_dir = get_installation_dir() - self.installation0 = (self.installation_dir - if self.installation_dir != "/" else "") - testfile = self.installation0 + '/etc/pacman.conf' - if not os.path.isfile(testfile): - errout(_("File '%s' doesn't exist:\n" - " '%s' not an Arch installation?") - % (testfile, self.installation_dir)) - - self.profile_dir = get_profile() - - - def build(self, options): - if not (self.installation0 or query_yn(_( - "Building a larch live medium from the running system is" - "\nan error prone process. Changes to the running system" - "\nmade while running this function may be only partially" - "\nincorporated into the compressed system images." - "\n\nDo you wish to continue?")), True): - return False - - # Define the working area - it must be inside the installation - # because of the use of chroot for some functions - self.larchify_dir = self.installation0 + CHROOT_DIR_LARCHIFY - # Location for the live medium image - self.medium_dir = self.installation0 + CHROOT_DIR_MEDIUM - # And potentially a saved system.sqf - self.system_sqf = self.installation0 + CHROOT_SYSTEMSQF - # Needed for a potentially saved locales directory - self.locales_base = self.installation0 + CHROOT_DIR_BUILD - # For building the (mods.sqf) overlay - self.overlay = self.installation0 + CHROOT_DIR_OVERLAY - comment("Initializing larchify process") - - if options.oldsqf: - if os.path.isfile(self.medium_dir + "/larch/system.sqf"): - runcmd("mv %s/larch/system.sqf %s" % - (self.medium_dir, self.system_sqf)) - else: - runcmd("rm -f %s" % self.system_sqf) - - # Clean out larchify area and create overlay directory - runcmd('rm -rf %s' % self.larchify_dir) - runcmd('mkdir -p %s' % self.overlay) - - if not self.find_kernel(): - return False - - if not self.system_check(): - return False - - comment("Beginning to build larch medium files") - # Clear out the directory - runcmd('rm -rf %s' % self.medium_dir) - # The base medium boot directory, bootloader independent. - runcmd('mkdir -p %s/boot' % self.medium_dir) - # The main larch direcory - runcmd('mkdir -p %s/larch' % self.medium_dir) - - # kernel - runcmd("cp -f %s/boot/%s %s/boot/larch.kernel" % - (self.installation0, self.kname, self.medium_dir)) - # Remember file name (to ease update handling) - runcmd('bash -c "echo \'%s\' > %s/larch/kernelname"' - % (self.kname, self.medium_dir)) - - # if no saved system.sqf, squash the Arch installation at self.installation_dir - if not os.path.isfile(self.system_sqf): - comment("Generating system.sqf") - # root directories which are not included in the squashed system.sqf - #ignoredirs = "boot dev mnt media proc sys tmp .livesys " - ignoredirs = "dev mnt media proc sys tmp .livesys " - ignoredirs += CHROOT_DIR_BUILD.lstrip("/") - # /var stuff - ignoredirs += " var/log var/tmp var/lock" - # others - ignoredirs += " usr/lib/locale" - - # Additional directories to ignore can also be specified in the - # profile. This is a nasty option. It was requested, and might - # be useful under certain special circumstances, but I recommend - # not using it unless you are really sure what you are doing. - veto_file = self.profile_dir + '/vetodirs' - if os.path.isfile(veto_file): - fh = open(veto_file) - for line in fh: - line = line.strip() - if line and (line[0] != '#'): - ignoredirs += ' ' + line.lstrip('/') - fh.close() - - if not chroot(self.installation0, - "/sbin/mksquashfs '/' '%s' -e %s" - % (CHROOT_SYSTEMSQF, ignoredirs), - filter=mksquashfs_filter_gen()): - errout(_("Squashing system.sqf failed")) - # remove execute attrib - runcmd("chmod oga-x %s" % self.system_sqf) - - # move system.sqf to medium directory - runcmd("mv %s %s/larch" % (self.system_sqf, self.medium_dir)) - - # prepare overlay - comment("Generating larch overlay") - # Copy over the overlay from the selected profile - if os.path.isdir("%s/rootoverlay" % self.profile_dir): - runcmd('bash -c "cp -rf %s/rootoverlay/* %s"' - % (self.profile_dir, self.overlay)) - # Ensure there is an /etc directory in the overlay - runcmd("mkdir -p %s/etc" % self.overlay) - # fix sudoers if any - if os.path.isfile("%s/etc/sudoers" % self.overlay): - runcmd("chmod 0440 %s/etc/sudoers" % self.overlay) - runcmd("chown root:root %s/etc/sudoers" % self.overlay) - - # Prepare inittab - inittab = self.overlay + "/etc/inittab" - itsave = inittab + ".larchsave" - it0 = self.installation0 + "/etc/inittab" - itl = self.overlay + "/etc/inittab.larch" - if not os.path.isfile(itl): - itl = self.installation0 + "/etc/inittab.larch" - if not os.path.isfile(itl): - itl = None - # Save the original inittab if there is an inittab.larch file, - # ... if there isn't already a saved one - if itl: - if ((not os.path.isfile(it0 + ".larchsave")) - and (not os.path.isfile(itsave))): - runcmd("cp %s %s" % (it0, itsave)) - # Use the .larch version in the live system - runcmd("cp -f %s %s" % (itl, inittab)) - - comment("Generating larch initcpio") - if not self.gen_initramfs(): - return False - - lpath = self.locales_base + '/locale' - if self.installation0: - if options.oldlocales and os.path.isdir(lpath): - comment("Copying saved glibc locales") - runcmd('rm -rf %s/usr/lib/locale' % self.overlay) - runcmd('mkdir -p %s/usr/lib' % self.overlay) - runcmd('cp -a %s %s/usr/lib' % (lpath, self.overlay)) - else: - comment("Generating glibc locales") - runcmd('rm -rf %s' % lpath) - script('larch-locales "%s" "%s"' % (self.installation0, - self.overlay)) - # Save the generated locales for possible reuse - runcmd('cp -a %s/usr/lib/locale %s' % (self.overlay, - self.locales_base)) - - if (os.path.isfile(self.installation0 + '/usr/bin/ssh-keygen') - and not os.path.isfile(self.profile_dir + '/nosshkeys')): - # ssh initialisation - done here so that it doesn't need to - # be done when the live system boots - comment("Generating ssh keys to overlay") - sshdir = CHROOT_DIR_OVERLAY + "/etc/ssh" - runcmd("mkdir -p %s" % (self.installation0 + sshdir)) - for k, f in [("rsa1", "ssh_host_key"), ("rsa", "ssh_host_rsa_key"), - ("dsa", "ssh_host_dsa_key")]: - chroot(self.installation0, - "ssh-keygen -t %s -N '' -f %s/%s" - % (k, sshdir, f), ["dev"]) - - # Ensure the hostname is in /etc/hosts - script("larch-hosts %s %s" % (self.installation0, self.overlay)) - - # Handle /mnt - runcmd("mkdir -p %s/mnt" % self.overlay) - for d in os.listdir("%s/mnt" % self.installation0): - if os.path.isdir("%s/mnt/%s" % (self.installation0, d)): - runcmd("mkdir %s/mnt/%s" % (self.overlay, d)) - - # Ensure there is a /boot directory - runcmd("mkdir -p %s/boot" % self.overlay) - - # Run customization script - tweak = self.profile_dir + '/build-tweak' - if os.path.isfile(tweak): - comment("(WARNING): Running user's build customization script") - if runcmd(tweak + ' %s %s' % (self.installation0, - self.overlay))[0]: - comment("Customization script completed") - else: - errout(_("Build customization script failed")) - - # Get root password - rootpwf = self.profile_dir + '/rootpw' - if os.path.isfile(rootpwf): - rootpw = readfile(rootpwf).strip() - if rootpw == '!': - # Lock the password - rootcmd = 'usermod -L' - else: - rootcmd = "usermod -p '%s'" % encryptPW(rootpw) - else: - rootcmd = None - - # Add users and set root password - if self.installation0 and not self.add_users(rootcmd): - return False - - comment("Squashing mods.sqf") - if not chroot(self.installation0, - "/sbin/mksquashfs '%s' '%s/larch/mods.sqf'" - % (CHROOT_DIR_OVERLAY, CHROOT_DIR_MEDIUM), - filter=mksquashfs_filter_gen()): - errout(_("Squashing mods.sqf failed")) - # remove execute attrib - runcmd("chmod oga-x %s/larch/mods.sqf" % self.medium_dir) - - runcmd("rm -rf %s" % self.overlay) - - comment(" *** %s ***" % _("larchify-process completed")) - return True - - - def add_users(self, rootcmd): - userinfo = Userinfo(self.profile_dir) - userlist = [] - for user in userinfo.allusers(): - # Only include if the user does not yet exist - if runcmd('bash -c "grep \"^%s\" %s/etc/passwd || echo -"' - % (user, self.installation_dir))[1][0] != '-': - comment("(WARNING): User '%s' exists already" % user) - else: - userlist.append(user) - - # Only continue if there are new users in the list - if rootcmd: - clist = [('root', rootcmd + ' %s')] - else: - if userlist == []: - return True - clist = [] - - # Save system files and replace them by the overlay versions - savedir = self.larchify_dir + '/save_etc' - runcmd('rm -rf %s' % savedir) - runcmd('mkdir -p %s/default' % savedir) - savelist = 'group,gshadow,passwd,shadow,login.defs,skel' - runcmd('bash -c "cp -a %s/etc/{%s} %s"' - % (self.installation0, savelist, savedir)) - runcmd('cp -a %s/etc/default/useradd %s/default' - % (self.installation0, savedir)) - for f in ('group', 'gshadow', 'passwd', 'shadow', 'login.defs'): - if os.path.isfile(self.overlay + '/etc/%s'): - runcmd('cp %s/etc/%s %s/etc' - % (self.overlay, f, self.installation0)) - if os.path.isfile(self.overlay + '/etc/default/useradd'): - runcmd('cp %s/etc/default/useradd %s/etc/default' - % (self.overlay, self.installation0)) - if os.path.isdir(self.overlay + '/etc/skel'): - runcmd('cp -r %s/etc/skel %s/etc' - % (self.overlay, self.installation0)) - - # Build the useradd command - userdir0 = '/users' - userdir = self.larchify_dir + userdir0 - userdirs = [] - runcmd('mkdir -p %s/home' % self.overlay) - for u in userlist: - cline = 'useradd -m' - pgroup = userinfo.get(u, 'maingroup') - if pgroup: - cline += ' -g ' + pgroup - uid = userinfo.get(u, 'uid') - if uid: - cline += ' -u ' + uid - pw = userinfo.get(u, 'pw') - if (pw == ''): - # Passwordless login - pwcrypt = '' - else: - # Normal MD5 password - pwcrypt = encryptPW(pw) - cline += " -p '%s'" % pwcrypt - skeldir = userinfo.get(u, 'skel') - if skeldir: - # Custom home initialization directories in the profile - # always start with 'skel_' - skel = 'skel_' + skeldir - if skel not in userdirs: - userdirs.append(skel) - cline += ' -k %s/%s' % (CHROOT_DIR_LARCHIFY + userdir0, - skel) - # Allow for expert tweaking - cline += ' ' + userinfo.get(u, 'expert') - # The user and the command to be run - clist.append((u, cline + ' %s')) - xgroups = userinfo.get(u, 'xgroups') - if xgroups: - xgl = [] - for g in xgroups.split(','): - clist.append((u, 'usermod -a -G %s %%s' % g)) - - if userdirs: - # Copy custom 'skel' directories to build space - runcmd('rm -rf %s' % userdir) - runcmd('mkdir -p %s' % userdir) - for ud in userdirs: - runcmd('cp -r %s/%s %s/%s' % - (self.profile_dir, ud, userdir, ud)) - - nfail = 0 - ok = True - for u, cmd in clist: - if not chroot(self.installation0, cmd % u): - nfail += 1 - # Errors adding users to groups are not fatal: - if not cmd.startswith('usermod -a -G'): - ok = False - if os.path.isdir('%s/home/%s' % (self.installation0, u)): - runcmd('mv %s/home/%s %s/home' - % (self.installation0, u, self.overlay)) - - if nfail > 0: - errout(_("%d user account operation(s) failed") % nfail, 0) - # Move changed /etc/{group,gshadow,passwd,shadow} to overlay - runcmd('bash -c "mv %s/etc/{group,gshadow,passwd,shadow} %s/etc"' - % (self.installation0, self.overlay)) - # Restore system files in base installation - runcmd('rm -rf %s/etc/skel' % self.installation0) - runcmd('bash -c "cp -a %s/* %s/etc"' - % (savedir, self.installation0)) - return ok - - - def system_check(self): - comment("Testing for necessary packages and kernel modules") - fail = "" - warn = "" - nplist = ["larch-live"] - - mdep = (self.installation0 + - "/lib/modules/%s/modules.dep" % self.kversion) - if Popen(["grep", "/squashfs.ko", mdep], stdout=PIPE, - stderr=STDOUT).wait() != 0: - fail += _("No squashfs module found\n") - - if Popen(["grep", "/aufs.ko", mdep], stdout=PIPE, - stderr=STDOUT).wait() == 0: - self.ufs='_aufs' - nplist.append("aufs2-util") - - elif Popen(["grep", "/unionfs.ko", mdep], stdout=PIPE, - stderr=STDOUT).wait() == 0: - self.ufs='_unionfs' - - else: - fail += _("No aufs or unionfs module found\n") - - for p in nplist: - if not self.haspack(p): - fail += _("Package '%s' is needed by larch systems\n") % p - - if not self.haspack("syslinux"): - warn += _("Without package 'syslinux' you will not be able\n" - "to create syslinux or isolinux booting media\n") - - if (not self.haspack("cdrkit")) and (not self.haspack("cdrtools")): - warn += _("Without package 'cdrkit' (or 'cdrtools') you will\n" - "not be able to create CD/DVD media\n") - - if not self.haspack("eject"): - warn += _("Without package 'eject' you will have problems\n" - "using CD/DVD media\n") - - if warn: - cont = query_yn(_("WARNING:\n%s" - "\n Continue building?") % warn) - else: - cont = True - - if fail: - errout(_("ERROR:\n%s") % fail) - - return cont - - - def haspack(self, package): - """Check whether the given package is installed. - """ - for p in os.listdir(self.installation0 + '/var/lib/pacman/local'): - if p.rsplit("-", 2)[0] == package: - return True - return False - - - def find_kernel(self): - # The uncomfortable length of this function is deceptive, - # most of it is for dealing with errors. - comment("Seeking kernel information") - kscript = "%s/kernel" % self.profile_dir - if os.path.isfile(kscript): - p = Popen([kscript], stdout=PIPE, stderr=STDOUT) - r = p.communicate()[0] - if p.returncode == 0: - self.kname, self.kversion = r.split() - - else: - errout(_("Problem running %s:\n %s") % (kscript, r)) - else: - kernels = glob(self.installation0 + '/boot/vmlinuz*') - if len(kernels) > 1: - errout(_("More than one kernel found:\n %s") % - "\n ".join(kernels)) - elif not kernels: - errout(_("No kernel found")) - self.kname = os.path.basename(kernels[0]) - - self.kversion = None - for kv in os.listdir(self.installation0 + '/lib/modules'): - if os.path.isfile(self.installation0 - + ('/lib/modules/%s/modules.dep' % kv)): - if self.kversion: - errout(_("More than one set of kernel modules in %s") - % (self.installation0 + '/lib/modules')) - self.kversion = kv - else: - kmpath = self.installation0 + ('/lib/modules/%s' % kv) - comment("Unexpected kernel files at %s" % kmpath) - # Try to find packages concerned - p = Popen(["find", ".", "-name", "*.ko"], cwd=kmpath, - stdout=PIPE, stderr=STDOUT) - r = p.communicate()[0] - if p.returncode == 0: - packs = [] - for km in r.split(): - a = chroot(self.installation0, - 'pacman -Qoq /lib/modules/%s/%s' - % (kv, km)) - - if a: - pack = "-".join(a[0].split()) - if pack not in packs: - packs.append(pack) - comment(" Package: %s" % pack) - - else: - comment("Couldn't determine guilty packages") - - if not query_yn(_("WARNING:" - "\n You seem to have installed a package containing modules" - "\nwhich aren't compatible with your kernel (see log)." - "\nPlease check that this won't cause problems." - "\nMaybe you need the corresponding package for your kernel?" - "\n\n Continue building?")): - return False - - if not self.kversion: - errout(_("Couldn't find kernel modules")) - - comment("Kernel: %s - version: %s" % (self.kname, self.kversion)) - chroot(self.installation0, "depmod %s" % self.kversion) - return True - - - def gen_initramfs(self): - # Fix up larch mkinitcpio.conf for unionfs/aufs - conf = self.overlay + "/etc/mkinitcpio.conf.larch" - if os.path.isfile(conf + "0"): - conf0 = conf + "0" - else: - conf0 = self.installation0 + "/etc/mkinitcpio.conf.larch0" - runcmd('bash -c "sed \'s|___aufs___|%s|g\' <%s >%s"' % (self.ufs, conf0, conf)) - - presets = [os.path.basename(f) for f in glob( - self.installation0 + "/etc/mkinitcpio.d/kernel26*.preset")] - if len(presets) != 1: - errout(_("Couldn't find usable mkinitcpio preset: %s") % - self.installation0 + "/etc/mkinitcpio.d/kernel26*.preset") - - # Save original preset file (unless a '*.larchsave' is already present) - idir = self.installation0 + "/etc/mkinitcpio.d" - oldir = self.overlay + "/etc/mkinitcpio.d" - if not os.path.isfile("%s/%s.larchsave" % (idir, presets[0])): - runcmd("mkdir -p %s" % oldir) - runcmd("cp %s/%s %s/%s.larchsave" % - (idir, presets[0], oldir, presets[0])) - - # Adjust larch.preset file for custom kernels - runcmd('bash -c "sed \'s|___|%s|\' <%s/larch.preset0 >%s/larch.preset"' - % (presets[0].rsplit(".", 1)[0], idir, oldir)) - - # Replace 'normal' preset in overlay - runcmd("cp %s/larch.preset %s/%s" % (oldir, oldir, presets[0])) - - # Generate initramfs - return chroot(self.installation0, - "mkinitcpio -k %s -c %s -g %s" % - (self.kversion, - CHROOT_DIR_OVERLAY + "/etc/mkinitcpio.conf.larch", - CHROOT_DIR_MEDIUM + "/boot/larch.img")) - - -def encryptPW(pw): - """Encrypt a password - needed for user account generation. - """ - salt = '$1$' - for i in range(8): - salt += random.choice("./0123456789abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ") - return crypt.crypt(pw, salt) - - - -if __name__ == "__main__": - start_translator() - - from optparse import OptionParser, OptionGroup - parser = OptionParser(usage=_("usage: %prog [options]")) - - 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 directory to be larchified (default %s)") - % INSTALLATION) - 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("-q", "--quiet", action="store_true", dest="quiet", - default=False, help=_("Suppress output messages, except errors" - " (no effect if -s specified)")) - parser.add_option("-o", "--oldsqf", action="store_true", dest="oldsqf", - default=False, help=_("Reuse previously generated system.sqf")) - parser.add_option("-l", "--oldlocales", action="store_true", - dest="oldlocales", default=False, - help=_("Reuse previously generated locales")) - parser.add_option("-f", "--force", action="store_true", dest="force", - default=False, help=_("Don't ask for confirmation")) - - (options, args) = parser.parse_args() -# Should there be arguments? - - if os.getuid() != 0: - print _("This application must be run as root") - sys.exit(1) - init('larchify', options) - builder = Builder(options) - if builder.build(options): - sys.exit(0) - else: - sys.exit(1) diff --git a/build_tools/larch7/larch0/cli/live_iso.py b/build_tools/larch7/larch0/cli/live_iso.py deleted file mode 100755 index e6899c9..0000000 --- a/build_tools/larch7/larch0/cli/live_iso.py +++ /dev/null @@ -1,154 +0,0 @@ -#!/usr/bin/env python -# -# live_iso.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.12 - -# This is a command line script to prepare an 'iso' file from an -# already larchified Arch Linux installation. Alternatively, another -# larch medium can be used as source (with the '-S' option). -# All needed parameters are passed as options. - -import os -from config import * -from backend import * -from media_common import * - - -def build_iso(options): - """Create a bootable iso from the source larch image. If a chroot - build is used (default unless -S is specified) the resulting iso file - will be relative to the larch build area (CHROOT_DIR_BUILD) in the - chroot directory, otherwise as specified to the -o option. - """ - medium = Medium(options) - ipath = medium.chrootpath - build = medium.build - - # Write bootloader configuration file - bootconfig(build, options.syslinux) - - if not os.path.isfile(medium.medium_dir + '/larch/larchboot'): - add_larchboot(build) - - # Need to adjust paths to cater for chroot! - source0 = medium.chroot_medium_dir() - isopath0 = medium.iso_path() - - # Select bootloader - if options.syslinux: - # Get fresh isolinux.bin - runcmd('cp %s/boot/isolinux/isolinux.bin0 %s/boot/isolinux/isolinux.bin' - % (build, build)) - parms = '-b boot/isolinux/isolinux.bin -c boot/isolinux/isolinux.boot' - # Select bootloader - else: - parms = '-b boot/grub/stage2_eltorito' - - # Actually the volume label can be 32 bytes, but 16 is compatible - # with ext2 (though a little longer than vfat) - label = check_label(options.label, 16) - # Build iso - if not chroot(ipath, ('mkisofs -R -l %s -no-emul-boot -boot-load-size 4' - ' -boot-info-table -input-charset=UTF-8' - ' -V "%s"' - ' -o "%s"' - ' -x "%s/boot"' - ' -x "%s/larch/save"' - ' "%s" "%s"') % (parms, label, isopath0, - source0, source0, source0, BUILD0), - filter=mkisofs_filter_gen()): - - errout(_("iso build failed")) - - # Process iso so that it can be 'dd'ed to a USB-stick - if options.syslinux and not chroot(ipath, ('isohybrid %s' % isopath0)): - errout(_("Couldn't perform 'isohybrid' operation on larch 'iso'" - " (Not Critical!)"), 0) - medium.unmount() - runcmd('rm -rf %s' % build) - - comment(" *** %s ***" % (_("%s was successfully created") - % (options.isofile))) - - - -if __name__ == "__main__": - start_translator() - - from optparse import OptionParser, OptionGroup - parser = OptionParser(usage=_("usage: %prog [options]")) - - parser.add_option("-p", "--profile", action="store", type="string", - default="", dest="profile", - help=_("Profile: 'user:profile-name' or path to profile directory" - " (conflicts with -S)")) - parser.add_option("-S", "--source", action="store", type="string", - default="", dest="source", - help=_("Source: path to larch medium image (conflicts with -p)." - " It can also be a device ('/dev/...') or an 'iso' file.")) - parser.add_option("-i", "--installation-dir", action="store", type="string", - default="", dest="idir", - help=_("Path to larchified directory (default %s)") % INSTALLATION) - 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("-q", "--quiet", action="store_true", dest="quiet", - default=False, help=_("Suppress output messages, except errors" - " (no effect if -s specified)")) - - parser.add_option("-f", "--force", action="store_true", dest="force", - default=False, help=_("Don't ask for confirmation")) - - parser.add_option("-b", "--isolinux", action="store_true", dest="syslinux", - default=False, help=_("Use the isolinux bootloader" - " (the default is GRUB)")) - parser.add_option("-l", "--label", action="store", type="string", - default=LABEL, dest="label", - help=_("Volume label for iso (default '%s')") % LABEL) - parser.add_option("-o", "--isofile", action="store", type="string", - default=ISOFILE, dest="isofile", - help=_("Specify the output file (default '%s'). It will be" - " generated to the current directory.") % ISOFILE) - parser.add_option("-D", "--setdir", action="store", type="string", - dest='setdir', default='', - help=_("Set current directory," - " so that the 'iso' can be placed there")) - parser.add_option("-C", "--chroot", action="store_true", - dest="chroot", default=False, - help=_("Use chroot for build (default when -S not specified)")) - parser.add_option("-c", "--nochroot", action="store_true", - dest="nochroot", default=False, - help=_("Don't use chroot for build (default when -S specified)")) - - parser.add_option('-T', '--testmedium', action='store_true', - dest='testmedium', default=False, - help=_("Test source medium only (used by gui)")) - - (options, args) = parser.parse_args() - - if os.getuid() != 0: - print _("This application must be run as root") - sys.exit(1) - - init('live_iso', options) - build_iso(options) diff --git a/build_tools/larch7/larch0/cli/live_part.py b/build_tools/larch7/larch0/cli/live_part.py deleted file mode 100755 index 22af5d3..0000000 --- a/build_tools/larch7/larch0/cli/live_part.py +++ /dev/null @@ -1,221 +0,0 @@ -#!/usr/bin/env python -# -# live_part.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.18 - -# This is a command line script to prepare a larch live medium from an -# already larchified Arch Linux installation, or another larch medium. -# Parameters are passed as options and arguments. - -import os -from config import * -from backend import * -from media_common import * - - -def build_partition(options, devicename): - """Install the larchified system to the partition specified by the - options. - 'devicename' is the name (e.g. 'sdb1', without '/dev/') of the - partition to receive the larch image - """ - medium = Medium(options) - ipath = medium.chrootpath - build = medium.build - - # Check and format device - device = '/dev/' + devicename - if not os.path.exists(device): - errout(_("Invalid device: %s") % device) - if options.format: - # label - if options.syslinux: - labellength = 11 - opt = 'n' - else: - labellength = 16 - opt = 'L' - l = ('-%s "%s"' % (opt, check_label(options.label, labellength)) - if options.label else '') - # set partition type, reload partition table, and format - if not (chroot(ipath, 'bash -c "echo -e \',,%s,*\\n\' |' - ' sfdisk --no-reread %s -N%s"' % - ('0c' if options.syslinux else 'L', - device[:8], device[8:]), ['dev']) - and chroot(ipath, 'partprobe %s' % device[:8], ['dev']) - and chroot(ipath, 'mkfs.%s %s %s' % - ('vfat' if options.syslinux else 'ext2', l, device), - ['dev'])): - - errout(_("Couldn't format %s") % device) - - # Need to get the label - if not formatting (an option for experts) - # it is probably not a good idea to change the volume label, so - # use the old one. - label = medium.get_device_label(device) - - # Check device format - ok, lines = runcmd('blkid -c /dev/null -o value -s TYPE %s' % device) - if not ok: - errout(_("Couldn't get format information for %s") % device) - fstype = lines[0] - if options.syslinux: - if fstype != 'vfat': - errout(_("syslinux is only supported on vfat")) - elif not fstype.startswith('ext'): - errout(_("GRUB is at present only supported on extN")) - - # Rename the syslinux boot directory if necessary - if os.path.isdir(build + '/boot/isolinux'): - runcmd('mv %s/boot/isolinux %s/boot/syslinux' % (build, build)) - # Write bootloader configuration file - bootconfig(build, options.syslinux, label, device, options.detection) - - # Mount partition and remove larch and boot dirs - runcmd('rm -rf %s' % MP) - runcmd('mkdir -p %s' % MP) - if not mount(device, MP): - errout(_("Couldn't mount larch partition, %s") % device) - runcmd('rm -rf %s/larch' % MP) - runcmd('rm -rf %s/boot' % MP) - - # Copy files to device - runcmd('cp -r %s/larch %s' % (medium.medium_dir, MP)) - runcmd('cp -r %s/boot %s' % (build, MP)) - medium.unmount() - - # To boot in 'search' mode the file larch/larchboot must be present - # (though at present this is only relevant for partitions, CDs will - # be booted even without this file). - # To enable session saving the file larch/save must be present - # (only relevant if not building an iso). - runcmd('bash -c "rm -f %s/larch/{larchboot,save}"' % MP) - if options.larchboot: - add_larchboot(MP) - - if options.nosave: - if options.save: - errout(_("Option '-a' conflicts with option '-A'")) - ssave = False - else: - ssave = not os.path.isfile(MP + '/larch/nosave') - - if options.save or ssave: - writefile("The presence of the file 'larch/save'" - " enables session saving.\n", MP + '/larch/save') - - # Unmount partition - unmount(MP) - - # Now set up bootloader in MBR - if options.mbr: - if options.syslinux: - runcmd('dd if=%s/boot/syslinux/mbr.bin of=%s' - % (build, device[:8])) - chroot(ipath, 'syslinux %s' % device, ('dev', 'proc')) - else: - script('larch-mbr-grub %s %s' % (ipath if ipath else '/', device)) - runcmd('rm -rf %s' % build) - comment(" *** %s ***" % (_("%s was successfully written") % device)) - - - -if __name__ == '__main__': - start_translator() - - from optparse import OptionParser, OptionGroup - parser = OptionParser(usage=_("usage: %prog [options] partition" - " (e.g. sdb1)")) - - parser.add_option("-p", "--profile", action="store", type="string", - default="", dest="profile", - help=_("Profile: 'user:profile-name' or path to profile directory" - " (conflicts with -S)")) - parser.add_option("-S", "--source", action="store", type="string", - default="", dest="source", - help=_("Source: path to larch medium image (conflicts with -p)." - " It can also be a device ('/dev/...') or an 'iso' file.")) - parser.add_option("-i", "--installation-dir", action="store", type="string", - default="", dest="idir", - help=_("Path to larchified directory (default %s)") % INSTALLATION) - 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("-q", "--quiet", action="store_true", dest="quiet", - default=False, help=_("Suppress output messages, except errors" - " (no effect if -s specified)")) - - parser.add_option("-f", "--force", action="store_true", dest="force", - default=False, help=_("Don't ask for confirmation")) - - 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("-b", "--syslinux", action="store_true", dest="syslinux", - default=False, help=_("Use the syslinux bootloader" - " (the default is GRUB)")) - parser.add_option("-l", "--label", action="store", type="string", - default=LABEL, dest="label", - help=_("Volume label for boot partition (default %s)") - % LABEL) - parser.add_option("-n", "--nosearchboot", action="store_false", - dest="larchboot", default=True, - help=_("Don't generate 'larch/larchboot' file")) - parser.add_option("-a", "--save", action="store_true", - dest="save", default=False, - help=_("Override profile larch/nosave" - " (force enable session saving) - conflicts with '-A'")) - parser.add_option("-A", "--nosave", action="store_true", - dest="nosave", default=False, - help=_("Force disabling of session saving - conflicts with '-a'")) - parser.add_option("-x", "--noformat", action="store_false", - dest="format", default=True, - help=_("Don't format partition (only for experts!)")) - parser.add_option("-m", "--noboot", action="store_false", - dest="mbr", default=True, - help=_("Don't install the bootloader (to the MBR)")) - parser.add_option("-C", "--chroot", action="store_true", - dest="chroot", default=False, - help=_("Use chroot for build (default when -S not specified)")) - parser.add_option("-c", "--nochroot", action="store_true", - dest="nochroot", default=False, - help=_("Don't use chroot for build (default when -S specified)")) - - (options, args) = parser.parse_args() - - # To avoid error messages - options.testmedium = False - options.setdir = '' - - if not args: - print _("You must specify the partition to receive larch\n") - parser.print_help() - sys.exit(1) - - if os.getuid() != 0: - print _("This application must be run as root") - sys.exit(1) - - init('live_part', options) - build_partition(options, devicename=args[0]) 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() diff --git a/build_tools/larch7/larch0/cli/test.py b/build_tools/larch7/larch0/cli/test.py deleted file mode 100755 index 18e8067..0000000 --- a/build_tools/larch7/larch0/cli/test.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python -# -# This is a little script for testing the dispatcher and termination of -# subprocesses. It spawns several levels of itself, each instance just -# outputs an incrementing count until it is terminated. - -import sys, os, time, signal - -try: - import json as serialize -except: - import simplejson as serialize - -def out(text): - sys.stdout.write(serialize.dumps(text) + '\n') - sys.stdout.flush() - -def sigint(num, frame): - """A handler for SIGINT. Tidy up properly and quit. - """ - out("!>INTERRUPTED %d" % level) - exit(1) -signal.signal(signal.SIGINT, sigint) - -level = 3 -while level > 0: - if os.fork(): - break - time.sleep(1) - level -= 1 - -sys.stderr.write('%d: pid=%d ppid=%d pgrp=%d\n' % (level, - os.getpid(), os.getppid(), os.getpgrp())) -sys.stderr.flush() -time.sleep(5) - -n = 0 -while True: - n += 1 - out('--%d: %04d' % (level, n)) - time.sleep(4) - diff --git a/build_tools/larch7/larch0/cli/userinfo.py b/build_tools/larch7/larch0/cli/userinfo.py deleted file mode 100644 index f2045aa..0000000 --- a/build_tools/larch7/larch0/cli/userinfo.py +++ /dev/null @@ -1,93 +0,0 @@ -# userinfo.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.11 - -import os -from ConfigParser import SafeConfigParser - -# Default list of 'additional' groups for a new user -BASEGROUPS = 'video,audio,optical,storage,scanner,power,camera' - -class Userinfo: - def __init__(self, profile): - self.profile_dir = profile - - def getusers(self): - """Read user information by means of a SafeConfigParser instance. - This is then available as self.userconf. - """ - self.userconf = SafeConfigParser({'pw':'', 'maingroup':'', 'uid':'', - 'skel':'', 'xgroups':BASEGROUPS, 'expert':''}) - users = self.profile_dir + '/users' - if os.path.isfile(users): - try: - self.userconf.read(users) - except: - error0(_("Invalid 'users' file")) - - def allusers(self): - self.getusers() - return self.userconf.sections() - - def get(self, user, field): - return self.userconf.get(user, field) - - def userinfo(self, user, fields): - """Get an ordered list of the given field data for the given user. - """ - return [self.userconf.get(user, f) for f in fields] - - def userset(self, uname, field, text): - self.userconf.set(uname, field, text) - - def newuser(self, user): - try: - self.userconf.add_section(user) - return self.saveusers() - except: - error0(_("Couldn't add user '%s'") % user) - return False - - def deluser(self, user): - try: - self.userconf.remove_section(user) - return self.saveusers() - except: - error0(_("Couldn't remove user '%s'") % user) - return False - - def saveusers(self): - """Save the user configuration data (in 'INI' format) - """ - try: - fh = None - fh = open(self.profile_dir + '/users', 'w') - self.userconf.write(fh) - fh.close() - return True - except: - if fh: - fh.close() - error0(_("Couldn't save 'users' file")) - self.getusers() - return False - |