예제 #1
0
 def backup(self, path):
     if not os.path.isdir(path):
         raise Error, 'arguement needs to be a directory'
     pdb = PaellaDatabase(self.conn, path)
     pdb.backup(path)
     mh = MachineHandler(self.conn)
     mh.export_machine_database(path)
예제 #2
0
class MachineDoc(BaseDocument):
    def __init__(self, app, **atts):
        BaseDocument.__init__(self, app, **atts)
        self.machine = MachineHandler(self.conn)

    def set_machine(self, machine):
        self.machine.set_machine(machine)
        self.clear_body()
        title = SimpleTitleElement('Machine:  %s' % machine, bgcolor='IndianRed',
                                   width='100%')
        self.body.appendChild(title)
        mtable = BaseElement('table')
        for k,v in self.machine.current.items():
            trow = TR()
            trow.appendChild(TxtTD(Bold(k)))
            trow.appendChild(TxtTD(v))
            mtable.appendChild(trow)
        self.body.appendChild(mtable)
        newanchor = Anchor('new.machine.foo', 'new')
        editanchor = Anchor('edit.machine.%s' % machine, 'edit')
        self.body.appendChild(HR())
        self.body.appendChild(editanchor)
        self.body.appendChild(BR())
        self.body.appendChild(newanchor)
        
    def set_clause(self, clause):
        print 'clause---->', clause, type(clause)
        #self.machine.cursor.clause = clause
        self.clear_body()
        title = SimpleTitleElement('Machines', bgcolor='IndianRed', width='100%')
        self.body.appendChild(title)
        for row in self.machine.cursor.select(clause=clause):
            self.body.appendChild(MachineFieldTable(row, bgcolor='MistyRose3'))
            self.body.appendChild(HR())
예제 #3
0
class MachineDoc(BaseDocument):
    def __init__(self, app, **atts):
        BaseDocument.__init__(self, app, **atts)
        self.machine = MachineHandler(self.conn)

    def set_machine(self, machine):
        self.machine.set_machine(machine)
        self.clear_body()
        title = SimpleTitleElement("Machine:  %s" % machine, bgcolor="IndianRed", width="100%")
        self.body.appendChild(title)
        mtable = BaseElement("table")
        for k, v in self.machine.current.items():
            trow = TR()
            trow.appendChild(TxtTD(Bold(k)))
            trow.appendChild(TxtTD(v))
            mtable.appendChild(trow)
        self.body.appendChild(mtable)
        newanchor = Anchor("new.machine.foo", "new")
        editanchor = Anchor("edit.machine.%s" % machine, "edit")
        self.body.appendChild(HR())
        self.body.appendChild(editanchor)
        self.body.appendChild(BR())
        self.body.appendChild(newanchor)

    def set_clause(self, clause):
        print "clause---->", clause, type(clause)
        # self.machine.cursor.clause = clause
        self.clear_body()
        title = SimpleTitleElement("Machines", bgcolor="IndianRed", width="100%")
        self.body.appendChild(title)
        for row in self.machine.cursor.select(clause=clause):
            self.body.appendChild(MachineFieldTable(row, bgcolor="MistyRose3"))
            self.body.appendChild(HR())
예제 #4
0
 def backup(self, path):
     if not os.path.isdir(path):
         raise Error, 'arguement needs to be a directory'
     pdb = PaellaDatabase(self.conn, path)
     pdb.backup(path)
     mh = MachineHandler(self.conn)
     mh.export_machine_database(path)
예제 #5
0
 def __init__(self, conn):
     self.conn = conn
     self.profile = Profile(self.conn)
     self.family = Family(self.conn)
     self.suite = None
     self.trait = None
     self.machine = MachineHandler(self.conn)
예제 #6
0
class ToolkitDatabase(object):
    def __init__(self, conn):
        self.conn = conn
        self.profile = Profile(self.conn)
        self.family = Family(self.conn)
        self.suite = None
        self.trait = None
        self.machine = MachineHandler(self.conn)
        
    def set_profile(self, profile):
        self.profile.set_profile(profile)
        self.suite = self.profile.current.suite
        self.trait = Trait(self.conn, self.suite)
        
    def set_trait(self, trait):
        self.trait.set_trait(trait)

    def set_machine(self, machine):
        self.machine.set_machine(machine)
        profile = self.machine.get_profile()
        self.set_profile(profile)
        if os.environ.has_key('PAELLA_TRAIT'):
            self.set_trait(os.environ['PAELLA_TRAIT'])
        
        
    def env(self):
        env = TemplatedEnvironment()
        if self.trait.current_trait is not None:
            env.update(self.trait._parents.Environment())
        env.update(self.profile.get_family_data())
        env.update(self.profile.get_profile_data())
        if self.machine.current_machine is not None:
            env.update(self.machine.get_machine_data())
        return env
예제 #7
0
 def __init__(self, app, **atts):
     _MachineBaseDocument.__init__(self, app, **atts)
     self.machine = MachineHandler(self.conn)
     self._bgcolor_body = 'Salmon'
     self._bgcolor_section = 'IndianRed'
     self._other_section_font_color = 'DarkViolet'
     self._bgcolor_thead = 'MediumOrchid2'
     self._bgcolor_table = 'MediumOrchid3'
     self.body['bgcolor'] = self._bgcolor_body
