Exemple #1
0
 def __init__(self):
     object.__init__(self)
     self.cfg = PaellaConfig()
     self.conn = InstallerConnection()
     self.profile = os.environ['PAELLA_PROFILE']
     self.target = os.environ['PAELLA_TARGET']
     self.machine = None
     self.trait = None
     self.suite = get_suite(self.conn, self.profile)
     self.pr = Profile(self.conn)
     self.pr.set_profile(self.profile)
     self.traitlist = self.pr.make_traitlist()
     self.pe = ProfileEnvironment(self.conn, self.profile)
     self.tp = TraitParent(self.conn, self.suite)
     self.fm = Family(self.conn)
     self.tr = Trait(self.conn, self.suite)
     self.families = list(
         self.fm.get_related_families(self.pr.get_families()))
     self._envv = None
     self.default = DefaultEnvironment(self.conn)
     #self.installer = TraitInstaller(self.conn, self.suite)
     self.installer = ProfileInstaller(self.conn)
     self.installer.set_logfile()
     self.installer.set_profile(self.profile)
     self.installer.set_target(self.target)
     if os.environ.has_key('PAELLA_MACHINE'):
         self.machine = os.environ['PAELLA_MACHINE']
     if os.environ.has_key('PAELLA_TRAIT'):
         self.set_trait(os.environ['PAELLA_TRAIT'])
Exemple #2
0
 def set_profile(self, profile):
     self.check_target_set()
     self.installer = ProfileInstaller(self)
     if os.environ.has_key('DEBUG'):
         self.log.info("ChrootInstaller.machine_data: %s" % self.machine_data)
     self.installer.machine_data.update(self.machine_data)
     if os.environ.has_key('DEBUG'):
         self.log.info("ProfileInstaller.machine_data: %s" % self.installer.machine_data)
     self.installer.set_profile(profile)
     self.set_suite(self.installer.suite)
Exemple #3
0
 def setup_installer(self):
     machine = self.machine.current.machine
     profile = self.machine.current.profile
     self.log.info('Setting up profile installer for %s' % machine)
     self.installer = ProfileInstaller(self.conn)
     self.installer.log = self.log
     self.installer.mtypedata = self.mtypedata
     self.installer.set_profile(profile)
     self.suite = self.installer.suite
     self._installer_ready = True
     self.log.info('Profile installer ready for %s' % machine)
 def __init__(self):
     object.__init__(self)
     self.cfg = PaellaConfig()
     self.conn = InstallerConnection()
     self.profile = os.environ['PAELLA_PROFILE']
     self.target = path(os.environ['PAELLA_TARGET'])
     self.machine = None
     self.trait = None
     self.suite = get_suite(self.conn, self.profile)
     self.pr = Profile(self.conn)
     self.pr.set_profile(self.profile)
     self.traitlist = self.pr.make_traitlist()
     self.pe = ProfileEnvironment(self.conn, self.profile)
     self.tp = TraitParent(self.conn, self.suite)
     self.fm = Family(self.conn)
     self.tr = Trait(self.conn, self.suite)
     self.families = list(self.fm.get_related_families(self.pr.get_families()))
     self._envv = None
     self.default = DefaultEnvironment(self.conn)
     #self.installer = TraitInstaller(self.conn, self.suite)
     self.installer = ProfileInstaller(self.conn)
     self.installer.set_logfile()
     self.installer.set_profile(self.profile)
     self.installer.set_target(self.target)
     if os.environ.has_key('PAELLA_MACHINE'):
         self.machine = os.environ['PAELLA_MACHINE']
     if os.environ.has_key('PAELLA_TRAIT'):
         self.set_trait(os.environ['PAELLA_TRAIT'])
 def setup_installer(self):
     machine = self.machine.current.machine
     profile = self.machine.current.profile
     self.log.info('Setting up profile installer for %s' % machine)
     self.installer = ProfileInstaller(self.conn)
     self.installer.log = self.log
     self.installer.mtypedata = self.mtypedata
     self.installer.set_profile(profile)
     self.suite = self.installer.suite
     self._installer_ready = True
     self.log.info('Profile installer ready for %s' % machine)
 def setup_installer(self):
     self.installer = ProfileInstaller(self.conn)
     self.installer.log = self.log
     self.installer.set_profile(self.profile)
     self.suite = self.installer.suite
     self._installer_ready = True
Exemple #7
0
 def setup_installer(self):
     profile = self.machine.current.profile
     self.installer = ProfileInstaller(self.conn, self.cfg)
     self.installer.set_profile(profile)
     self.suite = self.installer.suite
Exemple #8
0
class ChrootInstaller(BaseChrootInstaller):
    # we may need more __init__ args later
    def __init__(self, conn):
        BaseChrootInstaller.__init__(self, conn)
        self._bootstrapped = False
        self._install_finished = False
        
        self._processes = [
            'ready_target',
            'bootstrap',
            'mount_target_proc',
            'mount_target_sys',
            'make_device_entries',
            'mount_target_devpts',
            'apt_sources_installer',
            'ready_base_for_install',
            'pre_install',
            'install',
            'post_install',
            'apt_sources_final',
            'umount_target_sys',
            'umount_target_proc',
            'umount_target_devpts'
            ]
        # pre_install is unmapped
        # post_install is unmapped
        self._process_map = dict(ready_target=self.create_target_directory,
                                 bootstrap=self.bootstrap_target,
                                 mount_target_proc=self.mount_target_proc,
                                 mount_target_sys=self.mount_target_sys,
                                 make_device_entries=self.make_device_entries,
                                 mount_target_devpts=self.mount_target_devpts,
                                 apt_sources_installer=self.apt_sources_installer,
                                 ready_base_for_install=self.ready_base_for_install,
                                 install=self.install,
                                 apt_sources_final=self.apt_sources_final,
                                 umount_target_sys=self.umount_target_sys,
                                 umount_target_proc=self.umount_target_proc,
                                 umount_target_devpts=self.umount_target_devpts
                                 )
        # this is only used in the machine installer
        self.machine_data = {}
    
    # the default script for the chroot installer is None
    def make_script(self, procname):
        return None

    def set_logfile(self, logfile):
        BaseInstaller.set_logger(self, filename=logfile)
        self.log.info('-'*30)
        msg = '%s initialized' % self.__class__.__name__
        self.log.info(msg)
        self.log.info('-'*30)
        
    def set_profile(self, profile):
        self.check_target_set()
        self.installer = ProfileInstaller(self)
        if os.environ.has_key('DEBUG'):
            self.log.info("ChrootInstaller.machine_data: %s" % self.machine_data)
        self.installer.machine_data.update(self.machine_data)
        if os.environ.has_key('DEBUG'):
            self.log.info("ProfileInstaller.machine_data: %s" % self.installer.machine_data)
        self.installer.set_profile(profile)
        self.set_suite(self.installer.suite)
    
    
    def _bootstrap_with_tarball(self, suite):
        self.check_target_exists()
        suite_path = path(self.defenv.get('installer', 'suite_storage'))
        arch = get_architecture()
        filename = '%s-%s.tar.gz' % (suite, arch)
        basefile = suite_path / filename
        taropts = '-xzf'
        # we normally expect a tar.gz
        # but we'll check for a plain tar also
        if not basefile.exists():
            filename = '%s-%s.tar' % (suite, arch)
            basefile = suite_path / filename
            taropts = '-xf'
        if not basefile.exists():
            # We don't really want to ruin an install
            # by not having a tarball, so we log a warning
            # and proceed with a debootstrap.
            msg = "base tarball not found, reverting to debootstrap"
            self.log.warn(msg)
            self._bootstrap_with_debootstrap(suite)
        else:
            #cmd = 'tar -C %s %s %s' % (self.target, taropts, basefile)
            cmd = ['tar', '-C', str(self.target), taropts, str(basefile)]
            # if cmd returns nonzero, runlog will raise an error
            runlog(cmd)
            # we need to do certain things after extraction
            # that debootstrap does for us,
            # like copy /etc/resolv.conf to the target.
            # these things should be done in the
            # ready_base_for_install process
            
            # this is now done in post_process
            #self._bootstrapped = True
            
    def _bootstrap_with_debootstrap(self, suite):
        self.check_target_exists()
        mirror = self.defenv.get('installer', 'http_mirror')
        # debug stuff
        cmd = debootstrap(suite, self.target, mirror)
        # if cmd returns nonzero, runlog will raise an error
        runlog(cmd)
        # this is now done in post_process
        #self._bootstrapped = True

    def bootstrap_target(self):
        self.check_suite_set()
        if not self.target.exists():
            self.target.mkdir()
        if not self.target.isdir():
            raise InstallTargetError, "%s is not a directory" % self.target
        if self.defenv.getboolean('installer', 'bootstrap_target'):
            self.log.info('bootstrapping with debootstrap')
            self._bootstrap_with_debootstrap(self.base_suite)
        else:
            self.log.info('bootstrapping with premade tarball')
            self._bootstrap_with_tarball(self.base_suite)
        # here we add the apt keys that are needed
        # we should probably split this part off into
        # another process.  This step needs to be done
        # before the ready_base_for_install process, or
        # at least at the beginning of that process.
        aptkeys = AptKeyHandler(self.conn)
        keys = self.defenv.get_list('archive_keys', 'installer')
        for key in keys:
            try:
                row = aptkeys.get_row(key)
            except NoAptKeyError:
                msg = "There's no apt key named %s in the database" % key
                self.log.error(msg)
                raise UnsatisfiedRequirementsError , msg
            filename = self.target / ('%s.key' % key)
            if filename.exists():
                msg = "%s already exists" % filename
                self.log.error(msg)
                raise RuntimeError , msg
            keyfile = file(filename, 'w')
            keyfile.write(row.data)
            keyfile.close()
            self.chroot(['apt-key', 'add', '%s.key' % key])
            os.remove(filename)
            if filename.exists():
                msg = "%s wasn't deleted" % filename
                self.log.error(msg)
                raise RuntimeError , msg
            self.log.info('added key %s (%s) to apt' % (key, row.keyid))
        
    def make_device_entries(self):
        self.check_bootstrap()
        self.log.info('nothing done for make_device_entries yet')
        
    def apt_sources_installer(self):
        self.check_bootstrap()
        make_sources_list(self.conn, self.target, self.suite)
        
    def apt_sources_final(self):
        self.check_install_complete()
        sourceslist = self.target / 'etc/apt/sources.list'
        sourceslist_installer = path('%s.installer' % sourceslist)
        os.rename(sourceslist, sourceslist_installer)
        make_official_sources_list(self.conn, self.target, self.suite)

    
    def ready_base_for_install(self):
        """This gets the base that was either
        debootstrapped or extracted ready
        to install packages.  Since the
        install hasn't happened yet, replacing
        files like /etc/resolv.conf and the
        package lists shouldn't affect anything.
        the apt_sources_installer process is called
        right before this one, so there should be
        an appropriate sources.list to update packages
        with.
        """
        self.check_bootstrap()
        # 'copy' /etc/resolv.conf to target
        resolvconf = file('/etc/resolv.conf').read()
        target_resolvconf = self.target / 'etc/resolv.conf'
        target_resolvconf.write_text(resolvconf)
        # update the package lists
        self.chroot(['apt-get', '-y', 'update'])
        
        
    # common method for mounting /proc and /sys
    # here fs is either 'proc' or 'sys' or 'devpts'
    def _mount_target_virtfs(self, fs):
        fstype = dict(proc='proc', sys='sysfs', devpts='devpts')
        target = self.target / fs
        if fs == 'devpts':
            target = self.target / 'dev' / 'pts'
        if not target.isdir():
            self.log.info('creating %s' % target)
            target.mkdir()
        #cmd = 'mount -t %s none %s' % (fstype[fs], target)
        cmd = ['mount', '-t', fstype[fs], 'none', str(target)]
        runlog(cmd)
        
        
    def _umount_target_virtfs(self, fs):
        self.log.info('running umount for %s' % fs)
        # work around binfmt-support /proc locking
        # found this idea while messing around in live-helper
        target = self.target / fs
        if fs == 'proc':
            binfmt_misc = self.target / 'proc/sys/fs/binfmt_misc'
            status = binfmt_misc / 'status'
            if status.exists():
                self.log.info('Unmounting /proc/sys/fs/binfmt_misc in chroot')
                #cmd = 'umount %s' % binfmt
                cmd = ['umount', str(binfmt_misc)]
                runlog(cmd)
            # hack to stop mdadm on target
            mdstat = self.target / 'proc/mdstat'
            if mdstat.isfile():
                mdadm_initscript = self.target / 'etc/init.d/mdadm'
                if mdadm_initscript.isfile():
                    self.log.info("Stopping mdadm from running on target.")
                    cmd = ['chroot', self.target, '/etc/init.d/mdadm', 'stop']
                    runlog(cmd)
        if fs == 'devpts':
            target = self.target / 'dev' / 'pts'
        #cmd = 'umount %s' % target
        cmd = ['umount', str(target)]
        runlog(cmd)
        
    def _target_proc_mounted(self):
        testfile = self.target / 'proc/version'
        return testfile.isfile()

    def _target_sys_mounted(self):
        testdir = self.target / 'sys/kernel'
        return testdir.isdir()
    
    def mount_target_proc(self):
        self.check_bootstrap()
        self._mount_target_virtfs('proc')

    def mount_target_sys(self):
        self.check_bootstrap()
        self._mount_target_virtfs('sys')

    def mount_target_devpts(self):
        self.check_bootstrap()
        self._mount_target_virtfs('devpts')
        
    def umount_target_proc(self):
        self.check_target_proc_mounted()
        self._umount_target_virtfs('proc')

    def umount_target_sys(self):
        self.check_target_sys_mounted()
        self._umount_target_virtfs('sys')

    def umount_target_devpts(self):
        self._umount_target_virtfs('devpts')
        
    def install(self):
        self.check_target_proc_mounted()
        self.check_target_sys_mounted()
        self.check_installer_set()
        self.installer.run_all_processes()
        # this is now done in post_process
        #self._install_finished = True

    def log_all_processes_finished(self):
        self.log.info('-'*30)
        self.log.info('%s processes finished' % self.__class__.__name__)
        self.log.info('-'*30)

    def save_logfile_in_target(self):
        install_log = self.target / 'root/paella/install.log'
        self.mainlog.filename.copyfile(install_log)

    # if scripts are hooked into certain processes, we
    # need to mark those processes as being completed
    # in order for other processes to be run.
    def post_process(self, procname):
        name = self.__class__.__name__
        self.log.info('%s(%s) post_process' % (name, procname))
        if procname == 'bootstrap':
            self.log.info('%s marking %s finished' % (name, procname))
            self._bootstrapped = True
        elif procname == 'install':
            self.log.info('%s marking %s finished' % (name, procname))
            self._install_finished = True
