Example #1
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.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)
Example #2
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)
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()
Example #4
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()
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()
Example #6
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()
Example #7
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()
Example #8
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 = '/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()
Example #9
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()
Example #10
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')
        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()
Example #11
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()
Example #12
0
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.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()