예제 #8
0
 def restore(self, path):
     if not os.path.isdir(path):
         raise Error, 'arguement needs to be a directory'
     dbpath = join(path, 'database.xml')
     mdbpath = join(path, 'machine_database.xml')
     pp = PaellaProcessor(self.conn, self.cfg)
     pp.create(dbpath)
     mh = MachineHandler(self.conn)
     #md = mh.parse_xmlfile(mdbpath)
     mh.restore_machine_database(path)
예제 #9
0
 def restore(self, path):
     if not os.path.isdir(path):
         raise Error, 'arguement needs to be a directory'
     dbpath = join(path, 'database.xml')
     mdbpath = join(path, 'machine_database.xml')
     pp = PaellaProcessor(self.conn, self.cfg)
     pp.create(dbpath)
     mh = MachineHandler(self.conn)
     md = mh.parse_xmlfile(mdbpath)
     mh.insert_parsed_element(md)    
예제 #10
0
 def import_client(self, client):
     cpath, ppath, fpath, tpath = self._cpaths_(client)
     profiles, families, traits = self._client_schema(client)
     mdbpath = join(cpath, 'machine_database.xml')
     if families:
         f = Family(self.conn)
         f.import_families(fpath)
     if profiles:
         importer = PaellaImporter(self.conn)
         importer.import_all_profiles(ppath)
     mh = MachineHandler(self.conn)
     md = mh.parse_xmlfile(mdbpath)
     mh.insert_parsed_element(md)    
예제 #11
0
 def import_client(self, client):
     cpath, ppath, fpath, tpath = self._cpaths_(client)
     profiles, families, traits = self._client_schema(client)
     mdbpath = join(cpath, 'machine_database.xml')
     if families:
         f = Family(self.conn)
         f.import_families(fpath)
     if profiles:
         pp = PaellaProcessor(self.conn, self.cfg)
         pp.main_path = cpath
         pp.insert_profiles()
     mh = MachineHandler(self.conn)
     md = mh.parse_xmlfile(mdbpath)
     mh.insert_parsed_element(md)
예제 #12
0
 def import_client(self, client):
     cpath, ppath, fpath, tpath = self._cpaths_(client)
     profiles, families, traits = self._client_schema(client)
     mdbpath = join(cpath, 'machine_database.xml')
     if families:
         f = Family(self.conn)
         f.import_families(fpath)
     if profiles:
         pp = PaellaProcessor(self.conn, self.cfg)
         pp.main_path = cpath
         pp.insert_profiles()
     mh = MachineHandler(self.conn)
     md = mh.parse_xmlfile(mdbpath)
     mh.insert_parsed_element(md)    
예제 #13
0
 def __init__(self, conn):
     ChrootInstaller.__init__(self, conn)
     # the processes are mostly the same as in the
     # ChrootInstaller
     self._processes = list(DEFAULT_PROCESSES)
     pmap = dict(setup_disks=self.setup_disks,
                 mount_target=self.mount_target,
                 install_fstab=self.install_fstab,
                 install_modules=self.install_modules,
                 install_kernel=self.install_kernel
                 )
     self._process_map.update(pmap)
     self.machine = MachineHandler(self.conn)
     self.helper = None
     self._target_mounted = False
     self._disks_setup = False
예제 #14
0
 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 = {}
     self._enable_bad_hacks = False
     if self.cfg.is_it_true('installer', 'enable_bad_hacks'):
         self._enable_bad_hacks = True
예제 #15
0
파일: machine.py 프로젝트: joelsefus/paella
 def __init__(self, app, **atts):
     _MachineBaseDocument.__init__(self, app, **atts)
     self.machine = MachineHandler(self.conn)
     self._bgcolor_body = 'Salmon'
     self._bgcolor_section = 'IndianRed'
     self._other_section_font_color = 'DarkViolet'
     self._bgcolor_thead = 'MediumOrchid2'
     self._bgcolor_table = 'MediumOrchid3'
     self.body['bgcolor'] = self._bgcolor_body
예제 #16
0
 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
예제 #17
0
class MachineDoc(BaseDocument):
    def __init__(self, app, **atts):
        BaseDocument.__init__(self, app, **atts)
        self.machine = MachineHandler(self.conn)

    def set_machine(self, machine):
        self.machine.set_machine(machine)
        self.clear_body()
        title = SimpleTitleElement('Machine:  %s' % machine,
                                   bgcolor='IndianRed',
                                   width='100%')
        self.body.appendChild(title)
        mtable = BaseElement('table')
        for k, v in self.machine.current.items():
            trow = TR()
            trow.appendChild(TxtTD(Bold(k)))
            trow.appendChild(TxtTD(v))
            mtable.appendChild(trow)
        self.body.appendChild(mtable)
        newanchor = Anchor('new.machine.foo', 'new')
        editanchor = Anchor('edit.machine.%s' % machine, 'edit')
        self.body.appendChild(HR())
        self.body.appendChild(editanchor)
        self.body.appendChild(BR())
        self.body.appendChild(newanchor)

    def set_clause(self, clause):
        print 'clause---->', clause, type(clause)
        #self.machine.cursor.clause = clause
        self.clear_body()
        title = SimpleTitleElement('Machines',
                                   bgcolor='IndianRed',
                                   width='100%')
        self.body.appendChild(title)
        for row in self.machine.cursor.select(clause=clause):
            self.body.appendChild(MachineFieldTable(row, bgcolor='MistyRose3'))
            self.body.appendChild(HR())