class InstallerTools(object):
    def __init__(self):
        object.__init__(self)
        self.cfg = PaellaConfig()
        self.conn = InstallerConnection()
        self.profile = os.environ['PAELLA_PROFILE']
        self.target = path(os.environ['PAELLA_TARGET'])
        self.machine = None
        self.trait = None
        self.suite = get_suite(self.conn, self.profile)
        self.pr = Profile(self.conn)
        self.pr.set_profile(self.profile)
        self.traitlist = self.pr.make_traitlist()
        self.pe = ProfileEnvironment(self.conn, self.profile)
        self.tp = TraitParent(self.conn, self.suite)
        self.fm = Family(self.conn)
        self.tr = Trait(self.conn, self.suite)
        self.families = list(self.fm.get_related_families(self.pr.get_families()))
        self._envv = None
        self.default = DefaultEnvironment(self.conn)
        #self.installer = TraitInstaller(self.conn, self.suite)
        self.installer = ProfileInstaller(self.conn)
        self.installer.set_logfile()
        self.installer.set_profile(self.profile)
        self.installer.set_target(self.target)
        if os.environ.has_key('PAELLA_MACHINE'):
            self.machine = os.environ['PAELLA_MACHINE']
        if os.environ.has_key('PAELLA_TRAIT'):
            self.set_trait(os.environ['PAELLA_TRAIT'])
             

    # this needs updating for machine type data
    def env(self):
        env = TemplatedEnvironment(self.tp.Environment())
        env.update(self.pr.get_family_data())
        env.update(self.pr.get_profile_data())
        return env

    def set_trait(self, trait):
        self.trait = trait
        self.tp.set_trait(trait)
        self.tr.set_trait(trait)
        self.parents = self.tr.parents()
        self._envv = self.env()
        tinstaller = self.installer.installer
        tinstaller.set_trait(trait)
        self.packages = tinstaller.traitpackage.packages()
        self.templates = tinstaller.traittemplate.templates()
        
    def get(self, key):
        if self._envv is None:
            raise Error, 'need to set trait first'
        return self._envv.dereference(key)

    def lget(self, key):
        key = '_'.join([self.trait, key])
        return self.get(key)

    def install_modules(self, name):
        modules = str2list(self.get(name))
        print 'installing modules', modules, 'to %s/etc/modules' % self.target
        setup_modules(self.target, modules)

    def remove_packages(self, packages=None):
        if packages is None:
            packages = self.packages
        if len(packages):
            if hasattr(packages[0], 'package'):
                packages = [p.package for p in packages]
        package_list = ' '.join(packages)
        command = 'apt-get -y remove %s' % package_list
        self.installer.run('remove', command, proc=True)

    def chroot_command(self, cmd):
        return 'chroot %s %s' % (self.target, cmd)
Exemple #10
0
class MachineInstaller(BaseChrootInstaller):
    def __init__(self, conn):
        BaseChrootInstaller.__init__(self, conn)
        self.machine = MachineHandler(self.conn)
        self.processes = DEFAULT_PROCESSES
        self._process_map = {
            'setup_disks': self.setup_disks,
            'mount_target': self.mount_target,
            'bootstrap': self.bootstrap_target,
            'make_device_entries': self.make_device_entries,
            'apt_sources_installer': self.setup_apt_sources_installer,
            'ready_base': self.ready_base_for_install,
            'mount_target_proc': self.mount_target_proc,
            'install': self.install_to_target,
            'install_fstab': self.install_fstab,
            'install_modules': self.install_modules,
            'install_kernel': self.install_kernel,
            'apt_sources_final': self.setup_apt_sources_final,
            'umount_target_proc': self.umount_target_proc
        }
        self.helper = None

    def process(self):
        mach = self.machine.current.machine
        self.log.info('Starting machine install process for %s' % mach)
        for proc in self.processes:
            self.log.info('processing %s for machine %s' % (proc, mach))
            self.run_process(proc)
            self.log.info('processed %s for machine %s' % (proc, mach))
        self.log.info('Ending machine install process for %s' % mach)

    def _make_script(self, name):
        script = self.machine.get_script(name)
        if script is not None:
            return make_script(name, script, '/')
        else:
            return None

    def run_process(self, proc):
        info = self.log.info
        self.start_process(proc)
        script = self._make_script(proc)
        mtype = self.machine.current.machine_type
        if script is None:
            info('No script for process %s on machine type %s' % (proc, mtype))
            if proc in self._process_map:
                info('Running default process %s' % proc)
                self._process_map[proc]()
            else:
                info('Nothing to do for process %s' % proc)
        else:
            self.log.info('%s script exists for %s' % (proc, mtype))
            self.run_process_script(proc, script)
        self.finish_process(proc)

    def start_process(self, proc):
        self._check_target()
        if proc == 'bootstrap':
            self._check_target_exists()

    def finish_process(self, proc):
        if proc == 'mount_target':
            self._mounted = True
            self.log.info('Target should be mounted now.')
        elif proc == 'bootstrap':
            self.log.info('Target should be bootstrapped now.')
            self._bootstrapped = True

    def _runscript(self, script, name, info):
        self.log.info(info['start'])
        runvalue = self.run(name, script, chroot=False)
        os.remove(script)
        self.log.info(info['done'])
        return runvalue

    def run_process_script(self, proc, script):
        info = scriptinfo(proc)
        if self._runscript(script, proc, info):
            raise InstallError, 'Error running script %s' % proc

    def _check_mounted(self):
        self._check_target_exists()
        if not self._mounted:
            raise InstallError, 'target not mounted'

    def _check_bootstrap(self):
        self._check_mounted()
        BaseChrootInstaller._check_bootstrap(self)

    def set_machine(self, machine):
        self.machine.set_machine(machine)
        try:
            logfile = os.environ['LOGFILE']
        except KeyError:
            logfile = '/paellalog/paella-install-%s.log' % machine
        os.environ['PAELLA_LOGFILE'] = logfile
        # this needs to be removed sometime
        os.environ['LOGFILE'] = logfile
        os.environ['PAELLA_MACHINE'] = machine
        disklogpath = join(dirname(logfile), 'disklog-%s' % machine)
        if not os.path.isdir(disklogpath):
            makepaths(disklogpath)
        self.disklogpath = disklogpath
        self.curenv = CurrentEnvironment(self.conn,
                                         self.machine.current.machine)
        self.set_logfile(logfile)
        self.log.info('Machine Installer set machine to %s' % machine)
        self.mtypedata = self.machine.mtype.get_machine_type_data()

    def install(self, machine, target):
        self.set_machine(machine)
        self.setup_installer()
        self.set_target(target)
        makepaths(target)
        self.log.info('Installer set to install %s to %s' % (machine, target))
        self.helper = MachineInstallerHelper(self)
        self.helper.curenv = self.curenv
        self.process()

    def setup_installer(self):
        machine = self.machine.current.machine
        profile = self.machine.current.profile
        self.log.info('Setting up profile installer for %s' % machine)
        self.installer = ProfileInstaller(self.conn)
        self.installer.log = self.log
        self.installer.mtypedata = self.mtypedata
        self.installer.set_profile(profile)
        self.suite = self.installer.suite
        self._installer_ready = True
        self.log.info('Profile installer ready for %s' % machine)

    def setup_disks(self):
        "this is a default process"
        self.helper.setup_disks()

    def mount_target(self):
        "this is a default process"
        self._check_target()
        makepaths(self.target)
        device = self.machine.array_hack()
        #mounts = self.machine.get_ordered_fsmounts()
        mounts = self.machine.get_installable_fsmounts()
        mount_target(self.target, mounts, device)
        self._mounted = True

    def bootstrap_target(self):
        "this is a default process"
        self.helper.bootstrap_target()

    def make_device_entries(self):
        "this is a default process"
        if self.defenv.is_it_true('installer', 'use_devices_tarball'):
            runlog('echo extracting devices tarball')
            self._extract_devices_tarball()
        else:
            runlog('echo using MAKEDEV to make generic devices')
            self.make_generic_devices()
        self.make_disk_devices()

    def setup_apt_sources_installer(self):
        "this is a default process"
        make_sources_list(self.conn, self.target, self.suite)

    def ready_base_for_install(self):
        "this is a default process"
        set_root_passwd(self.target, myline)
        make_interfaces_simple(self.target)
        devices = self.helper.get_raid_devices()
        if devices:
            create_mdadm_conf(self.target, devices)

    def mount_target_proc(self):
        "this is a default process"
        echo('mounting target /proc')
        mount_target_proc(self.target)

    def install_to_target(self):
        "this is a default process"
        os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
        self._check_target()
        self._check_installer()
        self.installer.set_target(self.target)
        self.installer.process()

    def install_modules(self):
        "this is a default process"
        modules = self.machine.get_modules()
        setup_modules(self.target, modules)

    def install_kernel(self):
        "this is a default process"
        kernel = self.machine.current.kernel
        echo('installing kernel %s' % kernel)
        install_kernel(kernel, self.target)

    def setup_apt_sources_final(self):
        "this is a default process"
        make_official_sources_list(self.conn, self.target, self.suite)

    def install_fstab(self):
        "this is a default process"
        fstab = self.machine.make_fstab()
        make_fstab(fstab, self.target)

    def umount_target_proc(self):
        "this is a default process"
        echo('unmounting target /proc')
        mount_target_proc(self.target, umount=True)

    def _extract_devices_tarball(self):
        dtball = self.defenv.get('installer', 'devices_tarball')
        devpath = join(self.target, 'dev')
        runvalue = extract_tarball(devpath, dtball)
        if runvalue:
            raise Error, 'problem extracting devices tarball'

    def make_generic_devices(self):
        makedev(self.target, ['generic'])

    def make_disk_devices(self):
        devices = map(basename, self.machine.get_disk_devices())
        makedev(self.target, devices)
 def setup_installer(self):
     profile = self.machine.current.profile
     self.installer = ProfileInstaller(self.conn, self.cfg)
     self.installer.set_profile(profile)
     self.suite = self.installer.suite
Exemple #12
0
 def setup_installer(self):
     self.installer = ProfileInstaller(self.conn, self.cfg)
     self.installer.set_profile(self.profile)
     self.suite = get_suite(self.conn, self.profile)
Exemple #13
0
class ChrootInstaller(BaseInstaller):
    # we may need more __init__ args later
    def __init__(self, conn):
        BaseInstaller.__init__(self, conn)
        self._bootstrapped = False
        self._install_finished = False

        self._processes = [
            'ready_target', 'bootstrap', 'mount_target_proc',
            'mount_target_sys', 'make_device_entries', 'mount_target_devpts',
            'apt_sources_installer', 'ready_base_for_install', 'pre_install',
            'install', 'post_install', 'apt_sources_final',
            'umount_target_sys', 'umount_target_proc'
        ]
        # pre_install is unmapped
        # post_install is unmapped
        self._process_map = dict(
            ready_target=self.create_target_directory,
            bootstrap=self.bootstrap_target,
            mount_target_proc=self.mount_target_proc,
            mount_target_sys=self.mount_target_sys,
            make_device_entries=self.make_device_entries,
            mount_target_devpts=self.mount_target_devpts,
            apt_sources_installer=self.apt_sources_installer,
            ready_base_for_install=self.ready_base_for_install,
            install=self.install,
            apt_sources_final=self.apt_sources_final,
            umount_target_sys=self.umount_target_sys,
            umount_target_proc=self.umount_target_proc)
        # this is only used in the machine installer
        self.mtypedata = {}

    # the default script for the chroot installer is None
    def make_script(self, procname):
        return None

    def set_logfile(self, logfile):
        BaseInstaller.set_logfile(self, logfile)
        self.log.info('-' * 30)
        msg = '%s initialized' % self.__class__.__name__
        self.log.info(msg)
        self.log.info('-' * 30)

    @requires_target_set
    def set_profile(self, profile):
        self.installer = ProfileInstaller(self)
        self.installer.mtypedata.update(self.mtypedata)
        self.installer.set_profile(profile)
        self.set_suite(self.installer.suite)

    @requires_target_exists
    def _bootstrap_with_tarball(self, suite):
        suite_path = path(self.defenv.get('installer', 'suite_storage'))
        filename = '%s.tar.gz' % suite
        basefile = suite_path / filename
        taropts = '-xzf'
        if not basefile.exists():
            filename = '%s.tar' % suite
            basefile = suite_path / filename
            taropts = '-xf'
        cmd = 'tar -C %s %s %s' % (self.target, taropts, basefile)
        # if cmd returns nonzero, runlog will raise an error
        runlog(cmd)
        # we need to do certain things here that debootstrap
        # does for us, like copy /etc/resolv.conf
        self._bootstrapped = True

    @requires_target_exists
    def _bootstrap_with_debootstrap(self, suite):
        mirror = self.defenv.get('installer', 'http_mirror')
        cmd = debootstrap(suite, self.target, mirror)
        # if cmd returns nonzero, runlog will raise an error
        runlog(cmd)
        self._bootstrapped = True

    @requires_suite_set
    def bootstrap_target(self):
        if not self.target.exists():
            self.target.mkdir()
        if not self.target.isdir():
            raise InstallTargetError, "%s is not a directory" % self.target
        if self.defenv.getboolean('installer', 'bootstrap_target'):
            self.log.info('bootstrapping with debootstrap')
            self._bootstrap_with_debootstrap(self.base_suite)
        else:
            self.log.info('bootstrapping with premade tarball')
            self._bootstrap_with_tarball(self.base_suite)
        # here we add the apt keys that are needed
        aptkeys = AptKeyHandler(self.conn)
        keys = self.defenv.get_list('archive_keys', 'installer')
        for key in keys:
            row = aptkeys.get_row(key)
            filename = self.target / ('%s.key' % key)
            if filename.exists():
                raise RuntimeError, "%s already exists" % filename
            keyfile = file(filename, 'w')
            keyfile.write(row.data)
            keyfile.close()
            #self.chroot('apt-key add %s.key' % key)
            self.chroot(['apt-key', 'add', '%s.key' % key])
            os.remove(filename)
            if filename.exists():
                raise RuntimeError, "%s wasn't deleted" % filename
            self.log.info('added key %s (%s) to apt' % (key, row.keyid))

    @requires_bootstrap
    def make_device_entries(self):
        self.log.info('nothing done for make_device_entries yet')

    @requires_bootstrap
    def apt_sources_installer(self):
        make_sources_list(self.conn, self.target, self.suite)

    @requires_install_complete
    def apt_sources_final(self):
        sourceslist = self.target / 'etc/apt/sources.list'
        sourceslist_installer = path('%s.installer' % sourceslist)
        os.rename(sourceslist, sourceslist_installer)
        make_official_sources_list(self.conn, self.target, self.suite)

    # this is probably not useful anymore
    # it still has a purpose in the machine installer -
    #  it sets up the mdadm.conf file with the raid devices it creates
    #  if it creates any.
    @requires_bootstrap
    def ready_base_for_install(self):
        # update the package lists
        #self.chroot('apt-get -y update')
        self.chroot(['apt-get', '-y', 'update'])

    # common method for mounting /proc and /sys
    # here fs is either 'proc' or 'sys' or 'devpts'
    def _mount_target_virtfs(self, fs):
        fstype = dict(proc='proc', sys='sysfs', devpts='devpts')
        target = self.target / fs
        if fs == 'devpts':
            target = self.target / 'dev' / 'pts'
        if not target.isdir():
            target.mkdir()
        #cmd = 'mount -t %s none %s' % (fstype[fs], target)
        cmd = ['mount', '-t', fstype[fs], 'none', str(target)]
        runlog(cmd)

    def _umount_target_virtfs(self, fs):
        # work around binfmt-support /proc locking
        # found this idea while messing around in live-helper
        target = self.target / fs
        if fs == 'proc':
            binfmt_misc = self.target / 'proc/sys/fs/binfmt_misc'
            status = binfmt_misc / 'status'
            if status.exists():
                self.log.info('Unmounting /proc/sys/fs/binfmt_misc in chroot')
                #cmd = 'umount %s' % binfmt
                cmd = ['umount', str(binfmt_misc)]
                runlog(cmd)
        if fs == 'devpts':
            target = self.target / 'dev' / 'pts'
        #cmd = 'umount %s' % target
        cmd = ['umount', str(target)]
        runlog(cmd)

    def _target_proc_mounted(self):
        testfile = self.target / 'proc/version'
        return testfile.isfile()

    def _target_sys_mounted(self):
        testdir = self.target / 'sys/kernel'
        return testdir.isdir()

    @requires_bootstrap
    def mount_target_proc(self):
        self._mount_target_virtfs('proc')

    @requires_bootstrap
    def mount_target_sys(self):
        self._mount_target_virtfs('sys')

    def mount_target_devpts(self):
        self._mount_target_virtfs('devpts')

    @requires_target_proc_mounted
    def umount_target_proc(self):
        self._umount_target_virtfs('proc')

    @requires_target_sys_mounted
    def umount_target_sys(self):
        self._umount_target_virtfs('sys')

    def umount_target_devpts(self):
        self._umount_target_virtfs('devpts')

    @requires_target_proc_mounted
    @requires_target_sys_mounted
    @requires_installer_set
    def install(self):
        self.installer.run_all_processes()
        self._install_finished = True

    def log_all_processes_finished(self):
        self.log.info('-' * 30)
        self.log.info('%s processes finished' % self.__class__.__name__)
        self.log.info('-' * 30)

    def save_logfile_in_target(self):
        install_log = self.target / 'root/paella/install.log'
        self.mainlog.filename.copyfile(install_log)
