def backup(self, path): if not os.path.isdir(path): raise Error, 'arguement needs to be a directory' pdb = PaellaDatabase(self.conn, path) pdb.backup(path) mh = MachineHandler(self.conn) mh.export_machine_database(path)
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())
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())
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)
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
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 restore(self, path): if not os.path.isdir(path): raise Error, 'arguement needs to be a directory' dbpath = join(path, 'database.xml') mdbpath = join(path, 'machine_database.xml') pp = PaellaProcessor(self.conn, self.cfg) pp.create(dbpath) mh = MachineHandler(self.conn) #md = mh.parse_xmlfile(mdbpath) mh.restore_machine_database(path)
def restore(self, path): if not os.path.isdir(path): raise Error, 'arguement needs to be a directory' dbpath = join(path, 'database.xml') mdbpath = join(path, 'machine_database.xml') pp = PaellaProcessor(self.conn, self.cfg) pp.create(dbpath) mh = MachineHandler(self.conn) md = mh.parse_xmlfile(mdbpath) mh.insert_parsed_element(md)
def import_client(self, client): cpath, ppath, fpath, tpath = self._cpaths_(client) profiles, families, traits = self._client_schema(client) mdbpath = join(cpath, 'machine_database.xml') if families: f = Family(self.conn) f.import_families(fpath) if profiles: importer = PaellaImporter(self.conn) importer.import_all_profiles(ppath) mh = MachineHandler(self.conn) md = mh.parse_xmlfile(mdbpath) mh.insert_parsed_element(md)
def import_client(self, client): cpath, ppath, fpath, tpath = self._cpaths_(client) profiles, families, traits = self._client_schema(client) mdbpath = join(cpath, 'machine_database.xml') if families: f = Family(self.conn) f.import_families(fpath) if profiles: pp = PaellaProcessor(self.conn, self.cfg) pp.main_path = cpath pp.insert_profiles() mh = MachineHandler(self.conn) md = mh.parse_xmlfile(mdbpath) mh.insert_parsed_element(md)
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
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 __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
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())
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())
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())
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
class MachineInstaller(BaseChrootInstaller): def __init__(self, conn): BaseChrootInstaller.__init__(self, conn) self.machine = MachineHandler(self.conn) self.processes = DEFAULT_PROCESSES self._process_map = { 'setup_disks' : self.setup_disks, 'mount_target' : self.mount_target, 'bootstrap' : self.bootstrap_target, 'make_device_entries' : self.make_device_entries, 'apt_sources_installer' : self.setup_apt_sources_installer, 'ready_base' : self.ready_base_for_install, 'mount_target_proc' : self.mount_target_proc, 'install' : self.install_to_target, 'install_fstab' : self.install_fstab, 'install_modules' : self.install_modules, 'install_kernel' : self.install_kernel, 'apt_sources_final' : self.setup_apt_sources_final, 'umount_target_proc' : self.umount_target_proc } self.helper = None def process(self): mach = self.machine.current.machine self.log.info('Starting machine install process for %s' % mach) for proc in self.processes: self.log.info('processing %s for machine %s' % (proc, mach)) self.run_process(proc) self.log.info('processed %s for machine %s' % (proc, mach)) self.log.info('Ending machine install process for %s' % mach) def _make_script(self, name): script = self.machine.get_script(name) if script is not None: return make_script(name, script, '/') else: return None def run_process(self, proc): info = self.log.info self.start_process(proc) script = self._make_script(proc) mtype = self.machine.current.machine_type if script is None: info('No script for process %s on machine type %s' % (proc, mtype)) if proc in self._process_map: info('Running default process %s' % proc) self._process_map[proc]() else: info('Nothing to do for process %s' % proc) else: self.log.info('%s script exists for %s' % (proc, mtype)) self.run_process_script(proc, script) self.finish_process(proc) def start_process(self, proc): self._check_target() if proc == 'bootstrap': self._check_target_exists() def finish_process(self, proc): if proc == 'mount_target': self._mounted = True self.log.info('Target should be mounted now.') elif proc == 'bootstrap': self.log.info('Target should be bootstrapped now.') self._bootstrapped = True def _runscript(self, script, name, info): self.log.info(info['start']) runvalue = self.run(name, script, chroot=False) os.remove(script) self.log.info(info['done']) return runvalue def run_process_script(self, proc, script): info = scriptinfo(proc) if self._runscript(script, proc, info): raise InstallError, 'Error running script %s' % proc def _check_mounted(self): self._check_target_exists() if not self._mounted: raise InstallError, 'target not mounted' def _check_bootstrap(self): self._check_mounted() BaseChrootInstaller._check_bootstrap(self) def set_machine(self, machine): self.machine.set_machine(machine) try: logfile = os.environ['LOGFILE'] except KeyError: logfile = '/paellalog/paella-install-%s.log' % machine os.environ['PAELLA_LOGFILE'] = logfile # this needs to be removed sometime os.environ['LOGFILE'] = logfile os.environ['PAELLA_MACHINE'] = machine disklogpath = join(dirname(logfile), 'disklog-%s' % machine) if not os.path.isdir(disklogpath): makepaths(disklogpath) self.disklogpath = disklogpath self.curenv = CurrentEnvironment(self.conn, self.machine.current.machine) self.set_logfile(logfile) self.log.info('Machine Installer set machine to %s' % machine) self.mtypedata = self.machine.mtype.get_machine_type_data() def install(self, machine, target): self.set_machine(machine) self.setup_installer() self.set_target(target) makepaths(target) self.log.info('Installer set to install %s to %s' % (machine, target)) self.helper = MachineInstallerHelper(self) self.helper.curenv = self.curenv self.process() def setup_installer(self): machine = self.machine.current.machine profile = self.machine.current.profile self.log.info('Setting up profile installer for %s' % machine) self.installer = ProfileInstaller(self.conn) self.installer.log = self.log self.installer.mtypedata = self.mtypedata self.installer.set_profile(profile) self.suite = self.installer.suite self._installer_ready = True self.log.info('Profile installer ready for %s' % machine) def setup_disks(self): "this is a default process" self.helper.setup_disks() def mount_target(self): "this is a default process" self._check_target() makepaths(self.target) device = self.machine.array_hack() #mounts = self.machine.get_ordered_fsmounts() mounts = self.machine.get_installable_fsmounts() mount_target(self.target, mounts, device) self._mounted = True def bootstrap_target(self): "this is a default process" self.helper.bootstrap_target() def make_device_entries(self): "this is a default process" if self.defenv.is_it_true('installer', 'use_devices_tarball'): runlog('echo extracting devices tarball') self._extract_devices_tarball() else: runlog('echo using MAKEDEV to make generic devices') self.make_generic_devices() self.make_disk_devices() def setup_apt_sources_installer(self): "this is a default process" make_sources_list(self.defenv, self.target, self.suite) def ready_base_for_install(self): "this is a default process" set_root_passwd(self.target, myline) make_interfaces_simple(self.target) devices = self.helper.get_raid_devices() if devices: create_mdadm_conf(self.target, devices) def mount_target_proc(self): "this is a default process" echo('mounting target /proc') mount_target_proc(self.target) def install_to_target(self): "this is a default process" os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def install_modules(self): "this is a default process" modules = self.machine.get_modules() setup_modules(self.target, modules) def install_kernel(self): "this is a default process" kernel = self.machine.current.kernel echo('installing kernel %s' % kernel) install_kernel(kernel, self.target) def setup_apt_sources_final(self): "this is a default process" make_official_sources_list(self.defenv, self.target, self.suite) def install_fstab(self): "this is a default process" fstab = self.machine.make_fstab() make_fstab(fstab, self.target) def umount_target_proc(self): "this is a default process" echo('unmounting target /proc') mount_target_proc(self.target, umount=True) def _extract_devices_tarball(self): dtball = self.defenv.get('installer', 'devices_tarball') devpath = join(self.target, 'dev') runvalue = extract_tarball(devpath, dtball) if runvalue: raise Error, 'problem extracting devices tarball' def make_generic_devices(self): makedev(self.target, ['generic']) def make_disk_devices(self): devices = map(basename, self.machine.get_disk_devices()) makedev(self.target, devices)
class 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
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()
def __init__(self, app, **atts): BaseDocument.__init__(self, app, **atts) self.machine = MachineHandler(self.conn)
class MachineInstaller(BaseChrootInstaller): def __init__(self, conn): BaseChrootInstaller.__init__(self, conn) self.machine = MachineHandler(self.conn) self.processes = DEFAULT_PROCESSES self._process_map = { 'setup_disks': self.setup_disks, 'mount_target': self.mount_target, 'bootstrap': self.bootstrap_target, 'make_device_entries': self.make_device_entries, 'apt_sources_installer': self.setup_apt_sources_installer, 'ready_base': self.ready_base_for_install, 'mount_target_proc': self.mount_target_proc, 'install': self.install_to_target, 'install_fstab': self.install_fstab, 'install_modules': self.install_modules, 'install_kernel': self.install_kernel, 'apt_sources_final': self.setup_apt_sources_final, 'umount_target_proc': self.umount_target_proc } self.helper = None def process(self): mach = self.machine.current.machine self.log.info('Starting machine install process for %s' % mach) for proc in self.processes: self.log.info('processing %s for machine %s' % (proc, mach)) self.run_process(proc) self.log.info('processed %s for machine %s' % (proc, mach)) self.log.info('Ending machine install process for %s' % mach) def _make_script(self, name): script = self.machine.get_script(name) if script is not None: return make_script(name, script, '/') else: return None def run_process(self, proc): info = self.log.info self.start_process(proc) script = self._make_script(proc) mtype = self.machine.current.machine_type if script is None: info('No script for process %s on machine type %s' % (proc, mtype)) if proc in self._process_map: info('Running default process %s' % proc) self._process_map[proc]() else: info('Nothing to do for process %s' % proc) else: self.log.info('%s script exists for %s' % (proc, mtype)) self.run_process_script(proc, script) self.finish_process(proc) def start_process(self, proc): self._check_target() if proc == 'bootstrap': self._check_target_exists() def finish_process(self, proc): if proc == 'mount_target': self._mounted = True self.log.info('Target should be mounted now.') elif proc == 'bootstrap': self.log.info('Target should be bootstrapped now.') self._bootstrapped = True def _runscript(self, script, name, info): self.log.info(info['start']) runvalue = self.run(name, script, chroot=False) os.remove(script) self.log.info(info['done']) return runvalue def run_process_script(self, proc, script): info = scriptinfo(proc) if self._runscript(script, proc, info): raise InstallError, 'Error running script %s' % proc def _check_mounted(self): self._check_target_exists() if not self._mounted: raise InstallError, 'target not mounted' def _check_bootstrap(self): self._check_mounted() BaseChrootInstaller._check_bootstrap(self) def set_machine(self, machine): self.machine.set_machine(machine) try: logfile = os.environ['LOGFILE'] except KeyError: logfile = '/paellalog/paella-install-%s.log' % machine os.environ['PAELLA_LOGFILE'] = logfile # this needs to be removed sometime os.environ['LOGFILE'] = logfile os.environ['PAELLA_MACHINE'] = machine disklogpath = join(dirname(logfile), 'disklog-%s' % machine) if not os.path.isdir(disklogpath): makepaths(disklogpath) self.disklogpath = disklogpath self.curenv = CurrentEnvironment(self.conn, self.machine.current.machine) self.set_logfile(logfile) self.log.info('Machine Installer set machine to %s' % machine) self.mtypedata = self.machine.mtype.get_machine_type_data() def install(self, machine, target): self.set_machine(machine) self.setup_installer() self.set_target(target) makepaths(target) self.log.info('Installer set to install %s to %s' % (machine, target)) self.helper = MachineInstallerHelper(self) self.helper.curenv = self.curenv self.process() def setup_installer(self): machine = self.machine.current.machine profile = self.machine.current.profile self.log.info('Setting up profile installer for %s' % machine) self.installer = ProfileInstaller(self.conn) self.installer.log = self.log self.installer.mtypedata = self.mtypedata self.installer.set_profile(profile) self.suite = self.installer.suite self._installer_ready = True self.log.info('Profile installer ready for %s' % machine) def setup_disks(self): "this is a default process" self.helper.setup_disks() def mount_target(self): "this is a default process" self._check_target() makepaths(self.target) device = self.machine.array_hack() #mounts = self.machine.get_ordered_fsmounts() mounts = self.machine.get_installable_fsmounts() mount_target(self.target, mounts, device) self._mounted = True def bootstrap_target(self): "this is a default process" self.helper.bootstrap_target() def make_device_entries(self): "this is a default process" if self.defenv.is_it_true('installer', 'use_devices_tarball'): runlog('echo extracting devices tarball') self._extract_devices_tarball() else: runlog('echo using MAKEDEV to make generic devices') self.make_generic_devices() self.make_disk_devices() def setup_apt_sources_installer(self): "this is a default process" make_sources_list(self.conn, self.target, self.suite) def ready_base_for_install(self): "this is a default process" set_root_passwd(self.target, myline) make_interfaces_simple(self.target) devices = self.helper.get_raid_devices() if devices: create_mdadm_conf(self.target, devices) def mount_target_proc(self): "this is a default process" echo('mounting target /proc') mount_target_proc(self.target) def install_to_target(self): "this is a default process" os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def install_modules(self): "this is a default process" modules = self.machine.get_modules() setup_modules(self.target, modules) def install_kernel(self): "this is a default process" kernel = self.machine.current.kernel echo('installing kernel %s' % kernel) install_kernel(kernel, self.target) def setup_apt_sources_final(self): "this is a default process" make_official_sources_list(self.conn, self.target, self.suite) def install_fstab(self): "this is a default process" fstab = self.machine.make_fstab() make_fstab(fstab, self.target) def umount_target_proc(self): "this is a default process" echo('unmounting target /proc') mount_target_proc(self.target, umount=True) def _extract_devices_tarball(self): dtball = self.defenv.get('installer', 'devices_tarball') devpath = join(self.target, 'dev') runvalue = extract_tarball(devpath, dtball) if runvalue: raise Error, 'problem extracting devices tarball' def make_generic_devices(self): makedev(self.target, ['generic']) def make_disk_devices(self): devices = map(basename, self.machine.get_disk_devices()) makedev(self.target, devices)
class NewInstaller(object): def __init__(self, conn, cfg): object.__init__(self) self.conn = conn self.cfg = cfg self.defenv = DefaultEnvironment(self.conn) self.machine = MachineHandler(self.conn) self.cursor = StatementCursor(self.conn) self.target = None self.installer = None self._mounted = None self._bootstrapped = None self.debmirror = self.cfg.get('debrepos', 'http_mirror') self._raid_setup = False self._raid_drives = {} self._enable_bad_hacks = False if self.cfg.is_it_true('installer', 'enable_bad_hacks'): self._enable_bad_hacks = True def set_logfile(self, logfile): env = os.environ if logfile is None: if env.has_key('PAELLA_LOGFILE'): self.logfile = env['PAELLA_LOGFILE'] elif env.has_key('LOGFILE'): self.logfile = env['LOGFILE'] elif self.defenv.has_option('installer', 'default_logfile'): self.logfile = self.defenv.get('installer', 'default_logfile') else: raise InstallSetupError, 'There is no log file defined, giving up.' else: self.logfile = logfile logdir = os.path.dirname(self.logfile) if logdir: makepaths(os.path.dirname(self.logfile)) format = '%(name)s - %(asctime)s - %(levelname)s: %(message)s' self.log = Log('paella-installer', self.logfile, format) def _check_target(self): if not self.target: raise Error, 'no target specified' def _check_installer(self): if not self.installer: raise Error, 'no installer available' def _check_mounted(self): self._check_target() if not self._mounted: raise InstallError, 'target not mounted' def _check_bootstrap(self): self._check_mounted() if not self._bootstrapped: raise Error, 'target not bootstrapped' def set_machine(self, machine): self.machine.set_machine(machine) try: logfile = os.environ['LOGFILE'] except KeyError: logfile = '/paellalog/paella-install-%s.log' % machine os.environ['LOGFILE'] = logfile os.environ['PAELLA_MACHINE'] = machine disklogpath = join(dirname(logfile), 'disklog') if not os.path.isdir(disklogpath): makepaths(disklogpath) self.disklogpath = disklogpath self.curenv = CurrentEnvironment(self.conn, self.machine.current.machine) self.set_logfile(logfile) def check_if_mounted(self, device): mounts = file('/proc/mounts') for line in file: if line.startswith(device): return True return False def unmount_device(self, device): mounted = os.system('umount %s' % device) def make_filesystems(self): device = self.machine.array_hack(self.machine.current.machine_type) mddev = False if device == '/dev/md': mdnum = 0 mddev = True all_fsmounts = self.machine.get_installable_fsmounts() env = CurrentEnvironment(self.conn, self.machine.current.machine) for row in all_fsmounts: if mddev: pdev = '/dev/md%d' % mdnum mdnum += 1 else: pdev = device + str(row.partition) if row.mnt_name in env.keys(): print '%s held' % row.mnt_name elif row.fstype == 'swap': runlog('echo making swap on %s' % pdev) runlog('mkswap %s' % pdev) else: print 'making filesystem for', row.mnt_name make_filesystem(pdev, row.fstype) def set_target(self, target): self.target = target def _pdev(self, device, partition): return device + str(partition) def _mount_target_proc(self): self._check_bootstrap() tproc = join(self.target, 'proc') cmd = 'mount --bind /proc %s' % tproc runvalue = runlog(cmd) if runvalue: raise InstallError, 'problem mounting target /proc at %s' % tproc else: self._proc_mounted = True def _umount_target_proc(self): tproc = join(self.target, 'proc') cmd = 'umount %s' % tproc runvalue = runlog(cmd) if runvalue: raise InstallError, 'problem unmounting target /proc at %s' % tproc else: self._proc_mounted = False def ready_target(self): self._check_target() makepaths(self.target) device = self.machine.array_hack(self.machine.current.machine_type) clause = Eq('filesystem', self.machine.current.filesystem) clause &= Gt('partition', '0') table = 'filesystem_mounts natural join mounts' mounts = self.cursor.select(table=table, clause=clause, order='mnt_point') if mounts[0].mnt_point != '/': raise Error, 'bad set of mounts', mounts mddev = False mdnum = 0 if device == '/dev/md': mddev = True pdev = '/dev/md0' mdnum += 1 else: pdev = self._pdev(device, mounts[0].partition) runlog('echo mounting target %s to %s ' % (pdev, self.target)) clause &= Neq('mnt_point', '/') mounts = self.cursor.select(table=table, clause=clause, order='ord') mountable = [mount for mount in mounts if mount.fstype != 'swap'] runlog('mount %s %s' % (pdev, self.target)) for mnt in mountable: tpath = os.path.join(self.target, mnt.mnt_point[1:]) makepaths(tpath) if mddev: pdev = '/dev/md%d' % mdnum else: pdev = self._pdev(device, mnt.partition) mdnum += 1 runlog('mount %s %s' % (pdev, tpath)) self._mounted = True def setup_installer(self): profile = self.machine.current.profile self.installer = ProfileInstaller(self.conn) self.installer.log = self.log self.installer.set_profile(profile) self.suite = self.installer.suite def organize_disks(self): return self.machine.check_machine_disks(self.machine.current.machine_type) def _setup_disks(self, diskname, disks=None): if disks is None: disks = self.organize_disks() devices = disks[diskname] def setup_disks(self): disks = self.organize_disks() disknames = disks.keys() if not len(disknames): self._setup_disk_fai('default', '/dev/hda') else: if len(disknames) > 1: #this isn't really handled yet self.partition_disks() self.make_filesystems() else: devices = disks[disknames[0]] if len(devices) > 1: #this is a raid setup self.partition_disks() self.make_filesystems() elif len(devices) == 1: self._setup_disk_fai(self.machine.current.filesystem, devices[0]) else: self._setup_disk_fai('default', '/dev/hda') def _setup_disk_fai(self, filesystem, device): disk_config = self.machine.make_disk_config_info(device) fileid, disk_config_path = tempfile.mkstemp('paella', 'diskinfo') disk_config_file = file(disk_config_path, 'w') disk_config_file.write(disk_config) disk_config_file.close() script = '/usr/lib/paella/scripts/setup_harddisks_fai' options = '-X -f %s' % disk_config_path env = 'env LOGDIR=%s diskvar=%s' % (self.disklogpath, join(self.disklogpath, 'diskvar')) command = '%s %s %s' % (env, script, options) runlog(command) def _setup_raid_drives(self, diskname, devices): self._raid_setup = True self._raid_drives[diskname] = devices for device in devices: self._partition_disk(diskname, device) ndev = len(devices) print 'doing raid setup on %s' % diskname fs = self.machine.current.filesystem print fs pnums = [r.partition for r in self.machine.get_installable_fsmounts(fs)] mdnum = 0 for p in pnums: mdadm = 'mdadm --create /dev/md%d' % mdnum mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev) devices = ['%s%s' % (d, p) for d in devices] command = mdadm + ' '.join(devices) print command yesman = 'bash -c "yes | %s"' % command print yesman os.system(yesman) mdnum += 1 print 'doing raid setup on %s' % str(devices) mdstat = file('/proc/mdstat').read() while mdstat.find('resync') > -1: sleep(10) mdstat = file('/proc/mdstat').read() def partition_disks(self): disks = self.organize_disks() for diskname in disks: for device in disks[diskname]: self._partition_disk(diskname, device) if len(disks[diskname]) > 1: self._raid_setup = True self._raid_drives[diskname] = disks[diskname] ndev = len(disks[diskname]) print 'doing raid setup on %s' % diskname fs = self.machine.current.filesystem print fs pnums = [r.partition for r in self.machine.get_installable_fsmounts(fs)] mdnum = 0 for p in pnums: mdadm = 'mdadm --create /dev/md%d' % mdnum mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev) devices = ['%s%s' % (d, p) for d in disks[diskname]] command = mdadm + ' '.join(devices) print command yesman = 'bash -c "yes | %s"' % command print yesman os.system(yesman) mdnum += 1 print 'doing raid setup on %s' % str(disks[diskname]) mdstat = file('/proc/mdstat').read() while mdstat.find('resync') > -1: sleep(10) mdstat = file('/proc/mdstat').read() def _partition_disk(self, diskname, device): print 'partitioning', diskname, device dump = self.machine.make_partition_dump(diskname, device) i, o = os.popen2('sfdisk %s' % device) i.write(dump) i.close() def extract_basebootstrap(self): self._check_mounted() self._check_installer() runlog('echo extracting premade base tarball') suite_path = self.cfg.get('installer', 'suite_storage') basefile = join(suite_path, '%s.tar' % self.suite) runvalue = runlog('tar -C %s -xf %s' % (self.target, basefile)) if runvalue: raise Error, 'problems extracting %s' % basefile self._bootstrapped = True def bootstrap_target(self): self._check_mounted() self._check_installer() runlog(debootstrap(self.suite, self.target, self.debmirror)) self._bootstrapped = True def _make_generic_devices(self, devices): here = os.getcwd() os.chdir(join(self.target, 'dev')) for dev in devices: runlog('echo making device %s with MAKEDEV' % dev) runlog('./MAKEDEV %s' % dev) os.chdir(here) def _extract_devices_tarball(self): dtball = self.cfg.get('installer', 'devices_tarball') devpath = join(self.target, 'dev') cmd = 'tar -C %s -xf %s' % (devpath, dtball) runvalue = runlog(cmd) if runvalue: raise Error, 'problem extracting devices tarball' def make_disk_devices(self): devices = map(basename, self.machine.get_disk_devices()) self._make_generic_devices(devices) def make_tty_devices(self): self._make_generic_devices(['console']) def make_input_devices(self): self._make_generic_devices(['input']) def make_generic_devices(self): #devices = ['std', 'console', 'pty', 'tap', 'sg', 'input', 'audio'] self._make_generic_devices(['generic']) def ready_base_for_install(self): self._check_bootstrap() self._check_installer() fstab = self.machine.make_fstab() ready_base_for_install(self.target, self.cfg, self.suite, fstab) if self.cfg.is_it_true('installer', 'use_devices_tarball'): runlog('echo extracting devices tarball') self._extract_devices_tarball() else: runlog('echo using MAKEDEV to make devices') self.make_generic_devices() self.make_disk_devices() if self._raid_setup: mdpath = join(self.target, 'etc/mdadm') makepaths(mdpath) mdconfname = join(mdpath, 'mdadm.conf') mdconf = file(mdconfname, 'w') for diskname in self._raid_drives: devices = ['%s*' % d for d in self._raid_drives[diskname]] line = 'DEVICE %s' % ' '.join(devices) mdconf.write(line + '\n') mdconf.close() mdconf = file(mdconfname, 'a') arrdata = commands.getoutput('mdadm -E --config=%s -s' % mdconfname) mdconf.write(arrdata + '\n') mdconf.write('\n') mdconf.close() self._mount_target_proc() def install_to_target(self): os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def post_install(self): print 'post_install' modules = self.machine.get_modules() print 'installing modules', modules setup_modules(self.target, modules) print 'modules installed' kernel = self.machine.current.kernel print 'installing kernel', kernel install_kernel(kernel, self.target) print 'kernel installed' def install(self, machine, target): self.set_machine(machine) if self._enable_bad_hacks: self.setup_disks() else: self.partition_disks() self.make_filesystems() self.setup_installer() self.set_target(target) self.ready_target() if self.cfg.is_it_true('installer', 'bootstrap_target'): self.bootstrap_target() else: self.extract_basebootstrap() self.ready_base_for_install() self.install_to_target() self.post_install()
class 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)
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
from useless.base.path import path from paella.base import PaellaConfig from paella.db import PaellaConnection from paella.db.trait import Trait from paella.db.family import Family from paella.db.profile import Profile from paella.db.machine import MachineHandler from paella.db.installer import InstallerManager from paella.db import DefaultEnvironment from paella.installer.toolkit import InstallerTools if __name__ == '__main__': cfg = PaellaConfig() conn = PaellaConnection() suite = 'bootstrap' t = Trait(conn, suite) f = Family(conn) p = Profile(conn) m = MachineHandler(conn) de = DefaultEnvironment(conn) im = InstallerManager(conn) #os.environ['PAELLA_MACHINE'] = 'testmachine' os.environ['PAELLA_PROFILE'] = 'default' os.environ['PAELLA_TARGET'] = path('/foo/bar') it = InstallerTools()
class NewInstaller(object): def __init__(self, conn, cfg): object.__init__(self) self.conn = conn self.cfg = cfg self.defenv = DefaultEnvironment(self.conn) self.machine = MachineHandler(self.conn) self.cursor = StatementCursor(self.conn) self.target = None self.installer = None self._mounted = None self._bootstrapped = None self.debmirror = self.cfg.get('debrepos', 'http_mirror') self._raid_setup = False self._raid_drives = {} self._enable_bad_hacks = False if self.cfg.is_it_true('installer', 'enable_bad_hacks'): self._enable_bad_hacks = True def set_logfile(self, logfile): env = os.environ if logfile is None: if env.has_key('PAELLA_LOGFILE'): self.logfile = env['PAELLA_LOGFILE'] elif env.has_key('LOGFILE'): self.logfile = env['LOGFILE'] elif self.defenv.has_option('installer', 'default_logfile'): self.logfile = self.defenv.get('installer', 'default_logfile') else: raise InstallSetupError, 'There is no log file defined, giving up.' else: self.logfile = logfile logdir = os.path.dirname(self.logfile) if logdir: makepaths(os.path.dirname(self.logfile)) format = '%(name)s - %(asctime)s - %(levelname)s: %(message)s' self.log = Log('paella-installer', self.logfile, format) def _check_target(self): if not self.target: raise Error, 'no target specified' def _check_installer(self): if not self.installer: raise Error, 'no installer available' def _check_mounted(self): self._check_target() if not self._mounted: raise InstallError, 'target not mounted' def _check_bootstrap(self): self._check_mounted() if not self._bootstrapped: raise Error, 'target not bootstrapped' def set_machine(self, machine): self.machine.set_machine(machine) try: logfile = os.environ['LOGFILE'] except KeyError: logfile = '/paellalog/paella-install-%s.log' % machine os.environ['LOGFILE'] = logfile os.environ['PAELLA_MACHINE'] = machine disklogpath = join(dirname(logfile), 'disklog') if not os.path.isdir(disklogpath): makepaths(disklogpath) self.disklogpath = disklogpath self.curenv = CurrentEnvironment(self.conn, self.machine.current.machine) self.set_logfile(logfile) def check_if_mounted(self, device): mounts = file('/proc/mounts') for line in file: if line.startswith(device): return True return False def unmount_device(self, device): mounted = os.system('umount %s' % device) def make_filesystems(self): device = self.machine.array_hack(self.machine.current.machine_type) mddev = False if device == '/dev/md': mdnum = 0 mddev = True all_fsmounts = self.machine.get_installable_fsmounts() env = CurrentEnvironment(self.conn, self.machine.current.machine) for row in all_fsmounts: if mddev: pdev = '/dev/md%d' % mdnum mdnum += 1 else: pdev = device + str(row.partition) if row.mnt_name in env.keys(): print '%s held' % row.mnt_name elif row.fstype == 'swap': runlog('echo making swap on %s' % pdev) runlog('mkswap %s' % pdev) else: print 'making filesystem for', row.mnt_name make_filesystem(pdev, row.fstype) def set_target(self, target): self.target = target def _pdev(self, device, partition): return device + str(partition) def _mount_target_proc(self): self._check_bootstrap() tproc = join(self.target, 'proc') cmd = 'mount --bind /proc %s' % tproc runvalue = runlog(cmd) if runvalue: raise InstallError, 'problem mounting target /proc at %s' % tproc else: self._proc_mounted = True def _umount_target_proc(self): tproc = join(self.target, 'proc') cmd = 'umount %s' % tproc runvalue = runlog(cmd) if runvalue: raise InstallError, 'problem unmounting target /proc at %s' % tproc else: self._proc_mounted = False def ready_target(self): self._check_target() makepaths(self.target) device = self.machine.array_hack(self.machine.current.machine_type) clause = Eq('filesystem', self.machine.current.filesystem) clause &= Gt('partition', '0') table = 'filesystem_mounts natural join mounts' mounts = self.cursor.select(table=table, clause=clause, order='mnt_point') if mounts[0].mnt_point != '/': raise Error, 'bad set of mounts', mounts mddev = False mdnum = 0 if device == '/dev/md': mddev = True pdev = '/dev/md0' mdnum += 1 else: pdev = self._pdev(device, mounts[0].partition) runlog('echo mounting target %s to %s ' % (pdev, self.target)) clause &= Neq('mnt_point', '/') mounts = self.cursor.select(table=table, clause=clause, order='ord') mountable = [mount for mount in mounts if mount.fstype != 'swap'] runlog('mount %s %s' % (pdev, self.target)) for mnt in mountable: tpath = os.path.join(self.target, mnt.mnt_point[1:]) makepaths(tpath) if mddev: pdev = '/dev/md%d' % mdnum else: pdev = self._pdev(device, mnt.partition) mdnum += 1 runlog('mount %s %s' % (pdev, tpath)) self._mounted = True def setup_installer(self): profile = self.machine.current.profile self.installer = ProfileInstaller(self.conn) self.installer.log = self.log self.installer.set_profile(profile) self.suite = self.installer.suite def organize_disks(self): return self.machine.check_machine_disks( self.machine.current.machine_type) def _setup_disks(self, diskname, disks=None): if disks is None: disks = self.organize_disks() devices = disks[diskname] def setup_disks(self): disks = self.organize_disks() disknames = disks.keys() if not len(disknames): self._setup_disk_fai('default', '/dev/hda') else: if len(disknames) > 1: #this isn't really handled yet self.partition_disks() self.make_filesystems() else: devices = disks[disknames[0]] if len(devices) > 1: #this is a raid setup self.partition_disks() self.make_filesystems() elif len(devices) == 1: self._setup_disk_fai(self.machine.current.filesystem, devices[0]) else: self._setup_disk_fai('default', '/dev/hda') def _setup_disk_fai(self, filesystem, device): disk_config = self.machine.make_disk_config_info(device) fileid, disk_config_path = tempfile.mkstemp('paella', 'diskinfo') disk_config_file = file(disk_config_path, 'w') disk_config_file.write(disk_config) disk_config_file.close() script = '/usr/lib/paella/scripts/setup_harddisks_fai' options = '-X -f %s' % disk_config_path env = 'env LOGDIR=%s diskvar=%s' % (self.disklogpath, join(self.disklogpath, 'diskvar')) command = '%s %s %s' % (env, script, options) runlog(command) def _setup_raid_drives(self, diskname, devices): self._raid_setup = True self._raid_drives[diskname] = devices for device in devices: self._partition_disk(diskname, device) ndev = len(devices) print 'doing raid setup on %s' % diskname fs = self.machine.current.filesystem print fs pnums = [ r.partition for r in self.machine.get_installable_fsmounts(fs) ] mdnum = 0 for p in pnums: mdadm = 'mdadm --create /dev/md%d' % mdnum mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev) devices = ['%s%s' % (d, p) for d in devices] command = mdadm + ' '.join(devices) print command yesman = 'bash -c "yes | %s"' % command print yesman os.system(yesman) mdnum += 1 print 'doing raid setup on %s' % str(devices) mdstat = file('/proc/mdstat').read() while mdstat.find('resync') > -1: sleep(10) mdstat = file('/proc/mdstat').read() def partition_disks(self): disks = self.organize_disks() for diskname in disks: for device in disks[diskname]: self._partition_disk(diskname, device) if len(disks[diskname]) > 1: self._raid_setup = True self._raid_drives[diskname] = disks[diskname] ndev = len(disks[diskname]) print 'doing raid setup on %s' % diskname fs = self.machine.current.filesystem print fs pnums = [ r.partition for r in self.machine.get_installable_fsmounts(fs) ] mdnum = 0 for p in pnums: mdadm = 'mdadm --create /dev/md%d' % mdnum mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev) devices = ['%s%s' % (d, p) for d in disks[diskname]] command = mdadm + ' '.join(devices) print command yesman = 'bash -c "yes | %s"' % command print yesman os.system(yesman) mdnum += 1 print 'doing raid setup on %s' % str(disks[diskname]) mdstat = file('/proc/mdstat').read() while mdstat.find('resync') > -1: sleep(10) mdstat = file('/proc/mdstat').read() def _partition_disk(self, diskname, device): print 'partitioning', diskname, device dump = self.machine.make_partition_dump(diskname, device) i, o = os.popen2('sfdisk %s' % device) i.write(dump) i.close() def extract_basebootstrap(self): self._check_mounted() self._check_installer() runlog('echo extracting premade base tarball') suite_path = self.cfg.get('installer', 'suite_storage') basefile = join(suite_path, '%s.tar' % self.suite) runvalue = runlog('tar -C %s -xf %s' % (self.target, basefile)) if runvalue: raise Error, 'problems extracting %s' % basefile self._bootstrapped = True def bootstrap_target(self): self._check_mounted() self._check_installer() runlog(debootstrap(self.suite, self.target, self.debmirror)) self._bootstrapped = True def _make_generic_devices(self, devices): here = os.getcwd() os.chdir(join(self.target, 'dev')) for dev in devices: runlog('echo making device %s with MAKEDEV' % dev) runlog('./MAKEDEV %s' % dev) os.chdir(here) def _extract_devices_tarball(self): dtball = self.cfg.get('installer', 'devices_tarball') devpath = join(self.target, 'dev') cmd = 'tar -C %s -xf %s' % (devpath, dtball) runvalue = runlog(cmd) if runvalue: raise Error, 'problem extracting devices tarball' def make_disk_devices(self): devices = map(basename, self.machine.get_disk_devices()) self._make_generic_devices(devices) def make_tty_devices(self): self._make_generic_devices(['console']) def make_input_devices(self): self._make_generic_devices(['input']) def make_generic_devices(self): #devices = ['std', 'console', 'pty', 'tap', 'sg', 'input', 'audio'] self._make_generic_devices(['generic']) def ready_base_for_install(self): self._check_bootstrap() self._check_installer() fstab = self.machine.make_fstab() ready_base_for_install(self.target, self.cfg, self.suite, fstab) if self.cfg.is_it_true('installer', 'use_devices_tarball'): runlog('echo extracting devices tarball') self._extract_devices_tarball() else: runlog('echo using MAKEDEV to make devices') self.make_generic_devices() self.make_disk_devices() if self._raid_setup: mdpath = join(self.target, 'etc/mdadm') makepaths(mdpath) mdconfname = join(mdpath, 'mdadm.conf') mdconf = file(mdconfname, 'w') for diskname in self._raid_drives: devices = ['%s*' % d for d in self._raid_drives[diskname]] line = 'DEVICE %s' % ' '.join(devices) mdconf.write(line + '\n') mdconf.close() mdconf = file(mdconfname, 'a') arrdata = commands.getoutput('mdadm -E --config=%s -s' % mdconfname) mdconf.write(arrdata + '\n') mdconf.write('\n') mdconf.close() self._mount_target_proc() def install_to_target(self): os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def post_install(self): print 'post_install' modules = self.machine.get_modules() print 'installing modules', modules setup_modules(self.target, modules) print 'modules installed' kernel = self.machine.current.kernel print 'installing kernel', kernel install_kernel(kernel, self.target) print 'kernel installed' def install(self, machine, target): self.set_machine(machine) if self._enable_bad_hacks: self.setup_disks() else: self.partition_disks() self.make_filesystems() self.setup_installer() self.set_target(target) self.ready_target() if self.cfg.is_it_true('installer', 'bootstrap_target'): self.bootstrap_target() else: self.extract_basebootstrap() self.ready_base_for_install() self.install_to_target() self.post_install()
class 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)
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