예제 #18
0
class MachineDoc(BaseDocument):
    def __init__(self, app, **atts):
        BaseDocument.__init__(self, app, **atts)
        self.machine = MachineHandler(self.conn)

    def set_machine(self, machine):
        self.machine.set_machine(machine)
        self.clear_body()
        title = SectionTitle('Machine:  %s' % machine)
        title['bgcolor'] = 'IndianRed'
        title['width'] = '100%'
        self.body.append(title)
        mtable = Table()
        for k, v in self.machine.current.items():
            tablerow = TableRow()
            tablerow.append(TableCell(Bold(k)))
            tablerow.append(TableCell(v))
            mtable.append(tablerow)
        self.body.append(mtable)
        newanchor = Anchor('new', href='new.machine.foo')
        editanchor = Anchor('edit', href='edit.machine.%s' % machine)
        self.body.append(Ruler())
        self.body.append(editanchor)
        self.body.append(Break())
        self.body.append(newanchor)

    def set_clause(self, clause):
        print 'clause---->', clause, type(clause)
        self.clear_body()
        title = SectionTitle('Machines')
        title['bgcolor'] = 'IndianRed'
        title['width'] = '100%'
        self.body.append(title)
        for row in self.machine.cursor.select(clause=clause):
            self.body.append(MachineFieldTable(row, bgcolor='MistyRose3'))
            self.body.append(Ruler())
예제 #19
0
class MachineDoc(BaseDocument):
    def __init__(self, app, **atts):
        BaseDocument.__init__(self, app, **atts)
        self.machine = MachineHandler(self.conn)

    def set_machine(self, machine):
        self.machine.set_machine(machine)
        self.clear_body()
        title = SectionTitle('Machine:  %s' % machine)
        title['bgcolor'] = 'IndianRed'
        title['width'] = '100%'
        self.body.append(title)
        mtable = Table()
        for k,v in self.machine.current.items():
            tablerow = TableRow()
            tablerow.append(TableCell(Bold(k)))
            tablerow.append(TableCell(v))
            mtable.append(tablerow)
        self.body.append(mtable)
        newanchor = Anchor('new', href='new.machine.foo')
        editanchor = Anchor('edit', href='edit.machine.%s' % machine)
        self.body.append(Ruler())
        self.body.append(editanchor)
        self.body.append(Break())
        self.body.append(newanchor)
        
    def set_clause(self, clause):
        print 'clause---->', clause, type(clause)
        self.clear_body()
        title = SectionTitle('Machines')
        title['bgcolor'] = 'IndianRed'
        title['width'] = '100%'
        self.body.append(title)
        for row in self.machine.cursor.select(clause=clause):
            self.body.append(MachineFieldTable(row, bgcolor='MistyRose3'))
            self.body.append(Ruler())
예제 #20
0
 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
예제 #21
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)
예제 #22
0
class MachineInstaller(ChrootInstaller):
    def __init__(self, conn):
        ChrootInstaller.__init__(self, conn)
        # the processes are mostly the same as in the
        # ChrootInstaller
        self._processes = list(DEFAULT_PROCESSES)
        pmap = dict(setup_disks=self.setup_disks,
                    mount_target=self.mount_target,
                    install_fstab=self.install_fstab,
                    install_modules=self.install_modules,
                    install_kernel=self.install_kernel
                    )
        self._process_map.update(pmap)
        self.machine = MachineHandler(self.conn)
        self.helper = None
        self._target_mounted = False
        self._disks_setup = False
        
    @requires_target_set
    def set_machine(self, machine):
        self.machine.set_machine(machine)
        # this needs to be a configuration option
        # in the default environment
        logdir = path('/paellalog')
        if not logdir.isdir():
            logdir.mkdir()
        logfile = logdir / 'paella-install-%s.log' % machine
        os.environ['PAELLA_MACHINE'] = machine
        self.disklogpath = logdir / ('disklog-%s'  % machine)
        if not self.disklogpath.isdir():
            self.disklogpath.mkdir()
        self.set_logfile(logfile)
        self.log.info('machine set to %s' % machine)
        # we need to set mtypedata before setting the profile
        # so that the mtypedata is passed to the profile and trait installers
        self.mtypedata = self.machine.mtype.get_machine_type_data()
        profile = self.machine.current.profile
        self.set_profile(profile)
        self.curenv = CurrentEnvironment(self.conn, machine)
        self.helper = MachineInstallerHelper(self)
        self.helper.curenv = self.curenv

    @requires_machine_set
    def make_script(self, procname):
        script = self.machine.get_script(procname)
        if script is not None:
            return make_script(procname, script, '/')
        else:
            return None
        
    @requires_target_mounted
    def ready_base_for_install(self):
        # run ready_base_for_install from chroot installer first
        ChrootInstaller.ready_base_for_install(self)
        self.log.info('checking for raid devices')
        raid_devices = self.helper.get_raid_devices()
        if raid_devices:
            self.log.info('raid devices found')
            create_mdadm_conf(self.target, raid_devices)
        else:
            self.log.info('no raid devices found')
        
    @requires_install_complete
    def install_modules(self):
        self.helper.install_modules()

    @requires_install_complete
    def install_kernel(self):
        self.helper.install_kernel()

    @requires_install_complete
    def install_fstab(self):
        self.helper.install_fstab()

    def setup_disks(self):
        self.helper.setup_disks()
        self._disks_setup = True
        
    @requires_target_exists
    @requires_disks_setup
    def mount_target(self):
        device = self.machine.array_hack()
        mounts = self.machine.get_installable_fsmounts()
        mount_target(self.target, mounts, device)
        self._target_mounted = True