class NewInstaller(object):
    def __init__(self, conn, cfg):
        object.__init__(self)
        self.conn = conn
        self.cfg = cfg
        self.machine = MachineHandler(self.conn)
        self.cursor = StatementCursor(self.conn)
        self.target = None
        self.installer = None
        self._mounted = None
        self._bootstrapped = None
        self.debmirror = self.cfg.get('debrepos', 'http_mirror')
                
    def _check_target(self):
        if not self.target:
            raise Error, 'no target specified'

    def _check_installer(self):
        if not self.installer:
            raise Error, 'no installer available'

    def _check_mounted(self):
        self._check_target()
        if not self._mounted:
            raise Error, 'target not mounted'

    def _check_bootstrap(self):
        self._check_mounted()
        if not self._bootstrapped:
            raise Error, 'target not bootstrapped'
        
    def set_machine(self, machine):
        self.machine.set_machine(machine)
        try:
            logfile = os.environ['LOGFILE']
        except KeyError:
            logfile = '/var/log/paella-install-%s.log' % machine
        os.environ['LOGFILE'] = logfile

    def make_filesystems(self):
        device = self.machine.array_hack(self.machine.current.machine_type)
        all_fsmounts = self.machine.get_installable_fsmounts()
        env = CurrentEnvironment(self.conn, self.machine.current.machine)
        for row in all_fsmounts:
            pdev = device + str(row.partition)
            if row.mnt_name in env.keys():
                print '%s held' % row.mnt_name
            else:
                print 'making filesystem for', row.mnt_name
                make_filesystem(pdev, row.fstype)

    def set_target(self, target):
        self.target = target

    def _pdev(self, device, partition):
        return device + str(partition)

    def ready_target(self):
        self._check_target()
        makepaths(self.target)
        device = self.machine.array_hack(self.machine.current.machine_type)
        clause = Eq('filesystem', self.machine.current.filesystem)
        clause &= Gt('partition', '0')
        table = 'filesystem_mounts natural join mounts'
        mounts = self.cursor.select(table=table, clause=clause, order='mnt_point')
        if mounts[0].mnt_point != '/':
            raise Error, 'bad set of mounts', mounts
        pdev = self._pdev(device, mounts[0].partition)
        print 'mounting target', pdev, self.target
        runlog('mount %s %s' % (pdev, self.target))
        for mnt in mounts[1:]:
            tpath = os.path.join(self.target, mnt.mnt_point[1:])
            makepaths(tpath)
            pdev = self._pdev(device, mnt.partition)
            runlog('mount %s %s' % (pdev, tpath))
        self._mounted = True
        
    def apt_update_target(self):
        raise Error, "deprecated --don't do this anymore"
        os.system('chroot %s apt-get -y update' % self.target)

    def setup_installer(self):
        profile = self.machine.current.profile
        self.installer = ProfileInstaller(self.conn, self.cfg)
        self.installer.set_profile(profile)
        self.suite = self.installer.suite
                        
    def partition_disks(self):
        clause = Eq('machine_type', self.machine.current.machine_type)
        disk_rows = self.cursor.select(table='machine_disks', clause=clause)
        for row in disk_rows:
            print 'partitioning', row.diskname, row.device
            dump = self.machine.make_partition_dump(row.diskname, row.device)
            i, o = os.popen2('sfdisk %s' % row.device)
            i.write(dump)
            i.close()

    def bootstrap_target(self):
        self._check_mounted()
        self._check_installer()
        runlog(debootstrap(self.suite, self.target, self.debmirror))
        self._bootstrapped = True
        
    def ready_base_for_install(self):
        self._check_bootstrap()
        self._check_installer()
        fstab = self.machine.make_fstab()
        ready_base_for_install(self.target, self.cfg, self.suite, fstab)
        
    def install_to_target(self):
        os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
        self._check_target()
        self._check_installer()
        self.installer.set_target(self.target)
        self.installer.process()        

    def post_install(self):
        print 'post_install'
        kernel = self.machine.current.kernel
        print 'installing kernel', kernel
        install_kernel(kernel, self.target)
        print 'kernel installed'
        
    
    def install(self, machine, target):
        self.set_machine(machine)
        self.partition_disks()
        self.make_filesystems()
        self.setup_installer()
        self.set_target(target)
        self.ready_target()
        self.bootstrap_target()
        self.ready_base_for_install()
        self.install_to_target()
        self.post_install()
Exemple #15
0
class ChrootInstaller(object):
    def __init__(self, conn, cfg):
        object.__init__(self)
        self.conn = conn
        self.cfg = cfg
        self.cursor = StatementCursor(self.conn)
        self.target = None
        self.installer = None
        self._mounted = None
        self._bootstrapped = None
        self.debmirror = self.cfg.get('debrepos', 'http_mirror')

    def _check_target(self):
        if not self.target:
            raise Error, 'no target specified'

    def _check_installer(self):
        if not self.installer:
            raise Error, 'no installer available'

    def _check_bootstrap(self):
        self._check_target()
        if not self._bootstrapped:
            raise Error, 'target not bootstrapped'

    def set_target(self, target):
        self.target = target

    def set_profile(self, profile):
        self.profile = profile

    def ready_target(self):
        self._check_target()

    def setup_installer(self):
        self.installer = ProfileInstaller(self.conn, self.cfg)
        self.installer.set_profile(self.profile)
        self.suite = get_suite(self.conn, self.profile)

    def bootstrap_target(self):
        self._check_target()
        self._check_installer()
        runlog(debootstrap(self.suite, self.target, self.debmirror))
        self._bootstrapped = True

    def ready_base_for_install(self):
        self._check_bootstrap()
        self._check_installer()
        fstab = '#unconfigured for chroot install\n'
        ready_base_for_install(self.target, self.cfg, self.suite, fstab)

    def install_to_target(self):
        os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
        self._check_target()
        self._check_installer()
        self.installer.set_target(self.target)
        self.installer.process()

    def post_install(self):
        print 'post_install'
        kernel = self.machine.current.kernel
        print 'installing kernel', kernel
        install_kernel(kernel, self.target)
        print 'kernel installed'

    def install(self, profile, target):
        self.set_profile(profile)
        self.setup_installer()
        self.set_target(target)
        self.ready_target()
        self.bootstrap_target()
        self.ready_base_for_install()
        self.install_to_target()
class NewInstaller(object):
    def __init__(self, conn, cfg):
        object.__init__(self)
        self.conn = conn
        self.cfg = cfg
        self.machine = MachineHandler(self.conn)
        self.cursor = StatementCursor(self.conn)
        self.target = None
        self.installer = None
        self._mounted = None
        self._bootstrapped = None
        self.debmirror = self.cfg.get('debrepos', 'http_mirror')
        self._raid_setup = False
        self._raid_drives = {}

    def _check_target(self):
        if not self.target:
            raise Error, 'no target specified'

    def _check_installer(self):
        if not self.installer:
            raise Error, 'no installer available'

    def _check_mounted(self):
        self._check_target()
        if not self._mounted:
            raise Error, 'target not mounted'

    def _check_bootstrap(self):
        self._check_mounted()
        if not self._bootstrapped:
            raise Error, 'target not bootstrapped'

    def set_machine(self, machine):
        self.machine.set_machine(machine)
        try:
            logfile = os.environ['LOGFILE']
        except KeyError:
            logfile = '/paellalog/paella-install-%s.log' % machine
        os.environ['LOGFILE'] = logfile
        os.environ['PAELLA_MACHINE'] = machine

    def make_filesystems(self):
        device = self.machine.array_hack(self.machine.current.machine_type)
        mddev = False
        if device == '/dev/md':
            mdnum = 0
            mddev = True
        all_fsmounts = self.machine.get_installable_fsmounts()
        env = CurrentEnvironment(self.conn, self.machine.current.machine)
        for row in all_fsmounts:
            if mddev:
                pdev = '/dev/md%d' % mdnum
                mdnum += 1
            else:
                pdev = device + str(row.partition)
            if row.mnt_name in env.keys():
                print '%s held' % row.mnt_name
            else:
                print 'making filesystem for', row.mnt_name
                make_filesystem(pdev, row.fstype)

    def set_target(self, target):
        self.target = target

    def _pdev(self, device, partition):
        return device + str(partition)

    def ready_target(self):
        self._check_target()
        makepaths(self.target)
        device = self.machine.array_hack(self.machine.current.machine_type)
        clause = Eq('filesystem', self.machine.current.filesystem)
        clause &= Gt('partition', '0')
        table = 'filesystem_mounts natural join mounts'
        mounts = self.cursor.select(table=table,
                                    clause=clause,
                                    order='mnt_point')
        if mounts[0].mnt_point != '/':
            raise Error, 'bad set of mounts', mounts
        mddev = False
        mdnum = 0
        if device == '/dev/md':
            mddev = True
            pdev = '/dev/md0'
            mdnum += 1
        else:
            pdev = self._pdev(device, mounts[0].partition)
        print 'mounting target', pdev, self.target
        clause &= Neq('mnt_point', '/')
        mounts = self.cursor.select(table=table, clause=clause, order='ord')
        runlog('mount %s %s' % (pdev, self.target))
        for mnt in mounts:
            tpath = os.path.join(self.target, mnt.mnt_point[1:])
            makepaths(tpath)
            if mddev:
                pdev = '/dev/md%d' % mdnum
            else:
                pdev = self._pdev(device, mnt.partition)
            mdnum += 1
            runlog('mount %s %s' % (pdev, tpath))
        self._mounted = True

    def setup_installer(self):
        profile = self.machine.current.profile
        self.installer = ProfileInstaller(self.conn, self.cfg)
        self.installer.set_profile(profile)
        self.suite = self.installer.suite

    def organize_disks(self):
        return self.machine.check_machine_disks(
            self.machine.current.machine_type)

    def partition_disks(self):
        disks = self.organize_disks()
        for diskname in disks:
            for device in disks[diskname]:
                self._partition_disk(diskname, device)
            if len(disks[diskname]) > 1:
                self._raid_setup = True
                self._raid_drives[diskname] = disks[diskname]
                ndev = len(disks[diskname])
                print 'doing raid setup on %s' % diskname
                fs = self.machine.current.filesystem
                print fs
                pnums = [
                    r.partition
                    for r in self.machine.get_installable_fsmounts(fs)
                ]
                mdnum = 0
                for p in pnums:
                    mdadm = 'mdadm --create /dev/md%d' % mdnum
                    mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev)
                    devices = ['%s%s' % (d, p) for d in disks[diskname]]
                    command = mdadm + ' '.join(devices)
                    print command
                    yesman = 'bash -c "yes | %s"' % command
                    print yesman
                    os.system(yesman)
                    mdnum += 1
                print 'doing raid setup on %s' % str(disks[diskname])
                mdstat = file('/proc/mdstat').read()
                while mdstat.find('resync') > -1:
                    sleep(10)
                    mdstat = file('/proc/mdstat').read()

    def _partition_disk(self, diskname, device):
        print 'partitioning', diskname, device
        dump = self.machine.make_partition_dump(diskname, device)
        i, o = os.popen2('sfdisk %s' % device)
        i.write(dump)
        i.close()

    def bootstrap_target(self):
        self._check_mounted()
        self._check_installer()
        runlog(debootstrap(self.suite, self.target, self.debmirror))
        self._bootstrapped = True

    def _make_generic_devices(self, devices):
        here = os.getcwd()
        os.chdir(join(self.target, 'dev'))
        for dev in devices:
            runlog('echo making device %s with MAKEDEV' % dev)
            runlog('./MAKEDEV %s' % dev)
        os.chdir(here)

    def make_disk_devices(self):
        devices = map(basename, self.machine.get_disk_devices())
        self._make_generic_devices(devices)

    def make_tty_devices(self):
        self._make_generic_devices(['console'])

    def make_input_devices(self):
        self._make_generic_devices(['input'])

    def make_generic_devices(self):
        #devices = ['std', 'console', 'pty', 'tap', 'sg', 'input', 'audio']
        self._make_generic_devices(['generic'])

    def ready_base_for_install(self):
        self._check_bootstrap()
        self._check_installer()
        fstab = self.machine.make_fstab()
        ready_base_for_install(self.target, self.cfg, self.suite, fstab)
        self.make_generic_devices()
        self.make_disk_devices()
        if self._raid_setup:
            mdpath = join(self.target, 'etc/mdadm')
            makepaths(mdpath)
            mdconfname = join(mdpath, 'mdadm.conf')
            mdconf = file(mdconfname, 'w')
            for diskname in self._raid_drives:
                devices = ['%s*' % d for d in self._raid_drives[diskname]]
                line = 'DEVICE %s' % ' '.join(devices)
                mdconf.write(line + '\n')
            mdconf.close()
            mdconf = file(mdconfname, 'a')
            arrdata = commands.getoutput('mdadm -E --config=%s -s' %
                                         mdconfname)
            mdconf.write(arrdata + '\n')
            mdconf.write('\n')
            mdconf.close()

    def install_to_target(self):
        os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
        self._check_target()
        self._check_installer()
        self.installer.set_target(self.target)
        self.installer.process()

    def post_install(self):
        print 'post_install'
        modules = self.machine.get_modules()
        print 'installing modules', modules
        setup_modules(self.target, modules)
        print 'modules installed'
        kernel = self.machine.current.kernel
        print 'installing kernel', kernel
        install_kernel(kernel, self.target)
        print 'kernel installed'

    def install(self, machine, target):
        self.set_machine(machine)
        self.partition_disks()
        self.make_filesystems()
        self.setup_installer()
        self.set_target(target)
        self.ready_target()
        self.bootstrap_target()
        self.ready_base_for_install()
        self.install_to_target()
        self.post_install()
