Example #1
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())
Example #2
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
Example #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())
Example #4
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())
Example #5
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())
Example #6
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())
Example #7
0
class MachineInstaller(BaseChrootInstaller):
    def __init__(self, conn):
        BaseChrootInstaller.__init__(self, conn)
        self.machine = MachineHandler(self.conn)
        self.processes = DEFAULT_PROCESSES
        self._process_map = {
            'setup_disks' : self.setup_disks,
            'mount_target' : self.mount_target,
            'bootstrap' : self.bootstrap_target,
            'make_device_entries' : self.make_device_entries,
            'apt_sources_installer' : self.setup_apt_sources_installer,
            'ready_base' : self.ready_base_for_install,
            'mount_target_proc' : self.mount_target_proc,
            'install' : self.install_to_target,
            'install_fstab' : self.install_fstab,
            'install_modules' : self.install_modules,
            'install_kernel' : self.install_kernel,
            'apt_sources_final' : self.setup_apt_sources_final,
            'umount_target_proc' : self.umount_target_proc
            }
        self.helper = None
        
    def process(self):
        mach = self.machine.current.machine
        self.log.info('Starting machine install process for %s' % mach)
        for proc in self.processes:
            self.log.info('processing %s for machine %s' % (proc, mach))
            self.run_process(proc)
            self.log.info('processed %s for machine %s' % (proc, mach))
        self.log.info('Ending machine install process for %s' % mach)
        
    def _make_script(self, name):
        script = self.machine.get_script(name)
        if script is not None:
            return make_script(name, script, '/')
        else:
            return None
        
    def run_process(self, proc):
        info = self.log.info
        self.start_process(proc)
        script = self._make_script(proc)
        mtype = self.machine.current.machine_type
        if script is None:
            info('No script for process %s on machine type %s' % (proc, mtype))
            if proc in self._process_map:
                info('Running default process %s' % proc)
                self._process_map[proc]()
            else:
                info('Nothing to do for process %s' % proc)
        else:
            self.log.info('%s script exists for %s' % (proc, mtype))
            self.run_process_script(proc, script)
        self.finish_process(proc)

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

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

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

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

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

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

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

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

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

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

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

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

    def make_disk_devices(self):
        devices = map(basename, self.machine.get_disk_devices())
        makedev(self.target, devices)
Example #8
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)
Example #9
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)
Example #10
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
Example #11
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)
Example #12
0
class NewInstaller(object):
    def __init__(self, conn, cfg):
        object.__init__(self)
        self.conn = conn
        self.cfg = cfg
        self.defenv = DefaultEnvironment(self.conn)
        self.machine = MachineHandler(self.conn)
        self.cursor = StatementCursor(self.conn)
        self.target = None
        self.installer = None
        self._mounted = None
        self._bootstrapped = None
        self.debmirror = self.cfg.get('debrepos', 'http_mirror')
        self._raid_setup = False
        self._raid_drives = {}
        self._enable_bad_hacks = False
        if self.cfg.is_it_true('installer', 'enable_bad_hacks'):
            self._enable_bad_hacks = True

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    def install(self, machine, target):
        self.set_machine(machine)
        if self._enable_bad_hacks:
            self.setup_disks()
        else:
            self.partition_disks()
            self.make_filesystems()
        self.setup_installer()
        self.set_target(target)
        self.ready_target()
        if self.cfg.is_it_true('installer', 'bootstrap_target'):
            self.bootstrap_target()
        else:
            self.extract_basebootstrap()
        self.ready_base_for_install()
        self.install_to_target()
        self.post_install()
Example #13
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
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()
Example #15
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()
Example #16
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