예제 #23
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 = {}
        self._enable_bad_hacks = False
        if self.cfg.is_it_true('installer', 'enable_bad_hacks'):
            self._enable_bad_hacks = True
        
    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 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
            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()
예제 #24
0
 def __init__(self, app, **atts):
     BaseDocument.__init__(self, app, **atts)
     self.machine = MachineHandler(self.conn)
예제 #25
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)
예제 #26
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()
예제 #27
0
class MachineDoc(_MachineBaseDocument):
    def __init__(self, app, **atts):
        _MachineBaseDocument.__init__(self, app, **atts)
        self.machine = MachineHandler(self.conn)
        self._bgcolor_body = 'Salmon'
        self._bgcolor_section = 'IndianRed'
        self._other_section_font_color = 'DarkViolet'
        self._bgcolor_thead = 'MediumOrchid2'
        self._bgcolor_table = 'MediumOrchid3'
        self.body['bgcolor'] = self._bgcolor_body

    def set_machine(self, machine):
        self.machine.set_machine(machine)
        self.clear_body()
        title = SectionTitle('Machine:  %s' % machine)
        title['bgcolor'] = self._bgcolor_section
        title['width'] = '100%'
        self.body.append(title)
        #mtable = Table()
        self._setup_parent_table()
        self._setup_main_attributes()
        self._setup_relation_sections()
        self._make_footer_anchors('machine', machine)
        return

    def _setup_parent_table(self):
        machine = self.machine.current_machine
        parent_table = Table(bgcolor=self._bgcolor_table, border=1)
        parent = self.machine.parent
        if parent is None:
            parent = '(No Parent Set)'
        headrow = TableRow(bgcolor=self._bgcolor_thead)
        for col in ['parent', 'command']:
            headrow.append(TableHeader(col))
        parent_table.append(headrow)
        mainrow = TableRow()
        parent_cell = TableCell(parent)
        mainrow.append(parent_cell)
        select_anchor = Anchor('select', href='select.parent.%s' % machine)
        delete_anchor = Anchor('delete', href='delete.parent.%s' % machine)
        command_cell = TableCell()
        command_cell.append(select_anchor)
        if self.machine.parent is not None:
            #command_cell.append(Break())
            command_cell.append('|=====|')
            command_cell.append(delete_anchor)
        mainrow.append(command_cell)
        parent_table.append(mainrow)
        self.body.append(parent_table)

    def _setup_main_attributes(self):
        machine = self.machine.current_machine
        attribute_table = Table(bgcolor=self._bgcolor_table, border=1)
        headrow = TableRow(bgcolor=self._bgcolor_thead)
        for col in ['Attribute', 'Value', 'Inherited From', 'Command']:
            headrow.append(TableHeader(col))
        attribute_table.append(headrow)
        for attribute in ['kernel', 'profile', 'diskconfig']:
            errormsg = ''
            try:
                value, inherited_from = self.machine.get_attribute(attribute)
            except AttributeUnsetInAncestryError:
                errormsg = "WARNING: not set anywhere"
                value, inherited_from = errormsg, errormsg
            tablerow = TableRow()
            href = 'select.attribute||%s.%s' % (attribute, machine)
            anchor = Anchor(attribute, href=href)
            cell = TableCell(Bold(anchor, ':'))
            tablerow.append(cell)
            cell = TableCell(value)
            tablerow.append(value)
            cell = TableCell()
            if inherited_from is not None:
                if errormsg:
                    anchor = Bold(errormsg)
                else:
                    anchor = Anchor(inherited_from,
                                    href='select.machine.%s' % inherited_from)
                cell.append(anchor)
            else:
                cell.append('(set here)')
            tablerow.append(cell)
            cell = TableCell()
            anchor = Anchor('clear',
                            href='delete.attribute||%s.%s' %
                            (attribute, machine))
            if inherited_from is None:
                cell.set(anchor)
            tablerow.append(cell)
            attribute_table.append(tablerow)
        self.body.append(attribute_table)

    def _setup_relation_sections(self):
        machine = self.machine.current_machine
        clause = Eq('machine', machine)
        cursor = self.conn.cursor(statement=True)
        famrows = cursor.select(table='machine_family',
                                clause=clause,
                                order='family')
        self._setup_section('Families', ['family'], famrows)
        self._setup_script_section()
        vars_ = cursor.select(table='machine_variables',
                              clause=clause,
                              order=['trait', 'name'])
        #self._setup_section('Variables', ['trait', 'name', 'value'], vars_)
        self._setup_variables_section(vars_)

    def _setup_script_section(self):
        machine = self.machine.current_machine
        relation = self.machine.relation
        scriptnames = relation.scripts.scriptnames
        scripts = []
        for scriptname in scriptnames:
            result = relation.get_script(scriptname, show_inheritance=True)
            if result is not None:
                # if result is not None, then result is a tuple
                # that is (fileobj, parent)
                # but we need scriptname, parent
                scripts.append((scriptname, result[1]))
        # make the section
        title = SectionTitle('Scripts', bgcolor=self._bgcolor_section)
        title.set_font(color=self._other_section_font_color)
        anchor = Anchor('new', href='new.%s.machine' % 'Scripts')
        title.row.append(TableCell(anchor))
        self.body.append(title)
        if len(scripts):
            table = self._make_script_table(scripts, border=1, cellspacing=1)
            color_header(table, self._bgcolor_thead)
            self.body.append(table)

    def _make_script_table(self, scripts, **atts):
        table = Table(bgcolor=self._bgcolor_table, **atts)
        table.context = 'Scripts'
        fields = ['script', 'inherited', 'command']
        self._add_table_header(table, fields)
        for scriptname, parent in scripts:
            self._add_script_table_row(table, scriptname, parent)
        return table

    def _add_script_table_row(self, table, scriptname, parent):
        tablerow = TableRow()
        # scriptname cell
        scriptname_cell = TableCell(scriptname)

        # command cell (we use
        # an empty cell as default)
        command_cell = TableCell()

        # parent cell
        if parent is None:
            parent = '(defined here)'
            # if script is defined here, instead of inherited
            # we make the command anchors.
            durl = 'delete.%s.%s' % (table.context, scriptname)
            eurl = 'edit.%s.%s' % (table.context, scriptname)
            delanchor = Anchor('delete', href=durl)
            editanchor = Anchor('edit', href=eurl)
            command_cell = TableCell(editanchor)
            command_cell.append(Break())
            command_cell.append(delanchor)
        parent_cell = TableCell(parent)

        # append the cells to the rows
        tablerow.append(scriptname_cell)
        tablerow.append(parent_cell)
        tablerow.append(command_cell)
        table.append(tablerow)

    def _setup_variables_section(self, rows):
        section = 'Variables'
        machine = self.machine.current_machine
        relation = self.machine.relation
        # make the section
        title = SectionTitle(section, bgcolor=self._bgcolor_section)
        title.set_font(color=self._other_section_font_color)
        anchor = Anchor('new', href='new.%s.machine' % section)
        title.row.append(TableCell(anchor))
        self.body.append(title)
        if len(rows):
            table = self._make_variables_table(rows, border=1, cellspacing=1)
            color_header(table, self._bgcolor_thead)
            self.body.append(table)

    def _make_variables_table(self, rows, **atts):
        table = Table(bgcolor=self._bgcolor_table, **atts)
        table.context = 'Variables'
        fields = ['trait', 'name', 'value']
        self._add_table_header(table, fields + ['command'])
        for row in rows:
            self._add_variables_table_row(table, fields, row)
        return table

    def _add_variables_table_row(self, table, fields, row):
        tablerow = TableRow()
        for field in fields:
            tablerow.append(TableCell(str(row[field])))
        ident = '%s||%s' % (row['trait'], row['name'])
        durl = 'delete.%s.%s' % (table.context, ident)
        eurl = 'edit.%s.%s' % (table.context, ident)
        delanchor = Anchor('delete', href=durl)
        editanchor = Anchor('edit', href=eurl)
        cell = TableCell(editanchor)
        cell.append(Break())
        cell.append(delanchor)
        tablerow.append(cell)
        table.append(tablerow)

    def _setup_section(self, name, fields, rows):
        title = SectionTitle(name, bgcolor=self._bgcolor_section)
        title.set_font(color=self._other_section_font_color)
        anchor = Anchor('new', href='new.%s.machine' % name)
        title.row.append(TableCell(anchor))
        self.body.append(title)
        if len(rows):
            table = self._make_table(name,
                                     fields,
                                     rows,
                                     border=1,
                                     cellspacing=1)
            color_header(table, self._bgcolor_thead)
            self.body.append(table)

    def _make_table(self, context, fields, rows, **atts):
        table = Table(bgcolor=self._bgcolor_table, **atts)
        table.context = context
        self._add_table_header(table, fields + ['command'])
        for row in rows:
            self._add_table_row(table, fields, row)
        return table

    def _add_table_row(self, table, fields, row):
        tablerow = TableRow()
        for field in fields:
            tablerow.append(TableCell(str(row[field])))
        durl = 'delete.%s.%s' % (table.context, row[fields[0]])
        eurl = 'edit.%s.%s' % (table.context, row[fields[0]])
        delanchor = Anchor('delete', href=durl)
        editanchor = Anchor('edit', href=eurl)
        cell = TableCell(editanchor)
        cell.append(Break())
        cell.append(delanchor)
        tablerow.append(cell)
        table.append(tablerow)

    def _make_footer_anchors(self, name, value):
        newanchor = Anchor('new', href='new.%s.foo' % name)
        deleteanchor = Anchor('delete', href='delete.%s.%s' % (name, value))
        self.body.append(Ruler())
        self.body.append(Break())
        self.body.append(deleteanchor)
        self.body.append(Break())
        self.body.append(newanchor)