Exemple #17
0
 def setup_installer(self):
     self.installer = ProfileInstaller(self.conn)
     self.installer.log = self.log
     self.installer.set_profile(self.profile)
     self.suite = self.installer.suite
     self._installer_ready = True
Exemple #18
0
class ChrootInstaller(BaseChrootInstaller):
    def __init__(self, conn, logfile=None):
        BaseChrootInstaller.__init__(self, conn)
        self.conn = conn
        self.cursor = StatementCursor(self.conn)
        self._mounted = None
        self._installer_ready = False
        self._base_ready = False
        if logfile is None:
            self.set_logfile(logfile)
        if logfile and type(logfile) is str:
            if not os.environ.has_key('PAELLA_LOGFILE'):
                os.environ['PAELLA_LOGFILE'] = logfile
            self.set_logfile(logfile)
        if logfile is False:
            pass

    def _check_base_ready(self):
        if not self._base_ready:
            raise InstallError, 'base is not ready for install.'

    def set_profile(self, profile):
        self.profile = profile

    def ready_target(self):
        self._check_target_exists()

    def setup_installer(self):
        self.installer = ProfileInstaller(self.conn)
        self.installer.log = self.log
        self.installer.set_profile(self.profile)
        self.suite = self.installer.suite
        self._installer_ready = True

    def bootstrap_target(self):
        self._bootstrap_target()
        self._check_bootstrap()

    def ready_base_for_install(self):
        self._check_bootstrap()
        fstab = '#unconfigured for chroot install\n'
        ready_base_for_install(self.target, self.conn, self.suite, fstab)
        self._mount_target_proc()
        self._check_target_proc()
        cmd = self.command('apt-get', '-y update', chroot=True)
        runvalue = runlog(cmd)
        if runvalue:
            raise InstallError, 'problem updating the apt lists.'
        if os.environ.has_key('FAKE_START_STOP_DAEMON'):
            make_fake_start_stop_daemon(self.target)
        self._base_ready = True

    def install_to_target(self):
        self._check_base_ready()
        os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
        self.installer.set_target(self.target)
        self.installer.process()

    def post_install(self):
        self._umount_target_proc()
        if os.environ.has_key('FAKE_START_STOP_DAEMON'):
            remove_fake_start_stop_daemon(self.target)

    def install(self, profile, target):
        self.set_profile(profile)
        self.setup_installer()
        self.set_target(target)
        self.ready_target()
        self.bootstrap_target()
        self.ready_base_for_install()
        self.install_to_target()
        self.post_install()
Exemple #19
0
class NewInstaller(object):
    def __init__(self, conn, cfg):
        object.__init__(self)
        self.conn = conn
        self.cfg = cfg
        self.machine = MachineHandler(self.conn)
        self.cursor = StatementCursor(self.conn)
        self.target = None
        self.installer = None
        self._mounted = None
        self._bootstrapped = None
        self.debmirror = self.cfg.get('debrepos', 'http_mirror')

    def _check_target(self):
        if not self.target:
            raise Error, 'no target specified'

    def _check_installer(self):
        if not self.installer:
            raise Error, 'no installer available'

    def _check_mounted(self):
        self._check_target()
        if not self._mounted:
            raise Error, 'target not mounted'

    def _check_bootstrap(self):
        self._check_mounted()
        if not self._bootstrapped:
            raise Error, 'target not bootstrapped'

    def set_machine(self, machine):
        self.machine.set_machine(machine)
        try:
            logfile = os.environ['LOGFILE']
        except KeyError:
            logfile = '/paellalog/paella-install-%s.log' % machine
        os.environ['LOGFILE'] = logfile
        os.environ['PAELLA_MACHINE'] = machine

    def make_filesystems(self):
        device = self.machine.array_hack(self.machine.current.machine_type)
        all_fsmounts = self.machine.get_installable_fsmounts()
        env = CurrentEnvironment(self.conn, self.machine.current.machine)
        for row in all_fsmounts:
            pdev = device + str(row.partition)
            if row.mnt_name in env.keys():
                print '%s held' % row.mnt_name
            else:
                print 'making filesystem for', row.mnt_name
                make_filesystem(pdev, row.fstype)

    def set_target(self, target):
        self.target = target

    def _pdev(self, device, partition):
        return device + str(partition)

    def ready_target(self):
        self._check_target()
        makepaths(self.target)
        device = self.machine.array_hack(self.machine.current.machine_type)
        clause = Eq('filesystem', self.machine.current.filesystem)
        clause &= Gt('partition', '0')
        table = 'filesystem_mounts natural join mounts'
        mounts = self.cursor.select(table=table,
                                    clause=clause,
                                    order='mnt_point')
        if mounts[0].mnt_point != '/':
            raise Error, 'bad set of mounts', mounts
        pdev = self._pdev(device, mounts[0].partition)
        print 'mounting target', pdev, self.target
        runlog('mount %s %s' % (pdev, self.target))
        for mnt in mounts[1:]:
            tpath = os.path.join(self.target, mnt.mnt_point[1:])
            makepaths(tpath)
            pdev = self._pdev(device, mnt.partition)
            runlog('mount %s %s' % (pdev, tpath))
        self._mounted = True

    def setup_installer(self):
        profile = self.machine.current.profile
        self.installer = ProfileInstaller(self.conn, self.cfg)
        self.installer.set_profile(profile)
        self.suite = self.installer.suite

    def organize_disks(self):
        return self.machine.check_machine_disks(
            self.machine.current.machine_type)

    def partition_disks(self):
        disks = self.organize_disks()
        for diskname in disks:
            for device in disks[diskname]:
                self._partition_disk(diskname, device)
            if len(disks[diskname]) > 1:
                ndev = len(disks[diskname])
                print 'doing raid setup on %s' % diskname
                fs = self.machine.current.filesystem
                print fs
                pnums = [
                    r.partition
                    for r in self.machine.get_installable_fsmounts(fs)
                ]
                for p in pnums:
                    mdadm = 'mdadm --create /dev/md%d' % p
                    mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev)
                    devices = ['%s%s' % (d, p) for d in disks[diskname]]
                    command = mdadm + ' '.join(devices)
                    print command
                    yesman = 'bash -c "yes | %s"' % command
                    print yesman
                    os.system(yesman)
                print 'doing raid setup on %s' % str(disks[diskname])
                mdstat = file('/proc/mdstat').read()
                while mdstat.find('resync') > -1:
                    sleep(10)
                    mdstat = file('/proc/mdstat').read()

    def _partition_disk(self, diskname, device):
        print 'partitioning', diskname, device
        dump = self.machine.make_partition_dump(diskname, device)
        i, o = os.popen2('sfdisk %s' % device)
        i.write(dump)
        i.close()

    def bootstrap_target(self):
        self._check_mounted()
        self._check_installer()
        runlog(debootstrap(self.suite, self.target, self.debmirror))
        self._bootstrapped = True

    def ready_base_for_install(self):
        self._check_bootstrap()
        self._check_installer()
        fstab = self.machine.make_fstab()
        ready_base_for_install(self.target, self.cfg, self.suite, fstab)

    def install_to_target(self):
        os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
        self._check_target()
        self._check_installer()
        self.installer.set_target(self.target)
        self.installer.process()

    def post_install(self):
        print 'post_install'
        modules = self.machine.get_modules()
        print 'installing modules', modules
        setup_modules(self.target, modules)
        print 'modules installed'
        kernel = self.machine.current.kernel
        print 'installing kernel', kernel
        install_kernel(kernel, self.target)
        print 'kernel installed'

    def install(self, machine, target):
        self.set_machine(machine)
        self.partition_disks()
        self.make_filesystems()
        self.setup_installer()
        self.set_target(target)
        self.ready_target()
        self.bootstrap_target()
        self.ready_base_for_install()
        self.install_to_target()
        self.post_install()
Exemple #20
0
class ChrootInstaller(BaseInstaller):
    # we may need more __init__ args later
    def __init__(self, conn):
        BaseInstaller.__init__(self, conn)
        self._bootstrapped = False
        self._install_finished = False
        
        self._processes = [
            'ready_target',
            'bootstrap',
            'mount_target_proc',
            'mount_target_sys',
            'make_device_entries',
            'mount_target_devpts',
            'apt_sources_installer',
            'ready_base_for_install',
            'pre_install',
            'install',
            'post_install',
            'apt_sources_final',
            'umount_target_sys',
            'umount_target_proc'
            ]
        # pre_install is unmapped
        # post_install is unmapped
        self._process_map = dict(ready_target=self.create_target_directory,
                                 bootstrap=self.bootstrap_target,
                                 mount_target_proc=self.mount_target_proc,
                                 mount_target_sys=self.mount_target_sys,
                                 make_device_entries=self.make_device_entries,
                                 mount_target_devpts=self.mount_target_devpts,
                                 apt_sources_installer=self.apt_sources_installer,
                                 ready_base_for_install=self.ready_base_for_install,
                                 install=self.install,
                                 apt_sources_final=self.apt_sources_final,
                                 umount_target_sys=self.umount_target_sys,
                                 umount_target_proc=self.umount_target_proc
                                 )
        # this is only used in the machine installer
        self.mtypedata = {}
    
    # the default script for the chroot installer is None
    def make_script(self, procname):
        return None

    def set_logfile(self, logfile):
        BaseInstaller.set_logfile(self, logfile)
        self.log.info('-'*30)
        msg = '%s initialized' % self.__class__.__name__
        self.log.info(msg)
        self.log.info('-'*30)
        
    @requires_target_set
    def set_profile(self, profile):
        self.installer = ProfileInstaller(self)
        self.installer.mtypedata.update(self.mtypedata)
        self.installer.set_profile(profile)
        self.set_suite(self.installer.suite)
    
    
    @requires_target_exists
    def _bootstrap_with_tarball(self, suite):
        suite_path = path(self.defenv.get('installer', 'suite_storage'))
        filename = '%s.tar.gz' % suite
        basefile = suite_path / filename
        taropts = '-xzf'
        if not basefile.exists():
            filename = '%s.tar' % suite
            basefile = suite_path / filename
            taropts = '-xf'
        cmd = 'tar -C %s %s %s' % (self.target, taropts, basefile)
        # if cmd returns nonzero, runlog will raise an error
        runlog(cmd)
        # we need to do certain things here that debootstrap
        # does for us, like copy /etc/resolv.conf
        self._bootstrapped = True
            
    @requires_target_exists
    def _bootstrap_with_debootstrap(self, suite):
        mirror = self.defenv.get('installer', 'http_mirror')
        cmd = debootstrap(suite, self.target, mirror)
        # if cmd returns nonzero, runlog will raise an error
        runlog(cmd)
        self._bootstrapped = True

    @requires_suite_set
    def bootstrap_target(self):
        if not self.target.exists():
            self.target.mkdir()
        if not self.target.isdir():
            raise InstallTargetError, "%s is not a directory" % self.target
        if self.defenv.getboolean('installer', 'bootstrap_target'):
            self.log.info('bootstrapping with debootstrap')
            self._bootstrap_with_debootstrap(self.base_suite)
        else:
            self.log.info('bootstrapping with premade tarball')
            self._bootstrap_with_tarball(self.base_suite)
        # here we add the apt keys that are needed
        aptkeys = AptKeyHandler(self.conn)
        keys = self.defenv.get_list('archive_keys', 'installer')
        for key in keys:
            row = aptkeys.get_row(key)
            filename = self.target / ('%s.key' % key)
            if filename.exists():
                raise RuntimeError, "%s already exists" % filename
            keyfile = file(filename, 'w')
            keyfile.write(row.data)
            keyfile.close()
            #self.chroot('apt-key add %s.key' % key)
            self.chroot(['apt-key', 'add', '%s.key' % key])
            os.remove(filename)
            if filename.exists():
                raise RuntimeError, "%s wasn't deleted" % filename
            self.log.info('added key %s (%s) to apt' % (key, row.keyid))
        
    @requires_bootstrap
    def make_device_entries(self):
        self.log.info('nothing done for make_device_entries yet')
        
    @requires_bootstrap
    def apt_sources_installer(self):
        make_sources_list(self.conn, self.target, self.suite)
        
    @requires_install_complete
    def apt_sources_final(self):
        sourceslist = self.target / 'etc/apt/sources.list'
        sourceslist_installer = path('%s.installer' % sourceslist)
        os.rename(sourceslist, sourceslist_installer)
        make_official_sources_list(self.conn, self.target, self.suite)

    # this is probably not useful anymore
    # it still has a purpose in the machine installer -
    #  it sets up the mdadm.conf file with the raid devices it creates
    #  if it creates any.
    @requires_bootstrap
    def ready_base_for_install(self):
        # update the package lists
        #self.chroot('apt-get -y update')
        self.chroot(['apt-get', '-y', 'update'])
        
        
    # common method for mounting /proc and /sys
    # here fs is either 'proc' or 'sys' or 'devpts'
    def _mount_target_virtfs(self, fs):
        fstype = dict(proc='proc', sys='sysfs', devpts='devpts')
        target = self.target / fs
        if fs == 'devpts':
            target = self.target / 'dev' / 'pts'
        if not target.isdir():
            target.mkdir()
        #cmd = 'mount -t %s none %s' % (fstype[fs], target)
        cmd = ['mount', '-t', fstype[fs], 'none', str(target)]
        runlog(cmd)
        
        
    def _umount_target_virtfs(self, fs):
        # work around binfmt-support /proc locking
        # found this idea while messing around in live-helper
        target = self.target / fs
        if fs == 'proc':
            binfmt_misc = self.target / 'proc/sys/fs/binfmt_misc'
            status = binfmt_misc / 'status'
            if status.exists():
                self.log.info('Unmounting /proc/sys/fs/binfmt_misc in chroot')
                #cmd = 'umount %s' % binfmt
                cmd = ['umount', str(binfmt_misc)]
                runlog(cmd)
        if fs == 'devpts':
            target = self.target / 'dev' / 'pts'
        #cmd = 'umount %s' % target
        cmd = ['umount', str(target)]
        runlog(cmd)
        
    def _target_proc_mounted(self):
        testfile = self.target / 'proc/version'
        return testfile.isfile()

    def _target_sys_mounted(self):
        testdir = self.target / 'sys/kernel'
        return testdir.isdir()
    
    @requires_bootstrap
    def mount_target_proc(self):
        self._mount_target_virtfs('proc')

    @requires_bootstrap
    def mount_target_sys(self):
        self._mount_target_virtfs('sys')

    def mount_target_devpts(self):
        self._mount_target_virtfs('devpts')
        
    @requires_target_proc_mounted
    def umount_target_proc(self):
        self._umount_target_virtfs('proc')

    @requires_target_sys_mounted
    def umount_target_sys(self):
        self._umount_target_virtfs('sys')

    def umount_target_devpts(self):
        self._umount_target_virtfs('devpts')
        
    @requires_target_proc_mounted
    @requires_target_sys_mounted
    @requires_installer_set
    def install(self):
        self.installer.run_all_processes()
        self._install_finished = True

    def log_all_processes_finished(self):
        self.log.info('-'*30)
        self.log.info('%s processes finished' % self.__class__.__name__)
        self.log.info('-'*30)

    def save_logfile_in_target(self):
        install_log = self.target / 'root/paella/install.log'
        self.mainlog.filename.copyfile(install_log)
class NewInstaller(object):
    def __init__(self, conn, cfg):
        object.__init__(self)
        self.conn = conn
        self.cfg = cfg
        self.machine = MachineHandler(self.conn)
        self.cursor = StatementCursor(self.conn)
        self.target = None
        self.installer = None
        self._mounted = None
        self._bootstrapped = None
        self.debmirror = self.cfg.get('debrepos', 'http_mirror')
                
    def _check_target(self):
        if not self.target:
            raise Error, 'no target specified'

    def _check_installer(self):
        if not self.installer:
            raise Error, 'no installer available'

    def _check_mounted(self):
        self._check_target()
        if not self._mounted:
            raise Error, 'target not mounted'

    def _check_bootstrap(self):
        self._check_mounted()
        if not self._bootstrapped:
            raise Error, 'target not bootstrapped'
        
    def set_machine(self, machine):
        self.machine.set_machine(machine)
        try:
            logfile = os.environ['LOGFILE']
        except KeyError:
            logfile = '/paellalog/paella-install-%s.log' % machine
        os.environ['LOGFILE'] = logfile
        os.environ['PAELLA_MACHINE'] = machine
        
    def make_filesystems(self):
        device = self.machine.array_hack(self.machine.current.machine_type)
        all_fsmounts = self.machine.get_installable_fsmounts()
        env = CurrentEnvironment(self.conn, self.machine.current.machine)
        for row in all_fsmounts:
            pdev = device + str(row.partition)
            if row.mnt_name in env.keys():
                print '%s held' % row.mnt_name
            else:
                print 'making filesystem for', row.mnt_name
                make_filesystem(pdev, row.fstype)

    def set_target(self, target):
        self.target = target

    def _pdev(self, device, partition):
        return device + str(partition)

    def ready_target(self):
        self._check_target()
        makepaths(self.target)
        device = self.machine.array_hack(self.machine.current.machine_type)
        clause = Eq('filesystem', self.machine.current.filesystem)
        clause &= Gt('partition', '0')
        table = 'filesystem_mounts natural join mounts'
        mounts = self.cursor.select(table=table, clause=clause, order='mnt_point')
        if mounts[0].mnt_point != '/':
            raise Error, 'bad set of mounts', mounts
        pdev = self._pdev(device, mounts[0].partition)
        print 'mounting target', pdev, self.target
        runlog('mount %s %s' % (pdev, self.target))
        for mnt in mounts[1:]:
            tpath = os.path.join(self.target, mnt.mnt_point[1:])
            makepaths(tpath)
            pdev = self._pdev(device, mnt.partition)
            runlog('mount %s %s' % (pdev, tpath))
        self._mounted = True
        
    def setup_installer(self):
        profile = self.machine.current.profile
        self.installer = ProfileInstaller(self.conn, self.cfg)
        self.installer.set_profile(profile)
        self.suite = self.installer.suite

    def organize_disks(self):
        return self.machine.check_machine_disks(self.machine.current.machine_type)
                            
    def partition_disks(self):
        disks = self.organize_disks()
        for diskname in disks:
            for device in disks[diskname]:
                self._partition_disk(diskname, device)
            if len(disks[diskname]) > 1:
                ndev = len(disks[diskname])
                print 'doing raid setup on %s' % diskname
                fs = self.machine.current.filesystem
                print fs
                pnums = [r.partition for r in self.machine.get_installable_fsmounts(fs)]
                for p in pnums:
                    mdadm = 'mdadm --create /dev/md%d' % p
                    mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev)
                    devices = ['%s%s' % (d, p) for d in disks[diskname]]
                    command = mdadm + ' '.join(devices)
                    print command
                    yesman = 'bash -c "yes | %s"' % command
                    print yesman
                    os.system(yesman)
                print 'doing raid setup on %s' % str(disks[diskname])
                mdstat = file('/proc/mdstat').read()
                while mdstat.find('resync') > -1:
                    sleep(10)
                    mdstat = file('/proc/mdstat').read()                    
                    
            
    def _partition_disk(self, diskname, device):
        print 'partitioning', diskname, device
        dump = self.machine.make_partition_dump(diskname, device)
        i, o = os.popen2('sfdisk %s' % device)
        i.write(dump)
        i.close()
            
    def bootstrap_target(self):
        self._check_mounted()
        self._check_installer()
        runlog(debootstrap(self.suite, self.target, self.debmirror))
        self._bootstrapped = True
        
    def ready_base_for_install(self):
        self._check_bootstrap()
        self._check_installer()
        fstab = self.machine.make_fstab()
        ready_base_for_install(self.target, self.cfg, self.suite, fstab)
        
    def install_to_target(self):
        os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
        self._check_target()
        self._check_installer()
        self.installer.set_target(self.target)
        self.installer.process()        

    def post_install(self):
        print 'post_install'
        modules = self.machine.get_modules()
        print 'installing modules', modules
        setup_modules(self.target, modules)
        print 'modules installed'
        kernel = self.machine.current.kernel
        print 'installing kernel', kernel
        install_kernel(kernel, self.target)
        print 'kernel installed'
        
    def install(self, machine, target):
        self.set_machine(machine)
        self.partition_disks()
        self.make_filesystems()
        self.setup_installer()
        self.set_target(target)
        self.ready_target()
        self.bootstrap_target()
        self.ready_base_for_install()
        self.install_to_target()
        self.post_install()
Exemple #22
0
 def set_profile(self, profile):
     self.installer = ProfileInstaller(self)
     self.installer.mtypedata.update(self.mtypedata)
     self.installer.set_profile(profile)
     self.set_suite(self.installer.suite)
Exemple #23
0
 def set_profile(self, profile):
     self.installer = ProfileInstaller(self)
     self.installer.mtypedata.update(self.mtypedata)
     self.installer.set_profile(profile)
     self.set_suite(self.installer.suite)
class MachineInstaller(BaseChrootInstaller):
    def __init__(self, conn):
        BaseChrootInstaller.__init__(self, conn)
        self.machine = MachineHandler(self.conn)
        self.processes = DEFAULT_PROCESSES
        self._process_map = {
            'setup_disks' : self.setup_disks,
            'mount_target' : self.mount_target,
            'bootstrap' : self.bootstrap_target,
            'make_device_entries' : self.make_device_entries,
            'apt_sources_installer' : self.setup_apt_sources_installer,
            'ready_base' : self.ready_base_for_install,
            'mount_target_proc' : self.mount_target_proc,
            'install' : self.install_to_target,
            'install_fstab' : self.install_fstab,
            'install_modules' : self.install_modules,
            'install_kernel' : self.install_kernel,
            'apt_sources_final' : self.setup_apt_sources_final,
            'umount_target_proc' : self.umount_target_proc
            }
        self.helper = None
        
    def process(self):
        mach = self.machine.current.machine
        self.log.info('Starting machine install process for %s' % mach)
        for proc in self.processes:
            self.log.info('processing %s for machine %s' % (proc, mach))
            self.run_process(proc)
            self.log.info('processed %s for machine %s' % (proc, mach))
        self.log.info('Ending machine install process for %s' % mach)
        
    def _make_script(self, name):
        script = self.machine.get_script(name)
        if script is not None:
            return make_script(name, script, '/')
        else:
            return None
        
    def run_process(self, proc):
        info = self.log.info
        self.start_process(proc)
        script = self._make_script(proc)
        mtype = self.machine.current.machine_type
        if script is None:
            info('No script for process %s on machine type %s' % (proc, mtype))
            if proc in self._process_map:
                info('Running default process %s' % proc)
                self._process_map[proc]()
            else:
                info('Nothing to do for process %s' % proc)
        else:
            self.log.info('%s script exists for %s' % (proc, mtype))
            self.run_process_script(proc, script)
        self.finish_process(proc)

    def start_process(self, proc):
        self._check_target()
        if proc == 'bootstrap':
            self._check_target_exists()
            
    def finish_process(self, proc):
        if proc == 'mount_target':
            self._mounted = True
            self.log.info('Target should be mounted now.')
        elif proc == 'bootstrap':
            self.log.info('Target should be bootstrapped now.')
            self._bootstrapped = True
    
    def _runscript(self, script, name, info):
        self.log.info(info['start'])
        runvalue = self.run(name, script, chroot=False)
        os.remove(script)
        self.log.info(info['done'])
        return runvalue
    
    def run_process_script(self, proc, script):
        info = scriptinfo(proc)
        if self._runscript(script, proc, info):
            raise InstallError, 'Error running script %s' % proc
        

    def _check_mounted(self):
        self._check_target_exists()
        if not self._mounted:
            raise InstallError, 'target not mounted'

    def _check_bootstrap(self):
        self._check_mounted()
        BaseChrootInstaller._check_bootstrap(self)
        
    def set_machine(self, machine):
        self.machine.set_machine(machine)
        try:
            logfile = os.environ['LOGFILE']
        except KeyError:
            logfile = '/paellalog/paella-install-%s.log' % machine
        os.environ['PAELLA_LOGFILE'] = logfile
        # this needs to be removed sometime
        os.environ['LOGFILE'] = logfile
        os.environ['PAELLA_MACHINE'] = machine
        disklogpath = join(dirname(logfile), 'disklog-%s' % machine)
        if not os.path.isdir(disklogpath):
            makepaths(disklogpath)
        self.disklogpath = disklogpath
        self.curenv = CurrentEnvironment(self.conn, self.machine.current.machine)
        self.set_logfile(logfile)
        self.log.info('Machine Installer set machine to %s' % machine)
        self.mtypedata = self.machine.mtype.get_machine_type_data()
        
    def install(self, machine, target):
        self.set_machine(machine)
        self.setup_installer()
        self.set_target(target)
        makepaths(target)
        self.log.info('Installer set to install %s to %s' % (machine, target))
        self.helper = MachineInstallerHelper(self)
        self.helper.curenv = self.curenv
        self.process()
        
    def setup_installer(self):
        machine = self.machine.current.machine
        profile = self.machine.current.profile
        self.log.info('Setting up profile installer for %s' % machine)
        self.installer = ProfileInstaller(self.conn)
        self.installer.log = self.log
        self.installer.mtypedata = self.mtypedata
        self.installer.set_profile(profile)
        self.suite = self.installer.suite
        self._installer_ready = True
        self.log.info('Profile installer ready for %s' % machine)
        
    
    def setup_disks(self):
        "this is a default process"
        self.helper.setup_disks()

    def mount_target(self):
        "this is a default process"
        self._check_target()
        makepaths(self.target)
        device = self.machine.array_hack()
        #mounts = self.machine.get_ordered_fsmounts()
        mounts = self.machine.get_installable_fsmounts()
        mount_target(self.target, mounts, device)
        self._mounted = True
        
    def bootstrap_target(self):
        "this is a default process"
        self.helper.bootstrap_target()

    def make_device_entries(self):
        "this is a default process"
        if self.defenv.is_it_true('installer', 'use_devices_tarball'):
            runlog('echo extracting devices tarball')
            self._extract_devices_tarball()
        else:
            runlog('echo using MAKEDEV to make generic devices')
            self.make_generic_devices()
        self.make_disk_devices()
        
    def setup_apt_sources_installer(self):
        "this is a default process"
        make_sources_list(self.defenv, self.target, self.suite)

    def ready_base_for_install(self):
        "this is a default process"
        set_root_passwd(self.target, myline)
        make_interfaces_simple(self.target)
        devices = self.helper.get_raid_devices()
        if devices:
            create_mdadm_conf(self.target, devices)

    def mount_target_proc(self):
        "this is a default process"
        echo('mounting target /proc')
        mount_target_proc(self.target)
        
    def install_to_target(self):
        "this is a default process"
        os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
        self._check_target()
        self._check_installer()
        self.installer.set_target(self.target)
        self.installer.process()        

    def install_modules(self):
        "this is a default process"
        modules = self.machine.get_modules()
        setup_modules(self.target, modules)

    def install_kernel(self):
        "this is a default process"
        kernel = self.machine.current.kernel
        echo('installing kernel %s' % kernel)
        install_kernel(kernel, self.target)
        
    def setup_apt_sources_final(self):
        "this is a default process"
        make_official_sources_list(self.defenv, self.target, self.suite)

    def install_fstab(self):
        "this is a default process"
        fstab = self.machine.make_fstab()
        make_fstab(fstab, self.target)
        
    def umount_target_proc(self):
        "this is a default process"
        echo('unmounting target /proc')
        mount_target_proc(self.target, umount=True)

        
    def _extract_devices_tarball(self):
        dtball = self.defenv.get('installer', 'devices_tarball')
        devpath = join(self.target, 'dev')
        runvalue = extract_tarball(devpath, dtball)
        if runvalue:
            raise Error, 'problem extracting devices tarball'

    def make_generic_devices(self):
        makedev(self.target, ['generic'])

    def make_disk_devices(self):
        devices = map(basename, self.machine.get_disk_devices())
        makedev(self.target, devices)