예제 #28
0
class MachineInstaller(BaseMachineInstaller):
    def __init__(self, conn):
        BaseMachineInstaller.__init__(self, conn)
        # the processes are mostly the same as in the
        # ChrootInstaller
        self._processes = list(DEFAULT_PROCESSES)
        pmap = dict(setup_disks=self.setup_disks,
                    mount_target=self.mount_target,
                    install_fstab=self.install_fstab,
                    install_modules=self.install_modules,
                    install_kernel=self.install_kernel,
                    prepare_bootloader=self.prepare_bootloader
                    )
        self._process_map.update(pmap)
        self.machine = MachineHandler(self.conn)
        self.helper = None
        self._target_mounted = False
        self._disks_setup = False
        
    def set_machine(self, machine):
        self.check_target_set()
        self.machine.set_machine(machine)
        logdir = path(self.defenv.get('installer', 'base_log_directory'))
        if not logdir.isdir():
            logdir.mkdir()
        logfile = logdir / 'paella-install-%s.log' % machine
        os.environ['PAELLA_MACHINE'] = machine
        disklogpath = path(self.defenv.get('installer', 'disk_log_directory'))
        self.disklogpath = disklogpath / ('disklog-%s'  % machine)
        if not self.disklogpath.isdir():
            self.disklogpath.makedirs()
        self.set_logfile(logfile)
        self.log.info('machine set to %s' % machine)
        # we need to set machine_data before setting the profile
        # so that the machine_data is passed to the profile and trait installers
        self.machine_data = self.machine.get_machine_data()
        profile = self.machine.get_profile()
        self.set_profile(profile)
        self.curenv = CurrentEnvironment(self.conn, machine)
        self.helper = MachineInstallerHelper(self)
        self.helper.curenv = self.curenv

    def make_script(self, procname):
        self.check_machine_set()
        script = self.machine.relation.get_script(procname, inherited=True)
        if script is not None:
            return make_script(procname, script, '/')
        else:
            return None
        
    def ready_base_for_install(self):
        self.check_target_mounted()
        # run ready_base_for_install from chroot installer first
        ChrootInstaller.ready_base_for_install(self)
        
    def install_modules(self):
        self.check_install_complete()
        self.log.info("install_modules isn't being used anymore.")
        msg = "This step is still here, in case you need to use a script"
        msg += " to add modules to /etc/modules ."
        self.log.info(msg)
        if False:
            self.helper.install_modules()

    def install_kernel(self):
        self.check_install_complete()
        self.helper.install_kernel()

    def prepare_bootloader(self):
        self.helper.prepare_bootloader()
        
    def install_fstab(self):
        self.check_install_complete()
        self.helper.install_fstab()

    def setup_disks(self):
        self.helper.setup_disks()
        self._disks_setup = True
        
    def mount_target(self):
        self.check_target_exists()
        self.check_disks_setup()
        self.helper.mount_target()
        # this is now done in post_process
        #self._target_mounted = True
        
    def log_all_processes_started(self):
        machine = self.machine.current_machine
        installer = self.__class__.__name__
        self.log.info('Starting all processes for %s(%s)' % (installer, machine))
        
    def log_all_processes_finished(self):
        machine = self.machine.current_machine
        installer = self.__class__.__name__
        self.log.info('Finished all processes for %s(%s)' % (installer, machine))

    def post_process(self, procname):
        # be sure to run parent's post_process first
        BaseMachineInstaller.post_process(self, procname)
        name = self.__class__.__name__
        # now check for processes specific to the machine installer
        if procname == 'mount_target':
            self.log.info('%s marking %s finished' % (name, procname))
            self._target_mounted = True
        elif procname == 'setup_disks':
            self.log.info('%s marking %s finished' % (name, procname))
            self._disks_setup = True