class NewInstaller(object):
    def __init__(self, conn, cfg):
        object.__init__(self)
        self.conn = conn
        self.cfg = cfg
        self.defenv = DefaultEnvironment(self.conn)
        self.machine = MachineHandler(self.conn)
        self.cursor = StatementCursor(self.conn)
        self.target = None
        self.installer = None
        self._mounted = None
        self._bootstrapped = None
        self.debmirror = self.cfg.get('debrepos', 'http_mirror')
        self._raid_setup = False
        self._raid_drives = {}
        self._enable_bad_hacks = False
        if self.cfg.is_it_true('installer', 'enable_bad_hacks'):
            self._enable_bad_hacks = True

    def set_logfile(self, logfile):
        env = os.environ
        if logfile is None:
            if env.has_key('PAELLA_LOGFILE'):
                self.logfile = env['PAELLA_LOGFILE']
            elif env.has_key('LOGFILE'):
                self.logfile = env['LOGFILE']
            elif self.defenv.has_option('installer', 'default_logfile'):
                self.logfile = self.defenv.get('installer', 'default_logfile')
            else:
                raise InstallSetupError, 'There is no log file defined, giving up.'
        else:
            self.logfile = logfile
        logdir = os.path.dirname(self.logfile)
        if logdir:
            makepaths(os.path.dirname(self.logfile))
        format = '%(name)s - %(asctime)s - %(levelname)s: %(message)s'
        self.log = Log('paella-installer', self.logfile, format)

    def _check_target(self):
        if not self.target:
            raise Error, 'no target specified'

    def _check_installer(self):
        if not self.installer:
            raise Error, 'no installer available'

    def _check_mounted(self):
        self._check_target()
        if not self._mounted:
            raise InstallError, 'target not mounted'

    def _check_bootstrap(self):
        self._check_mounted()
        if not self._bootstrapped:
            raise Error, 'target not bootstrapped'

    def set_machine(self, machine):
        self.machine.set_machine(machine)
        try:
            logfile = os.environ['LOGFILE']
        except KeyError:
            logfile = '/paellalog/paella-install-%s.log' % machine
        os.environ['LOGFILE'] = logfile
        os.environ['PAELLA_MACHINE'] = machine
        disklogpath = join(dirname(logfile), 'disklog')
        if not os.path.isdir(disklogpath):
            makepaths(disklogpath)
        self.disklogpath = disklogpath
        self.curenv = CurrentEnvironment(self.conn,
                                         self.machine.current.machine)
        self.set_logfile(logfile)

    def check_if_mounted(self, device):
        mounts = file('/proc/mounts')
        for line in file:
            if line.startswith(device):
                return True
        return False

    def unmount_device(self, device):
        mounted = os.system('umount %s' % device)

    def make_filesystems(self):
        device = self.machine.array_hack(self.machine.current.machine_type)
        mddev = False
        if device == '/dev/md':
            mdnum = 0
            mddev = True
        all_fsmounts = self.machine.get_installable_fsmounts()
        env = CurrentEnvironment(self.conn, self.machine.current.machine)
        for row in all_fsmounts:
            if mddev:
                pdev = '/dev/md%d' % mdnum
                mdnum += 1
            else:
                pdev = device + str(row.partition)
            if row.mnt_name in env.keys():
                print '%s held' % row.mnt_name
            elif row.fstype == 'swap':
                runlog('echo making swap on %s' % pdev)
                runlog('mkswap %s' % pdev)
            else:
                print 'making filesystem for', row.mnt_name
                make_filesystem(pdev, row.fstype)

    def set_target(self, target):
        self.target = target

    def _pdev(self, device, partition):
        return device + str(partition)

    def _mount_target_proc(self):
        self._check_bootstrap()
        tproc = join(self.target, 'proc')
        cmd = 'mount --bind /proc %s' % tproc
        runvalue = runlog(cmd)
        if runvalue:
            raise InstallError, 'problem mounting target /proc at %s' % tproc
        else:
            self._proc_mounted = True

    def _umount_target_proc(self):
        tproc = join(self.target, 'proc')
        cmd = 'umount %s' % tproc
        runvalue = runlog(cmd)
        if runvalue:
            raise InstallError, 'problem unmounting target /proc at %s' % tproc
        else:
            self._proc_mounted = False

    def ready_target(self):
        self._check_target()
        makepaths(self.target)
        device = self.machine.array_hack(self.machine.current.machine_type)
        clause = Eq('filesystem', self.machine.current.filesystem)
        clause &= Gt('partition', '0')
        table = 'filesystem_mounts natural join mounts'
        mounts = self.cursor.select(table=table,
                                    clause=clause,
                                    order='mnt_point')
        if mounts[0].mnt_point != '/':
            raise Error, 'bad set of mounts', mounts
        mddev = False
        mdnum = 0
        if device == '/dev/md':
            mddev = True
            pdev = '/dev/md0'
            mdnum += 1
        else:
            pdev = self._pdev(device, mounts[0].partition)
        runlog('echo mounting target %s to %s ' % (pdev, self.target))
        clause &= Neq('mnt_point', '/')
        mounts = self.cursor.select(table=table, clause=clause, order='ord')
        mountable = [mount for mount in mounts if mount.fstype != 'swap']
        runlog('mount %s %s' % (pdev, self.target))
        for mnt in mountable:
            tpath = os.path.join(self.target, mnt.mnt_point[1:])
            makepaths(tpath)
            if mddev:
                pdev = '/dev/md%d' % mdnum
            else:
                pdev = self._pdev(device, mnt.partition)
            mdnum += 1
            runlog('mount %s %s' % (pdev, tpath))
        self._mounted = True

    def setup_installer(self):
        profile = self.machine.current.profile
        self.installer = ProfileInstaller(self.conn)
        self.installer.log = self.log
        self.installer.set_profile(profile)
        self.suite = self.installer.suite

    def organize_disks(self):
        return self.machine.check_machine_disks(
            self.machine.current.machine_type)

    def _setup_disks(self, diskname, disks=None):
        if disks is None:
            disks = self.organize_disks()
        devices = disks[diskname]

    def setup_disks(self):
        disks = self.organize_disks()
        disknames = disks.keys()
        if not len(disknames):
            self._setup_disk_fai('default', '/dev/hda')
        else:
            if len(disknames) > 1:
                #this isn't really handled yet
                self.partition_disks()
                self.make_filesystems()
            else:
                devices = disks[disknames[0]]
                if len(devices) > 1:
                    #this is a raid setup
                    self.partition_disks()
                    self.make_filesystems()
                elif len(devices) == 1:
                    self._setup_disk_fai(self.machine.current.filesystem,
                                         devices[0])
                else:
                    self._setup_disk_fai('default', '/dev/hda')

    def _setup_disk_fai(self, filesystem, device):
        disk_config = self.machine.make_disk_config_info(device)
        fileid, disk_config_path = tempfile.mkstemp('paella', 'diskinfo')
        disk_config_file = file(disk_config_path, 'w')
        disk_config_file.write(disk_config)
        disk_config_file.close()
        script = '/usr/lib/paella/scripts/setup_harddisks_fai'
        options = '-X -f %s' % disk_config_path
        env = 'env LOGDIR=%s diskvar=%s' % (self.disklogpath,
                                            join(self.disklogpath, 'diskvar'))
        command = '%s %s %s' % (env, script, options)
        runlog(command)

    def _setup_raid_drives(self, diskname, devices):
        self._raid_setup = True
        self._raid_drives[diskname] = devices
        for device in devices:
            self._partition_disk(diskname, device)
        ndev = len(devices)
        print 'doing raid setup on %s' % diskname
        fs = self.machine.current.filesystem
        print fs
        pnums = [
            r.partition for r in self.machine.get_installable_fsmounts(fs)
        ]
        mdnum = 0
        for p in pnums:
            mdadm = 'mdadm --create /dev/md%d' % mdnum
            mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev)
            devices = ['%s%s' % (d, p) for d in devices]
            command = mdadm + ' '.join(devices)
            print command
            yesman = 'bash -c "yes | %s"' % command
            print yesman
            os.system(yesman)
            mdnum += 1
        print 'doing raid setup on %s' % str(devices)
        mdstat = file('/proc/mdstat').read()
        while mdstat.find('resync') > -1:
            sleep(10)
            mdstat = file('/proc/mdstat').read()

    def partition_disks(self):
        disks = self.organize_disks()
        for diskname in disks:
            for device in disks[diskname]:
                self._partition_disk(diskname, device)
            if len(disks[diskname]) > 1:
                self._raid_setup = True
                self._raid_drives[diskname] = disks[diskname]
                ndev = len(disks[diskname])
                print 'doing raid setup on %s' % diskname
                fs = self.machine.current.filesystem
                print fs
                pnums = [
                    r.partition
                    for r in self.machine.get_installable_fsmounts(fs)
                ]
                mdnum = 0
                for p in pnums:
                    mdadm = 'mdadm --create /dev/md%d' % mdnum
                    mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev)
                    devices = ['%s%s' % (d, p) for d in disks[diskname]]
                    command = mdadm + ' '.join(devices)
                    print command
                    yesman = 'bash -c "yes | %s"' % command
                    print yesman
                    os.system(yesman)
                    mdnum += 1
                print 'doing raid setup on %s' % str(disks[diskname])
                mdstat = file('/proc/mdstat').read()
                while mdstat.find('resync') > -1:
                    sleep(10)
                    mdstat = file('/proc/mdstat').read()

    def _partition_disk(self, diskname, device):
        print 'partitioning', diskname, device
        dump = self.machine.make_partition_dump(diskname, device)
        i, o = os.popen2('sfdisk %s' % device)
        i.write(dump)
        i.close()

    def extract_basebootstrap(self):
        self._check_mounted()
        self._check_installer()
        runlog('echo extracting premade base tarball')
        suite_path = self.cfg.get('installer', 'suite_storage')
        basefile = join(suite_path, '%s.tar' % self.suite)
        runvalue = runlog('tar -C %s -xf %s' % (self.target, basefile))
        if runvalue:
            raise Error, 'problems extracting %s' % basefile
        self._bootstrapped = True

    def bootstrap_target(self):
        self._check_mounted()
        self._check_installer()
        runlog(debootstrap(self.suite, self.target, self.debmirror))
        self._bootstrapped = True

    def _make_generic_devices(self, devices):
        here = os.getcwd()
        os.chdir(join(self.target, 'dev'))
        for dev in devices:
            runlog('echo making device %s with MAKEDEV' % dev)
            runlog('./MAKEDEV %s' % dev)
        os.chdir(here)

    def _extract_devices_tarball(self):
        dtball = self.cfg.get('installer', 'devices_tarball')
        devpath = join(self.target, 'dev')
        cmd = 'tar -C %s -xf %s' % (devpath, dtball)
        runvalue = runlog(cmd)
        if runvalue:
            raise Error, 'problem extracting devices tarball'

    def make_disk_devices(self):
        devices = map(basename, self.machine.get_disk_devices())
        self._make_generic_devices(devices)

    def make_tty_devices(self):
        self._make_generic_devices(['console'])

    def make_input_devices(self):
        self._make_generic_devices(['input'])

    def make_generic_devices(self):
        #devices = ['std', 'console', 'pty', 'tap', 'sg', 'input', 'audio']
        self._make_generic_devices(['generic'])

    def ready_base_for_install(self):
        self._check_bootstrap()
        self._check_installer()
        fstab = self.machine.make_fstab()
        ready_base_for_install(self.target, self.cfg, self.suite, fstab)
        if self.cfg.is_it_true('installer', 'use_devices_tarball'):
            runlog('echo extracting devices tarball')
            self._extract_devices_tarball()
        else:
            runlog('echo using MAKEDEV to make devices')
            self.make_generic_devices()
        self.make_disk_devices()
        if self._raid_setup:
            mdpath = join(self.target, 'etc/mdadm')
            makepaths(mdpath)
            mdconfname = join(mdpath, 'mdadm.conf')
            mdconf = file(mdconfname, 'w')
            for diskname in self._raid_drives:
                devices = ['%s*' % d for d in self._raid_drives[diskname]]
                line = 'DEVICE %s' % ' '.join(devices)
                mdconf.write(line + '\n')
            mdconf.close()
            mdconf = file(mdconfname, 'a')
            arrdata = commands.getoutput('mdadm -E --config=%s -s' %
                                         mdconfname)
            mdconf.write(arrdata + '\n')
            mdconf.write('\n')
            mdconf.close()
        self._mount_target_proc()

    def install_to_target(self):
        os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
        self._check_target()
        self._check_installer()
        self.installer.set_target(self.target)
        self.installer.process()

    def post_install(self):
        print 'post_install'
        modules = self.machine.get_modules()
        print 'installing modules', modules
        setup_modules(self.target, modules)
        print 'modules installed'
        kernel = self.machine.current.kernel
        print 'installing kernel', kernel
        install_kernel(kernel, self.target)
        print 'kernel installed'

    def install(self, machine, target):
        self.set_machine(machine)
        if self._enable_bad_hacks:
            self.setup_disks()
        else:
            self.partition_disks()
            self.make_filesystems()
        self.setup_installer()
        self.set_target(target)
        self.ready_target()
        if self.cfg.is_it_true('installer', 'bootstrap_target'):
            self.bootstrap_target()
        else:
            self.extract_basebootstrap()
        self.ready_base_for_install()
        self.install_to_target()
        self.post_install()
class NewInstaller(object):
    def __init__(self, conn, cfg):
        object.__init__(self)
        self.conn = conn
        self.cfg = cfg
        self.machine = MachineHandler(self.conn)
        self.cursor = StatementCursor(self.conn)
        self.target = None
        self.installer = None
        self._mounted = None
        self._bootstrapped = None
        self.debmirror = self.cfg.get("debrepos", "http_mirror")
        self._raid_setup = False
        self._raid_drives = {}

    def _check_target(self):
        if not self.target:
            raise Error, "no target specified"

    def _check_installer(self):
        if not self.installer:
            raise Error, "no installer available"

    def _check_mounted(self):
        self._check_target()
        if not self._mounted:
            raise Error, "target not mounted"

    def _check_bootstrap(self):
        self._check_mounted()
        if not self._bootstrapped:
            raise Error, "target not bootstrapped"

    def set_machine(self, machine):
        self.machine.set_machine(machine)
        try:
            logfile = os.environ["LOGFILE"]
        except KeyError:
            logfile = "/paellalog/paella-install-%s.log" % machine
        os.environ["LOGFILE"] = logfile
        os.environ["PAELLA_MACHINE"] = machine

    def make_filesystems(self):
        device = self.machine.array_hack(self.machine.current.machine_type)
        mddev = False
        if device == "/dev/md":
            mdnum = 0
            mddev = True
        all_fsmounts = self.machine.get_installable_fsmounts()
        env = CurrentEnvironment(self.conn, self.machine.current.machine)
        for row in all_fsmounts:
            if mddev:
                pdev = "/dev/md%d" % mdnum
                mdnum += 1
            else:
                pdev = device + str(row.partition)
            if row.mnt_name in env.keys():
                print "%s held" % row.mnt_name
            else:
                print "making filesystem for", row.mnt_name
                make_filesystem(pdev, row.fstype)

    def set_target(self, target):
        self.target = target

    def _pdev(self, device, partition):
        return device + str(partition)

    def ready_target(self):
        self._check_target()
        makepaths(self.target)
        device = self.machine.array_hack(self.machine.current.machine_type)
        clause = Eq("filesystem", self.machine.current.filesystem)
        clause &= Gt("partition", "0")
        table = "filesystem_mounts natural join mounts"
        mounts = self.cursor.select(table=table, clause=clause, order="mnt_point")
        if mounts[0].mnt_point != "/":
            raise Error, "bad set of mounts", mounts
        mddev = False
        mdnum = 0
        if device == "/dev/md":
            mddev = True
            pdev = "/dev/md0"
            mdnum += 1
        else:
            pdev = self._pdev(device, mounts[0].partition)
        print "mounting target", pdev, self.target
        clause &= Neq("mnt_point", "/")
        mounts = self.cursor.select(table=table, clause=clause, order="ord")
        runlog("mount %s %s" % (pdev, self.target))
        for mnt in mounts:
            tpath = os.path.join(self.target, mnt.mnt_point[1:])
            makepaths(tpath)
            if mddev:
                pdev = "/dev/md%d" % mdnum
            else:
                pdev = self._pdev(device, mnt.partition)
            mdnum += 1
            runlog("mount %s %s" % (pdev, tpath))
        self._mounted = True

    def setup_installer(self):
        profile = self.machine.current.profile
        self.installer = ProfileInstaller(self.conn, self.cfg)
        self.installer.set_profile(profile)
        self.suite = self.installer.suite

    def organize_disks(self):
        return self.machine.check_machine_disks(self.machine.current.machine_type)

    def partition_disks(self):
        disks = self.organize_disks()
        for diskname in disks:
            for device in disks[diskname]:
                self._partition_disk(diskname, device)
            if len(disks[diskname]) > 1:
                self._raid_setup = True
                self._raid_drives[diskname] = disks[diskname]
                ndev = len(disks[diskname])
                print "doing raid setup on %s" % diskname
                fs = self.machine.current.filesystem
                print fs
                pnums = [r.partition for r in self.machine.get_installable_fsmounts(fs)]
                mdnum = 0
                for p in pnums:
                    mdadm = "mdadm --create /dev/md%d" % mdnum
                    mdadm = "%s --force -l1 -n%d " % (mdadm, ndev)
                    devices = ["%s%s" % (d, p) for d in disks[diskname]]
                    command = mdadm + " ".join(devices)
                    print command
                    yesman = 'bash -c "yes | %s"' % command
                    print yesman
                    os.system(yesman)
                    mdnum += 1
                print "doing raid setup on %s" % str(disks[diskname])
                mdstat = file("/proc/mdstat").read()
                while mdstat.find("resync") > -1:
                    sleep(10)
                    mdstat = file("/proc/mdstat").read()

    def _partition_disk(self, diskname, device):
        print "partitioning", diskname, device
        dump = self.machine.make_partition_dump(diskname, device)
        i, o = os.popen2("sfdisk %s" % device)
        i.write(dump)
        i.close()

    def bootstrap_target(self):
        self._check_mounted()
        self._check_installer()
        runlog(debootstrap(self.suite, self.target, self.debmirror))
        self._bootstrapped = True

    def ready_base_for_install(self):
        self._check_bootstrap()
        self._check_installer()
        fstab = self.machine.make_fstab()
        ready_base_for_install(self.target, self.cfg, self.suite, fstab)
        if self._raid_setup:
            mdpath = join(self.target, "etc/mdadm")
            makepaths(mdpath)
            mdconf = file(join(mdpath, "mdadm.conf"), "w")
            for diskname in self._raid_drives:
                devices = ["%s*" % d for d in self._raid_drives[diskname]]
                line = "DEVICE %s" % " ".join(devices)
                mdconf.write(line + "\n")
            arrdata = commands.getoutput("mdadm -E -s")
            mdconf.write(arrdata + "\n")
            mdconf.write("\n")
            mdconf.close()

    def install_to_target(self):
        os.environ["DEBIAN_FRONTEND"] = "noninteractive"
        self._check_target()
        self._check_installer()
        self.installer.set_target(self.target)
        self.installer.process()

    def post_install(self):
        print "post_install"
        modules = self.machine.get_modules()
        print "installing modules", modules
        setup_modules(self.target, modules)
        print "modules installed"
        kernel = self.machine.current.kernel
        print "installing kernel", kernel
        install_kernel(kernel, self.target)
        print "kernel installed"

    def install(self, machine, target):
        self.set_machine(machine)
        self.partition_disks()
        self.make_filesystems()
        self.setup_installer()
        self.set_target(target)
        self.ready_target()
        self.bootstrap_target()
        self.ready_base_for_install()
        self.install_to_target()
        self.post_install()