예제 #29
0
from useless.base.path import path

from paella.base import PaellaConfig
from paella.db import PaellaConnection
from paella.db.trait import Trait
from paella.db.family import Family
from paella.db.profile import Profile
from paella.db.machine import MachineHandler
from paella.db.installer import InstallerManager

from paella.db import DefaultEnvironment

from paella.installer.toolkit import InstallerTools

if __name__ == '__main__':
    cfg = PaellaConfig()
    conn = PaellaConnection()
    suite = 'bootstrap'
    t = Trait(conn, suite)
    f = Family(conn)
    p = Profile(conn)
    m = MachineHandler(conn)
    de = DefaultEnvironment(conn)
    im = InstallerManager(conn)

    #os.environ['PAELLA_MACHINE'] = 'testmachine'
    os.environ['PAELLA_PROFILE'] = 'default'
    os.environ['PAELLA_TARGET'] = path('/foo/bar')
    it = InstallerTools()
    
예제 #30
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()
예제 #31
0
 def __init__(self, app, **atts):
     BaseDocument.__init__(self, app, **atts)
     self.machine = MachineHandler(self.conn)
예제 #32
0
파일: machine.py 프로젝트: joelsefus/paella
class MachineDoc(_MachineBaseDocument):
    def __init__(self, app, **atts):
        _MachineBaseDocument.__init__(self, app, **atts)
        self.machine = MachineHandler(self.conn)
        self._bgcolor_body = 'Salmon'
        self._bgcolor_section = 'IndianRed'
        self._other_section_font_color = 'DarkViolet'
        self._bgcolor_thead = 'MediumOrchid2'
        self._bgcolor_table = 'MediumOrchid3'
        self.body['bgcolor'] = self._bgcolor_body

    def set_machine(self, machine):
        self.machine.set_machine(machine)
        self.clear_body()
        title = SectionTitle('Machine:  %s' % machine)
        title['bgcolor'] = self._bgcolor_section
        title['width'] = '100%'
        self.body.append(title)
        #mtable = Table()
        self._setup_parent_table()
        self._setup_main_attributes()
        self._setup_relation_sections()
        self._make_footer_anchors('machine', machine)
        return

    def _setup_parent_table(self):
        machine = self.machine.current_machine
        parent_table = Table(bgcolor=self._bgcolor_table, border=1)
        parent = self.machine.parent
        if parent is None:
            parent = '(No Parent Set)'
        headrow = TableRow(bgcolor=self._bgcolor_thead)
        for col in ['parent', 'command']:
            headrow.append(TableHeader(col))
        parent_table.append(headrow)
        mainrow = TableRow()
        parent_cell = TableCell(parent)
        mainrow.append(parent_cell)
        select_anchor = Anchor('select', href='select.parent.%s' % machine)
        delete_anchor = Anchor('delete', href='delete.parent.%s' % machine)
        command_cell = TableCell()
        command_cell.append(select_anchor)
        if self.machine.parent is not None:
            #command_cell.append(Break())
            command_cell.append('|=====|')
            command_cell.append(delete_anchor)
        mainrow.append(command_cell)
        parent_table.append(mainrow)
        self.body.append(parent_table)
        
    def _setup_main_attributes(self):
        machine = self.machine.current_machine
        attribute_table = Table(bgcolor=self._bgcolor_table, border=1)
        headrow = TableRow(bgcolor=self._bgcolor_thead)
        for col in ['Attribute', 'Value', 'Inherited From', 'Command']:
            headrow.append(TableHeader(col))
        attribute_table.append(headrow)
        for attribute in ['kernel', 'profile', 'diskconfig']:
            errormsg = ''
            try:
                value, inherited_from = self.machine.get_attribute(attribute)
            except AttributeUnsetInAncestryError:
                errormsg = "WARNING: not set anywhere"
                value, inherited_from = errormsg, errormsg
            tablerow = TableRow()
            href = 'select.attribute||%s.%s' % (attribute, machine)
            anchor = Anchor(attribute, href=href)
            cell = TableCell(Bold(anchor, ':'))
            tablerow.append(cell)
            cell = TableCell(value)
            tablerow.append(value)
            cell = TableCell()
            if inherited_from is not None:
                if errormsg:
                    anchor = Bold(errormsg)
                else:
                    anchor = Anchor(inherited_from, href='select.machine.%s' % inherited_from)
                cell.append(anchor)
            else:
                cell.append('(set here)')
            tablerow.append(cell)
            cell = TableCell()
            anchor = Anchor('clear', href='delete.attribute||%s.%s' % (attribute, machine))
            if inherited_from is None:
                cell.set(anchor)
            tablerow.append(cell)
            attribute_table.append(tablerow)
        self.body.append(attribute_table)
        
    def _setup_relation_sections(self):
        machine = self.machine.current_machine
        clause = Eq('machine', machine)
        cursor = self.conn.cursor(statement=True)
        famrows = cursor.select(table='machine_family', clause=clause,
                                     order='family')
        self._setup_section('Families', ['family'], famrows)
        self._setup_script_section()
        vars_ = cursor.select(table='machine_variables', clause=clause,
                                   order=['trait', 'name'])
        #self._setup_section('Variables', ['trait', 'name', 'value'], vars_)
        self._setup_variables_section(vars_)
        
    def _setup_script_section(self):
        machine = self.machine.current_machine
        relation = self.machine.relation
        scriptnames = relation.scripts.scriptnames
        scripts = []
        for scriptname in scriptnames:
            result = relation.get_script(scriptname, show_inheritance=True)
            if result is not None:
                # if result is not None, then result is a tuple
                # that is (fileobj, parent)
                # but we need scriptname, parent
                scripts.append((scriptname, result[1]))
        # make the section
        title = SectionTitle('Scripts', bgcolor=self._bgcolor_section)
        title.set_font(color=self._other_section_font_color)
        anchor = Anchor('new', href='new.%s.machine' % 'Scripts')
        title.row.append(TableCell(anchor))
        self.body.append(title)
        if len(scripts):
            table = self._make_script_table(scripts, border=1, cellspacing=1)
            color_header(table, self._bgcolor_thead)
            self.body.append(table)

    def _make_script_table(self, scripts, **atts):
        table = Table(bgcolor=self._bgcolor_table, **atts)
        table.context = 'Scripts'
        fields= ['script', 'inherited', 'command']
        self._add_table_header(table, fields)
        for scriptname, parent in scripts:
            self._add_script_table_row(table, scriptname, parent)
        return table
    
    def _add_script_table_row(self, table, scriptname, parent):
        tablerow = TableRow()
        # scriptname cell
        scriptname_cell = TableCell(scriptname)
        
        # command cell (we use
        # an empty cell as default)
        command_cell = TableCell()

        # parent cell
        if parent is None:
            parent = '(defined here)'
            # if script is defined here, instead of inherited
            # we make the command anchors.
            durl = 'delete.%s.%s' % (table.context, scriptname)
            eurl = 'edit.%s.%s' % (table.context, scriptname)
            delanchor = Anchor('delete', href=durl)
            editanchor = Anchor('edit', href=eurl)
            command_cell = TableCell(editanchor)
            command_cell.append(Break())
            command_cell.append(delanchor)
        parent_cell = TableCell(parent)

        # append the cells to the rows
        tablerow.append(scriptname_cell)
        tablerow.append(parent_cell)
        tablerow.append(command_cell)
        table.append(tablerow)

    def _setup_variables_section(self, rows):
        section = 'Variables'
        machine = self.machine.current_machine
        relation = self.machine.relation
        # make the section
        title = SectionTitle(section, bgcolor=self._bgcolor_section)
        title.set_font(color=self._other_section_font_color)
        anchor = Anchor('new', href='new.%s.machine' % section)
        title.row.append(TableCell(anchor))
        self.body.append(title)
        if len(rows):
            table = self._make_variables_table(rows, border=1, cellspacing=1)
            color_header(table, self._bgcolor_thead)
            self.body.append(table)

    def _make_variables_table(self, rows, **atts):
        table = Table(bgcolor=self._bgcolor_table, **atts)
        table.context = 'Variables'
        fields = ['trait', 'name', 'value']
        self._add_table_header(table, fields + ['command'])
        for row in rows:
            self._add_variables_table_row(table, fields, row)
        return table

    def _add_variables_table_row(self, table, fields, row):
        tablerow = TableRow()
        for field in fields:
            tablerow.append(TableCell(str(row[field])))
        ident = '%s||%s' % (row['trait'], row['name'])
        durl = 'delete.%s.%s' % (table.context, ident)
        eurl = 'edit.%s.%s' % (table.context, ident)
        delanchor = Anchor('delete', href=durl)
        editanchor = Anchor('edit', href=eurl)
        cell = TableCell(editanchor)
        cell.append(Break())
        cell.append(delanchor)
        tablerow.append(cell)
        table.append(tablerow)

    def _setup_section(self, name, fields, rows):
        title = SectionTitle(name, bgcolor=self._bgcolor_section)
        title.set_font(color=self._other_section_font_color)
        anchor = Anchor('new', href='new.%s.machine' % name)
        title.row.append(TableCell(anchor))
        self.body.append(title)
        if len(rows):
            table = self._make_table(name, fields, rows, border=1, cellspacing=1)
            color_header(table, self._bgcolor_thead)
            self.body.append(table)
            
    def _make_table(self, context, fields, rows, **atts):
        table = Table(bgcolor=self._bgcolor_table, **atts)
        table.context = context
        self._add_table_header(table, fields + ['command'])
        for row in rows:
            self._add_table_row(table, fields, row)
        return table

    def _add_table_row(self, table, fields, row):
        tablerow = TableRow()
        for field in fields:
            tablerow.append(TableCell(str(row[field])))
        durl = 'delete.%s.%s' % (table.context, row[fields[0]])
        eurl = 'edit.%s.%s' % (table.context, row[fields[0]])
        delanchor = Anchor('delete', href=durl)
        editanchor = Anchor('edit', href=eurl)
        cell = TableCell(editanchor)
        cell.append(Break())
        cell.append(delanchor)
        tablerow.append(cell)
        table.append(tablerow)

    def _make_footer_anchors(self, name, value):
        newanchor = Anchor('new', href='new.%s.foo' % name)
        deleteanchor = Anchor('delete', href='delete.%s.%s' % (name, value))
        self.body.append(Ruler())
        self.body.append(Break())
        self.body.append(deleteanchor)
        self.body.append(Break())
        self.body.append(newanchor)
예제 #33
0
class MachineInstaller(BaseMachineInstaller):
    def __init__(self, conn):
        BaseMachineInstaller.__init__(self, conn)
        # the processes are mostly the same as in the
        # ChrootInstaller
        self._processes = list(DEFAULT_PROCESSES)
        pmap = dict(setup_disks=self.setup_disks,
                    mount_target=self.mount_target,
                    install_fstab=self.install_fstab,
                    install_modules=self.install_modules,
                    install_kernel=self.install_kernel,
                    prepare_bootloader=self.prepare_bootloader
                    )
        self._process_map.update(pmap)
        self.machine = MachineHandler(self.conn)
        self.helper = None
        self._target_mounted = False
        self._disks_setup = False
        
    def set_machine(self, machine):
        self.check_target_set()
        self.machine.set_machine(machine)
        logdir = path(self.defenv.get('installer', 'base_log_directory'))
        if not logdir.isdir():
            logdir.mkdir()
        logfile = logdir / 'paella-install-%s.log' % machine
        os.environ['PAELLA_MACHINE'] = machine
        disklogpath = path(self.defenv.get('installer', 'disk_log_directory'))
        self.disklogpath = disklogpath / ('disklog-%s'  % machine)
        if not self.disklogpath.isdir():
            self.disklogpath.makedirs()
        self.set_logfile(logfile)
        self.log.info('machine set to %s' % machine)
        # we need to set machine_data before setting the profile
        # so that the machine_data is passed to the profile and trait installers
        self.machine_data = self.machine.get_machine_data()
        profile = self.machine.get_profile()
        self.set_profile(profile)
        self.curenv = CurrentEnvironment(self.conn, machine)
        self.helper = MachineInstallerHelper(self)
        self.helper.curenv = self.curenv

    def make_script(self, procname):
        self.check_machine_set()
        script = self.machine.relation.get_script(procname, inherited=True)
        if script is not None:
            return make_script(procname, script, '/')
        else:
            return None
        
    def ready_base_for_install(self):
        self.check_target_mounted()
        # run ready_base_for_install from chroot installer first
        ChrootInstaller.ready_base_for_install(self)
        
    def install_modules(self):
        self.check_install_complete()
        self.log.info("install_modules isn't being used anymore.")
        msg = "This step is still here, in case you need to use a script"
        msg += " to add modules to /etc/modules ."
        self.log.info(msg)
        if False:
            self.helper.install_modules()

    def install_kernel(self):
        self.check_install_complete()
        self.helper.install_kernel()

    def prepare_bootloader(self):
        self.helper.prepare_bootloader()
        
    def install_fstab(self):
        self.check_install_complete()
        self.helper.install_fstab()

    def setup_disks(self):
        self.helper.setup_disks()
        self._disks_setup = True
        
    def mount_target(self):
        self.check_target_exists()
        self.check_disks_setup()
        self.helper.mount_target()
        self._target_mounted = True