class NewInstaller(object):
    def __init__(self, conn, cfg):
        object.__init__(self)
        self.conn = conn
        self.cfg = cfg
        self.machine = MachineHandler(self.conn)
        self.cursor = StatementCursor(self.conn)
        self.target = None
        self.installer = None
        self._mounted = None
        self._bootstrapped = None
        self.debmirror = self.cfg.get('debrepos', 'http_mirror')
        self._raid_setup = False
        self._raid_drives = {}
                
    def _check_target(self):
        if not self.target:
            raise Error, 'no target specified'

    def _check_installer(self):
        if not self.installer:
            raise Error, 'no installer available'

    def _check_mounted(self):
        self._check_target()
        if not self._mounted:
            raise Error, 'target not mounted'

    def _check_bootstrap(self):
        self._check_mounted()
        if not self._bootstrapped:
            raise Error, 'target not bootstrapped'
        
    def set_machine(self, machine):
        self.machine.set_machine(machine)
        try:
            logfile = os.environ['LOGFILE']
        except KeyError:
            logfile = '/paellalog/paella-install-%s.log' % machine
        os.environ['LOGFILE'] = logfile
        os.environ['PAELLA_MACHINE'] = machine
        
    def make_filesystems(self):
        device = self.machine.array_hack(self.machine.current.machine_type)
        mddev = False
        if device == '/dev/md':
            mdnum = 0
            mddev = True
        all_fsmounts = self.machine.get_installable_fsmounts()
        env = CurrentEnvironment(self.conn, self.machine.current.machine)
        for row in all_fsmounts:
            if mddev:
                pdev = '/dev/md%d' % mdnum
                mdnum += 1
            else:
                pdev = device + str(row.partition)
            if row.mnt_name in env.keys():
                print '%s held' % row.mnt_name
            else:
                print 'making filesystem for', row.mnt_name
                make_filesystem(pdev, row.fstype)

    def set_target(self, target):
        self.target = target

    def _pdev(self, device, partition):
        return device + str(partition)

    def ready_target(self):
        self._check_target()
        makepaths(self.target)
        device = self.machine.array_hack(self.machine.current.machine_type)
        clause = Eq('filesystem', self.machine.current.filesystem)
        clause &= Gt('partition', '0')
        table = 'filesystem_mounts natural join mounts'
        mounts = self.cursor.select(table=table, clause=clause, order='mnt_point')
        if mounts[0].mnt_point != '/':
            raise Error, 'bad set of mounts', mounts
        mddev = False
        mdnum = 0
        if device == '/dev/md':
            mddev = True
            pdev = '/dev/md0'
            mdnum += 1
        else:
            pdev = self._pdev(device, mounts[0].partition)
        print 'mounting target', pdev, self.target
        clause &= Neq('mnt_point', '/')
        mounts = self.cursor.select(table=table, clause=clause, order='ord')
        runlog('mount %s %s' % (pdev, self.target))
        for mnt in mounts:
            tpath = os.path.join(self.target, mnt.mnt_point[1:])
            makepaths(tpath)
            if mddev:
                pdev = '/dev/md%d' % mdnum
            else:
                pdev = self._pdev(device, mnt.partition)
            mdnum += 1
            runlog('mount %s %s' % (pdev, tpath))
        self._mounted = True
        
    def setup_installer(self):
        profile = self.machine.current.profile
        self.installer = ProfileInstaller(self.conn, self.cfg)
        self.installer.set_profile(profile)
        self.suite = self.installer.suite

    def organize_disks(self):
        return self.machine.check_machine_disks(self.machine.current.machine_type)
                            
    def partition_disks(self):
        disks = self.organize_disks()
        for diskname in disks:
            for device in disks[diskname]:
                self._partition_disk(diskname, device)
            if len(disks[diskname]) > 1:
                self._raid_setup = True
                self._raid_drives[diskname] = disks[diskname]
                ndev = len(disks[diskname])
                print 'doing raid setup on %s' % diskname
                fs = self.machine.current.filesystem
                print fs
                pnums = [r.partition for r in self.machine.get_installable_fsmounts(fs)]
                mdnum = 0 
                for p in pnums:
                    mdadm = 'mdadm --create /dev/md%d' % mdnum
                    mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev)
                    devices = ['%s%s' % (d, p) for d in disks[diskname]]
                    command = mdadm + ' '.join(devices)
                    print command
                    yesman = 'bash -c "yes | %s"' % command
                    print yesman
                    os.system(yesman)
                    mdnum += 1
                print 'doing raid setup on %s' % str(disks[diskname])
                mdstat = file('/proc/mdstat').read()
                while mdstat.find('resync') > -1:
                    sleep(10)
                    mdstat = file('/proc/mdstat').read()                    
                    
            
    def _partition_disk(self, diskname, device):
        print 'partitioning', diskname, device
        dump = self.machine.make_partition_dump(diskname, device)
        i, o = os.popen2('sfdisk %s' % device)
        i.write(dump)
        i.close()
            
    def bootstrap_target(self):
        self._check_mounted()
        self._check_installer()
        runlog(debootstrap(self.suite, self.target, self.debmirror))
        self._bootstrapped = True

    def _make_generic_devices(self, devices):
        here = os.getcwd()
        os.chdir(join(self.target, 'dev'))
        for dev in devices:
            runlog('echo making device %s with MAKEDEV' % dev)
            runlog('./MAKEDEV %s' % dev)
        os.chdir(here)

    def make_disk_devices(self):
        devices = map(basename, self.machine.get_disk_devices())
        self._make_generic_devices(devices)

    def make_tty_devices(self):
        self._make_generic_devices(['console'])

    def make_input_devices(self):
        self._make_generic_devices(['input'])

    def make_generic_devices(self):
        #devices = ['std', 'console', 'pty', 'tap', 'sg', 'input', 'audio']
        self._make_generic_devices(['generic'])
        
    def ready_base_for_install(self):
        self._check_bootstrap()
        self._check_installer()
        fstab = self.machine.make_fstab()
        ready_base_for_install(self.target, self.cfg, self.suite, fstab)
        self.make_generic_devices()
        self.make_disk_devices()
        if self._raid_setup:
            mdpath = join(self.target, 'etc/mdadm')
            makepaths(mdpath)
            mdconfname = join(mdpath, 'mdadm.conf')
            mdconf = file(mdconfname, 'w')
            for diskname in self._raid_drives:
                devices = ['%s*' % d for d in self._raid_drives[diskname]]
                line = 'DEVICE %s' % ' '.join(devices)
                mdconf.write(line + '\n')
            mdconf.close()
            mdconf = file(mdconfname, 'a')
            arrdata = commands.getoutput('mdadm -E --config=%s -s' % mdconfname)
            mdconf.write(arrdata + '\n')
            mdconf.write('\n')
            mdconf.close()
            
    def install_to_target(self):
        os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
        self._check_target()
        self._check_installer()
        self.installer.set_target(self.target)
        self.installer.process()        

    def post_install(self):
        print 'post_install'
        modules = self.machine.get_modules()
        print 'installing modules', modules
        setup_modules(self.target, modules)
        print 'modules installed'
        kernel = self.machine.current.kernel
        print 'installing kernel', kernel
        install_kernel(kernel, self.target)
        print 'kernel installed'
        
    def install(self, machine, target):
        self.set_machine(machine)
        self.partition_disks()
        self.make_filesystems()
        self.setup_installer()
        self.set_target(target)
        self.ready_target()
        self.bootstrap_target()
        self.ready_base_for_install()
        self.install_to_target()
        self.post_install()
Exemple #28
0
class ChrootInstaller(BaseChrootInstaller):
    def __init__(self, conn, logfile=None):
        BaseChrootInstaller.__init__(self, conn)
        self.conn = conn
        self.cursor = StatementCursor(self.conn)
        self._mounted = None
        self._installer_ready  = False
        self._base_ready = False
        if logfile is None:
            self.set_logfile(logfile)
        if logfile is False:
            pass
        
    def _check_base_ready(self):
        if not self._base_ready:
            raise InstallError, 'base is not ready for install.'
        
    def set_profile(self, profile):
        self.profile = profile
        
    def ready_target(self):
        self._check_target_exists()
        
    def setup_installer(self):
        self.installer = ProfileInstaller(self.conn)
        self.installer.log = self.log
        self.installer.set_profile(self.profile)
        self.suite = self.installer.suite
        self._installer_ready = True
                        
    def bootstrap_target(self):
        self._bootstrap_target()
        self._check_bootstrap()
        
        
    def ready_base_for_install(self):
        self._check_bootstrap()
        fstab = '#unconfigured for chroot install\n'
        ready_base_for_install(self.target, self.defenv, self.suite, fstab)
        self._mount_target_proc()
        self._check_target_proc()
        cmd = self.command('apt-get', '-y update', chroot=True)
        runvalue = runlog(cmd)
        if runvalue:
            raise InstallError, 'problem updating the apt lists.'
        if os.environ.has_key('FAKE_START_STOP_DAEMON'):
            make_fake_start_stop_daemon(self.target)
        self._base_ready = True
        
    def install_to_target(self):
        self._check_base_ready()
        os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
        self.installer.set_target(self.target)
        self.installer.process()        

    def post_install(self):
        self._umount_target_proc()
        if os.environ.has_key('FAKE_START_STOP_DAEMON'):
            remove_fake_start_stop_daemon(self.target)        
    
    def install(self, profile, target):
        self.set_profile(profile)
        self.setup_installer()
        self.set_target(target)
        self.ready_target()
        self.bootstrap_target()
        self.ready_base_for_install()
        self.install_to_target()
        self.post_install()
Exemple #29
0
class ChrootInstaller(object):
    def __init__(self, conn, cfg):
        object.__init__(self)
        self.conn = conn
        self.cfg = cfg
        self.cursor = StatementCursor(self.conn)
        self.target = None
        self.installer = None
        self._mounted = None
        self._bootstrapped = None
        self.debmirror = self.cfg.get("debrepos", "http_mirror")

    def _check_target(self):
        if not self.target:
            raise Error, "no target specified"

    def _check_installer(self):
        if not self.installer:
            raise Error, "no installer available"

    def _check_bootstrap(self):
        self._check_target()
        if not self._bootstrapped:
            raise Error, "target not bootstrapped"

    def set_target(self, target):
        self.target = target

    def set_profile(self, profile):
        self.profile = profile

    def ready_target(self):
        self._check_target()

    def setup_installer(self):
        self.installer = ProfileInstaller(self.conn, self.cfg)
        self.installer.set_profile(self.profile)
        self.suite = get_suite(self.conn, self.profile)

    def bootstrap_target(self):
        self._check_target()
        self._check_installer()
        runlog(debootstrap(self.suite, self.target, self.debmirror))
        self._bootstrapped = True

    def ready_base_for_install(self):
        self._check_bootstrap()
        self._check_installer()
        fstab = "#unconfigured for chroot install\n"
        ready_base_for_install(self.target, self.cfg, self.suite, fstab)

    def install_to_target(self):
        os.environ["DEBIAN_FRONTEND"] = "noninteractive"
        self._check_target()
        self._check_installer()
        self.installer.set_target(self.target)
        self.installer.process()

    def post_install(self):
        print "post_install"
        kernel = self.machine.current.kernel
        print "installing kernel", kernel
        install_kernel(kernel, self.target)
        print "kernel installed"

    def install(self, profile, target):
        self.set_profile(profile)
        self.setup_installer()
        self.set_target(target)
        self.ready_target()
        self.bootstrap_target()
        self.ready_base_for_install()
        self.install_to_target()
Exemple #30
0
class InstallerTools(object):
    def __init__(self):
        object.__init__(self)
        self.cfg = PaellaConfig()
        self.conn = InstallerConnection()
        self.profile = os.environ['PAELLA_PROFILE']
        self.target = os.environ['PAELLA_TARGET']
        self.machine = None
        self.trait = None
        self.suite = get_suite(self.conn, self.profile)
        self.pr = Profile(self.conn)
        self.pr.set_profile(self.profile)
        self.traitlist = self.pr.make_traitlist()
        self.pe = ProfileEnvironment(self.conn, self.profile)
        self.tp = TraitParent(self.conn, self.suite)
        self.fm = Family(self.conn)
        self.tr = Trait(self.conn, self.suite)
        self.families = list(
            self.fm.get_related_families(self.pr.get_families()))
        self._envv = None
        self.default = DefaultEnvironment(self.conn)
        #self.installer = TraitInstaller(self.conn, self.suite)
        self.installer = ProfileInstaller(self.conn)
        self.installer.set_logfile()
        self.installer.set_profile(self.profile)
        self.installer.set_target(self.target)
        if os.environ.has_key('PAELLA_MACHINE'):
            self.machine = os.environ['PAELLA_MACHINE']
        if os.environ.has_key('PAELLA_TRAIT'):
            self.set_trait(os.environ['PAELLA_TRAIT'])

    def env(self):
        env = RefDict(self.tp.Environment())
        env.update(self.pr.get_family_data())
        env.update(self.pr.get_profile_data())
        return env

    def set_trait(self, trait):
        self.trait = trait
        self.tp.set_trait(trait)
        self.tr.set_trait(trait)
        self.parents = self.tr.parents()
        self._envv = self.env()
        tinstaller = self.installer.installer
        tinstaller.set_trait(trait)
        self.packages = tinstaller.traitpackage.packages()
        self.templates = tinstaller.traittemplate.templates()

    def get(self, key):
        if self._envv is None:
            raise Error, 'need to set trait first'
        return self._envv.dereference(key)

    def install_modules(self, name):
        modules = str2list(self.get(name))
        print 'installing modules', modules, 'to %s/etc/modules' % self.target
        setup_modules(self.target, modules)

    def remove_packages(self, packages=None):
        if packages is None:
            packages = self.packages
        if len(packages):
            if hasattr(packages[0], 'package'):
                packages = [p.package for p in packages]
        package_list = ' '.join(packages)
        command = 'apt-get -y remove %s' % package_list
        self.installer.run('remove', command, proc=True)
Exemple #31
0
 def setup_installer(self):
     self.installer = ProfileInstaller(self.conn, self.cfg)
     self.installer.set_profile(self.profile)
     self.suite = get_suite(self.conn, self.profile)
class NewInstaller(object):
    def __init__(self, conn, cfg):
        object.__init__(self)
        self.conn = conn
        self.cfg = cfg
        self.defenv = DefaultEnvironment(self.conn)
        self.machine = MachineHandler(self.conn)
        self.cursor = StatementCursor(self.conn)
        self.target = None
        self.installer = None
        self._mounted = None
        self._bootstrapped = None
        self.debmirror = self.cfg.get('debrepos', 'http_mirror')
        self._raid_setup = False
        self._raid_drives = {}
        self._enable_bad_hacks = False
        if self.cfg.is_it_true('installer', 'enable_bad_hacks'):
            self._enable_bad_hacks = True
        
    def set_logfile(self, logfile):
        env = os.environ
        if logfile is None:
            if env.has_key('PAELLA_LOGFILE'):
                self.logfile = env['PAELLA_LOGFILE']
            elif env.has_key('LOGFILE'):
                self.logfile = env['LOGFILE']
            elif self.defenv.has_option('installer', 'default_logfile'):
                self.logfile = self.defenv.get('installer', 'default_logfile')
            else:
                raise InstallSetupError, 'There is no log file defined, giving up.'
        else:
            self.logfile = logfile
        logdir = os.path.dirname(self.logfile)
        if logdir:
            makepaths(os.path.dirname(self.logfile))
        format = '%(name)s - %(asctime)s - %(levelname)s: %(message)s'
        self.log = Log('paella-installer', self.logfile, format)
        
    def _check_target(self):
        if not self.target:
            raise Error, 'no target specified'

    def _check_installer(self):
        if not self.installer:
            raise Error, 'no installer available'

    def _check_mounted(self):
        self._check_target()
        if not self._mounted:
            raise InstallError, 'target not mounted'

    def _check_bootstrap(self):
        self._check_mounted()
        if not self._bootstrapped:
            raise Error, 'target not bootstrapped'
        
    def set_machine(self, machine):
        self.machine.set_machine(machine)
        try:
            logfile = os.environ['LOGFILE']
        except KeyError:
            logfile = '/paellalog/paella-install-%s.log' % machine
        os.environ['LOGFILE'] = logfile
        os.environ['PAELLA_MACHINE'] = machine
        disklogpath = join(dirname(logfile), 'disklog')
        if not os.path.isdir(disklogpath):
            makepaths(disklogpath)
        self.disklogpath = disklogpath
        self.curenv = CurrentEnvironment(self.conn, self.machine.current.machine)
        self.set_logfile(logfile)
        
    def check_if_mounted(self, device):
        mounts = file('/proc/mounts')
        for line in file:
            if line.startswith(device):
                return True
        return False

    def unmount_device(self, device):
        mounted = os.system('umount %s' % device)
        
    def make_filesystems(self):
        device = self.machine.array_hack(self.machine.current.machine_type)
        mddev = False
        if device == '/dev/md':
            mdnum = 0
            mddev = True
        all_fsmounts = self.machine.get_installable_fsmounts()
        env = CurrentEnvironment(self.conn, self.machine.current.machine)
        for row in all_fsmounts:
            if mddev:
                pdev = '/dev/md%d' % mdnum
                mdnum += 1
            else:
                pdev = device + str(row.partition)
            if row.mnt_name in env.keys():
                print '%s held' % row.mnt_name
            elif row.fstype == 'swap':
                runlog('echo making swap on %s' % pdev)
                runlog('mkswap %s' % pdev)
            else:
                print 'making filesystem for', row.mnt_name
                make_filesystem(pdev, row.fstype)

    def set_target(self, target):
        self.target = target

    def _pdev(self, device, partition):
        return device + str(partition)

    def _mount_target_proc(self):
        self._check_bootstrap()
        tproc = join(self.target, 'proc')
        cmd = 'mount --bind /proc %s' % tproc
        runvalue = runlog(cmd)
        if runvalue:
            raise InstallError, 'problem mounting target /proc at %s' % tproc
        else:
            self._proc_mounted = True

    def _umount_target_proc(self):
        tproc = join(self.target, 'proc')
        cmd = 'umount %s' % tproc
        runvalue = runlog(cmd)
        if runvalue:
            raise InstallError, 'problem unmounting target /proc at %s' % tproc
        else:
            self._proc_mounted = False
            
    def ready_target(self):
        self._check_target()
        makepaths(self.target)
        device = self.machine.array_hack(self.machine.current.machine_type)
        clause = Eq('filesystem', self.machine.current.filesystem)
        clause &= Gt('partition', '0')
        table = 'filesystem_mounts natural join mounts'
        mounts = self.cursor.select(table=table, clause=clause, order='mnt_point')
        if mounts[0].mnt_point != '/':
            raise Error, 'bad set of mounts', mounts
        mddev = False
        mdnum = 0
        if device == '/dev/md':
            mddev = True
            pdev = '/dev/md0'
            mdnum += 1
        else:
            pdev = self._pdev(device, mounts[0].partition)
        runlog('echo mounting target %s to %s ' % (pdev, self.target))
        clause &= Neq('mnt_point', '/')
        mounts = self.cursor.select(table=table, clause=clause, order='ord')
        mountable = [mount for mount in mounts if mount.fstype != 'swap']
        runlog('mount %s %s' % (pdev, self.target))
        for mnt in mountable:
            tpath = os.path.join(self.target, mnt.mnt_point[1:])
            makepaths(tpath)
            if mddev:
                pdev = '/dev/md%d' % mdnum
            else:
                pdev = self._pdev(device, mnt.partition)
            mdnum += 1
            runlog('mount %s %s' % (pdev, tpath))
        self._mounted = True
        
    def setup_installer(self):
        profile = self.machine.current.profile
        self.installer = ProfileInstaller(self.conn)
        self.installer.log = self.log
        self.installer.set_profile(profile)
        self.suite = self.installer.suite

    def organize_disks(self):
        return self.machine.check_machine_disks(self.machine.current.machine_type)
                            
    def _setup_disks(self, diskname, disks=None):
        if disks is None:
            disks = self.organize_disks()
        devices = disks[diskname]

    def setup_disks(self):
        disks = self.organize_disks()
        disknames = disks.keys()
        if not len(disknames):
            self._setup_disk_fai('default', '/dev/hda')
        else:
            if len(disknames) > 1:
                #this isn't really handled yet
                self.partition_disks()
                self.make_filesystems()
            else:
                devices = disks[disknames[0]]
                if len(devices) > 1:
                    #this is a raid setup
                    self.partition_disks()
                    self.make_filesystems()
                elif len(devices) == 1:
                    self._setup_disk_fai(self.machine.current.filesystem, devices[0])
                else:
                    self._setup_disk_fai('default', '/dev/hda')
    
    def _setup_disk_fai(self, filesystem, device):
        disk_config = self.machine.make_disk_config_info(device)
        fileid, disk_config_path = tempfile.mkstemp('paella', 'diskinfo')
        disk_config_file = file(disk_config_path, 'w')
        disk_config_file.write(disk_config)
        disk_config_file.close()
        script = '/usr/lib/paella/scripts/setup_harddisks_fai'
        options = '-X -f %s' % disk_config_path
        env = 'env LOGDIR=%s diskvar=%s' % (self.disklogpath, join(self.disklogpath, 'diskvar'))
        command = '%s %s %s' % (env, script, options)
        runlog(command)
        
    def _setup_raid_drives(self, diskname, devices):
        self._raid_setup = True
        self._raid_drives[diskname] = devices
        for device in devices:
            self._partition_disk(diskname, device)
        ndev = len(devices)
        print 'doing raid setup on %s' % diskname
        fs = self.machine.current.filesystem
        print fs
        pnums = [r.partition for r in self.machine.get_installable_fsmounts(fs)]
        mdnum = 0 
        for p in pnums:
            mdadm = 'mdadm --create /dev/md%d' % mdnum
            mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev)
            devices = ['%s%s' % (d, p) for d in devices]
            command = mdadm + ' '.join(devices)
            print command
            yesman = 'bash -c "yes | %s"' % command
            print yesman
            os.system(yesman)
            mdnum += 1
        print 'doing raid setup on %s' % str(devices)
        mdstat = file('/proc/mdstat').read()
        while mdstat.find('resync') > -1:
            sleep(10)
            mdstat = file('/proc/mdstat').read()                    
        
    def partition_disks(self):
        disks = self.organize_disks()
        for diskname in disks:
            for device in disks[diskname]:
                self._partition_disk(diskname, device)
            if len(disks[diskname]) > 1:
                self._raid_setup = True
                self._raid_drives[diskname] = disks[diskname]
                ndev = len(disks[diskname])
                print 'doing raid setup on %s' % diskname
                fs = self.machine.current.filesystem
                print fs
                pnums = [r.partition for r in self.machine.get_installable_fsmounts(fs)]
                mdnum = 0 
                for p in pnums:
                    mdadm = 'mdadm --create /dev/md%d' % mdnum
                    mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev)
                    devices = ['%s%s' % (d, p) for d in disks[diskname]]
                    command = mdadm + ' '.join(devices)
                    print command
                    yesman = 'bash -c "yes | %s"' % command
                    print yesman
                    os.system(yesman)
                    mdnum += 1
                print 'doing raid setup on %s' % str(disks[diskname])
                mdstat = file('/proc/mdstat').read()
                while mdstat.find('resync') > -1:
                    sleep(10)
                    mdstat = file('/proc/mdstat').read()                    
                    
            
    def _partition_disk(self, diskname, device):
        print 'partitioning', diskname, device
        dump = self.machine.make_partition_dump(diskname, device)
        i, o = os.popen2('sfdisk %s' % device)
        i.write(dump)
        i.close()
            
    def extract_basebootstrap(self):
        self._check_mounted()
        self._check_installer()
        runlog('echo extracting premade base tarball')
        suite_path = self.cfg.get('installer', 'suite_storage')
        basefile = join(suite_path, '%s.tar' % self.suite)
        runvalue = runlog('tar -C %s -xf %s' % (self.target, basefile))
        if runvalue:
            raise Error, 'problems extracting %s' % basefile
        self._bootstrapped = True

    def bootstrap_target(self):
        self._check_mounted()
        self._check_installer()
        runlog(debootstrap(self.suite, self.target, self.debmirror))
        self._bootstrapped = True

    def _make_generic_devices(self, devices):
        here = os.getcwd()
        os.chdir(join(self.target, 'dev'))
        for dev in devices:
            runlog('echo making device %s with MAKEDEV' % dev)
            runlog('./MAKEDEV %s' % dev)
        os.chdir(here)

    def _extract_devices_tarball(self):
        dtball = self.cfg.get('installer', 'devices_tarball')
        devpath = join(self.target, 'dev')
        cmd = 'tar -C %s -xf %s' % (devpath, dtball)
        runvalue = runlog(cmd)
        if runvalue:
            raise Error, 'problem extracting devices tarball'
        

    def make_disk_devices(self):
        devices = map(basename, self.machine.get_disk_devices())
        self._make_generic_devices(devices)

    def make_tty_devices(self):
        self._make_generic_devices(['console'])

    def make_input_devices(self):
        self._make_generic_devices(['input'])

    def make_generic_devices(self):
        #devices = ['std', 'console', 'pty', 'tap', 'sg', 'input', 'audio']
        self._make_generic_devices(['generic'])
        
    def ready_base_for_install(self):
        self._check_bootstrap()
        self._check_installer()
        fstab = self.machine.make_fstab()
        ready_base_for_install(self.target, self.cfg, self.suite, fstab)
        if self.cfg.is_it_true('installer', 'use_devices_tarball'):
            runlog('echo extracting devices tarball')
            self._extract_devices_tarball()
        else:
            runlog('echo using MAKEDEV to make devices')
            self.make_generic_devices()
        self.make_disk_devices()
        if self._raid_setup:
            mdpath = join(self.target, 'etc/mdadm')
            makepaths(mdpath)
            mdconfname = join(mdpath, 'mdadm.conf')
            mdconf = file(mdconfname, 'w')
            for diskname in self._raid_drives:
                devices = ['%s*' % d for d in self._raid_drives[diskname]]
                line = 'DEVICE %s' % ' '.join(devices)
                mdconf.write(line + '\n')
            mdconf.close()
            mdconf = file(mdconfname, 'a')
            arrdata = commands.getoutput('mdadm -E --config=%s -s' % mdconfname)
            mdconf.write(arrdata + '\n')
            mdconf.write('\n')
            mdconf.close()
        self._mount_target_proc()
        
    def install_to_target(self):
        os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
        self._check_target()
        self._check_installer()
        self.installer.set_target(self.target)
        self.installer.process()        

    def post_install(self):
        print 'post_install'
        modules = self.machine.get_modules()
        print 'installing modules', modules
        setup_modules(self.target, modules)
        print 'modules installed'
        kernel = self.machine.current.kernel
        print 'installing kernel', kernel
        install_kernel(kernel, self.target)
        print 'kernel installed'
        
    def install(self, machine, target):
        self.set_machine(machine)
        if self._enable_bad_hacks:
            self.setup_disks()
        else:
            self.partition_disks()
            self.make_filesystems()
        self.setup_installer()
        self.set_target(target)
        self.ready_target()
        if self.cfg.is_it_true('installer', 'bootstrap_target'):
            self.bootstrap_target()
        else:
            self.extract_basebootstrap()
        self.ready_base_for_install()
        self.install_to_target()
        self.post_install()