def install_kernel_package(package, toolkit=None, target=None, loginfo=loginfo, logerror=logerror): if toolkit is not None: target = toolkit.target if target is None: raise RuntimeError , "No target specified." target = path(target) chroot_precommand = ['chroot', str(target)] aptinstall = ['aptitude', '--assume-yes', 'install'] cmd = chroot_precommand + aptinstall + [package] loginfo('install command is: %s' % ' '.join(cmd)) kimgconf = target / 'etc' / 'kernel-img.conf' kimgconf_old = path('%s.paella-orig' % kimgconf) kimgconflines = ['do_bootloader = No', 'do_initrd = Yes', 'warn_initrd = No' ] if kimgconf.exists(): loginfo('/etc/kernel-img.conf already exists') k = '/etc/kernel-img.conf' msg ='renaming %s to %s.paella-orig' % (k, k) loginfo(msg) if kimgconf_old.exists(): msg = '%s already exists, aborting install.' % kimgconf_old logerror(msg) raise RuntimeError , msg os.rename(kimgconf, kimgconf_old) kimgconf.write_lines(kimgconflines) subprocess.check_call(cmd) loginfo('Kernel installation is complete.') if kimgconf_old.exists(): loginfo('Restoring /etc/kernel-img.conf') os.remove(kimgconf) os.rename(kimgconf_old, kimgconf)
def _filename(self, sequence, filename=None): if filename is None: filename = self.orig_filename else: filename = path(filename) seqname = "%s.%d" % (filename, sequence) return path(seqname)
def _setup_standard_directories(self): self._std_dirs = KStandardDirs() self.tmpdir_parent = path(str(self._std_dirs.findResourceDir('tmp', '/'))) self.datadir_parent = path(str(self._std_dirs.findResourceDir('data', '/'))) self.tmpdir = self.tmpdir_parent / 'utguests' self.datadir = self.datadir_parent / 'utguests' # we need this in dosbox object (for now) self.main_config_dir = self.datadir if not os.path.exists(self.datadir): os.mkdir(self.datadir)
def export_profile(self, profile, dirname=None): if dirname is None: dirname = path('.') dirname = path(dirname) makepaths(dirname) # this env object should be handled # inside the profile object instead # of being handled here. env = self.profile.make_environment_object() env.set_profile(profile) self.profile.export_profile(dirname, profile=profile, env=env)
def extract_base_tarball(self): suite = self.suitecursor.get_base_suite(self._suite) fstype = self.cfg.get('umlmachines', 'backup_filesystem') if fstype == 'hostfs': #backup_path = path(self.cfg.get('umlmachines', 'hostfs_backup_path')).expand() backup_path = path(self.options['hostfs_backup_path'].value) else: backup_path = path('/mnt') basetarball = backup_path / path('%s.base.tar.gz' % suite) if not basetarball.isfile(): basetarball = backup_path / path('%s.base.tar' % suite) if basetarball.isfile(): extract_tarball(self.target, basetarball) else: raise RuntimeError, 'No base tarball found for suite %s' % suite
def import_all_aptkeys(self, dirname=None): if dirname is None: dirname = self.main_path / 'aptkeys' dirname = path(dirname) files = [f for f in dirname.listdir() if f.isfile() and f.endswith('.gpg')] for filename in files: self.import_aptkey(filename)
def __init__(self): object.__init__(self) self.cfg = PaellaConfig() self.conn = InstallerConnection() self.profile = os.environ['PAELLA_PROFILE'] self.target = path(os.environ['PAELLA_TARGET']) self.machine = None self.trait = None self.suite = get_suite(self.conn, self.profile) self.db = ToolkitDatabase(self.conn) self.db.set_profile(self.profile) self.traits = self.db.profile.make_traitlist() profile_families = self.db.profile.get_families() self.families = list(self.db.family.get_related_families(profile_families)) self.default = DefaultEnvironment(self.conn) if os.environ.has_key('PAELLA_MACHINE'): self.machine = os.environ['PAELLA_MACHINE'] self.db.set_machine(self.machine) # we need to make an installer to do # some of the installer functions. self.installer = None if os.environ.has_key('PAELLA_TRAIT'): self.set_trait(os.environ['PAELLA_TRAIT'])
def install_kernel_package(self): self.log.info('called install_kernel_package') extra_modules = self.determine_extra_modules_from_diskconfig() if extra_modules: self.log.info('Checking if extra packages are required before kernel install.') self.install_packages_for_extra_modules(extra_modules) kernel = self.machine.get_kernel() cmd = self.chroot_precommand + self.aptinstall + [kernel] self.log.info('install cmd is: %s' % ' '.join(cmd)) kimgconf = self.target / 'etc' / 'kernel-img.conf' kimgconf_old = path('%s.paella-orig' % kimgconf) kimgconflines = ['do_bootloader = No', 'do_initrd = Yes', 'warn_initrd = No' ] if kimgconf.exists(): self.log.info('/etc/kernel-img.conf already exists') k = '/etc/kernel-img.conf' msg ='renaming %s to %s.paella-orig' % (k, k) self.log.info(msg) if kimgconf_old.exists(): raise RuntimeError , '%s already exists, aborting install.' % kimgconf_old os.rename(kimgconf, kimgconf_old) kimgconf.write_lines(kimgconflines) runlog(cmd) self.log.info('Kernel installation is complete.') if kimgconf_old.exists(): self.log.info('Restoring /etc/kernel-img.conf') os.remove(kimgconf) os.rename(kimgconf_old, kimgconf)
def __init__(self, conn, suite, target): # target should already be a path object self.target = path(target) self.trait = None # setup relation objects self.traitpackage = TraitPackage(conn, suite) self.traittemplate = TraitTemplate(conn, suite) self.traitscripts = TraitScript(conn, suite) # setup empty variable containers self.profiledata = {} self.machine_data = {} self.familydata = {} # It's odd, but running the same # code for setting debconf selections # returns a 1 on the preseed process, yet # returns a 0 when it's done during # the templates process. # -- I found the problem, debconf reports # an error if the question doesn't exist # yet. # This attribute helps keep track of the # problem, and will run the debconf # selections during the templates # process, if the value is True. # I don't really like this, but it seems # to work for now, so I'm going to leave # it as is, and come up with a better # solution later. self.debconf_problem = False
def __init__(self): object.__init__(self) self.cfg = PaellaConfig() self.conn = InstallerConnection() self.profile = os.environ['PAELLA_PROFILE'] self.target = path(os.environ['PAELLA_TARGET']) self.machine = None self.trait = None self.suite = get_suite(self.conn, self.profile) self.db = ToolkitDatabase(self.conn) self.db.set_profile(self.profile) self.traits = self.db.profile.make_traitlist() profile_families = self.db.profile.get_families() self.families = list( self.db.family.get_related_families(profile_families)) self.default = DefaultEnvironment(self.conn) if os.environ.has_key('PAELLA_MACHINE'): self.machine = os.environ['PAELLA_MACHINE'] self.db.set_machine(self.machine) # we need to make an installer to do # some of the installer functions. self.installer = None if os.environ.has_key('PAELLA_TRAIT'): self.set_trait(os.environ['PAELLA_TRAIT'])
def decode_base64_templates(toolkit, trait=None, suffix='.b64', removefiles=True, verbose=False): it = toolkit current_trait = it.trait if trait is not None: if verbose: print "Setting trait to %s" % trait it.set_trait(trait) templates = it.db.trait.templates() b64_templates = [t for t in templates if t.endswith(suffix)] if verbose: print "base64 templates: %s" % b64_templates for template in b64_templates: if verbose: print "decoding %s" % template filename = it.target / template encoded_data = filename.bytes() decoded_data = base64.b64decode(encoded_data) truncate_position = -len(suffix) new_filename = path(filename[:truncate_position]) new_filename.write_bytes(decoded_data) if verbose: print "Created %s" % new_filename if removefiles: if verbose: print "Removing %s" % filename filename.remove() # set the trait back it.set_trait(current_trait)
def __init__(self, parent, logfile, name='LogBrowser'): BaseLogBrowser.__init__(self, parent, name=name) self.logfilename = path(logfile) if not self.logfilename.exists(): shell('touch %s' % self.logfilename) self.logfile_size = 0 self.setVScrollBarMode(self.AlwaysOff)
def export_profile(self, dirname, profile=None, env=None): element = self.generate_xml(profile=profile, env=env) if profile is None: profile = self.current.profile filename = path(dirname) / ('%s.xml' % profile) element.writexml(filename.open('w'), indent='\t', newl='\n', addindent='\t')
def export_db_element(self, dirname=None, filename="database.xml"): if dirname is None: dirname = self.db_export_path filename = path(dirname) / filename dbfile = filename.open("w") self.dbelement.writexml(dbfile, indent="\t", newl="\n", addindent="\t") dbfile.close()
def __init__(self): object.__init__(self) self.cfg = PaellaConfig() self.conn = InstallerConnection() self.profile = os.environ['PAELLA_PROFILE'] self.target = path(os.environ['PAELLA_TARGET']) self.machine = None self.trait = None self.suite = get_suite(self.conn, self.profile) self.pr = Profile(self.conn) self.pr.set_profile(self.profile) self.traitlist = self.pr.make_traitlist() self.pe = ProfileEnvironment(self.conn, self.profile) self.tp = TraitParent(self.conn, self.suite) self.fm = Family(self.conn) self.tr = Trait(self.conn, self.suite) self.families = list( self.fm.get_related_families(self.pr.get_families())) self._envv = None self.default = DefaultEnvironment(self.conn) #self.installer = TraitInstaller(self.conn, self.suite) self.installer = ProfileInstaller(self.conn) self.installer.set_logfile() self.installer.set_profile(self.profile) self.installer.set_target(self.target) if os.environ.has_key('PAELLA_MACHINE'): self.machine = os.environ['PAELLA_MACHINE'] if os.environ.has_key('PAELLA_TRAIT'): self.set_trait(os.environ['PAELLA_TRAIT'])
def _bootstrap_with_tarball(self, suite): self.check_target_exists() suite_path = path(self.defenv.get('installer', 'suite_storage')) arch = get_architecture() filename = '%s-%s.tar.gz' % (suite, arch) basefile = suite_path / filename taropts = '-xzf' # we normally expect a tar.gz # but we'll check for a plain tar also if not basefile.exists(): filename = '%s-%s.tar' % (suite, arch) basefile = suite_path / filename taropts = '-xf' if not basefile.exists(): # We don't really want to ruin an install # by not having a tarball, so we log a warning # and proceed with a debootstrap. msg = "base tarball not found, reverting to debootstrap" self.log.warn(msg) self._bootstrap_with_debootstrap(suite) else: #cmd = 'tar -C %s %s %s' % (self.target, taropts, basefile) cmd = ['tar', '-C', str(self.target), taropts, str(basefile)] # if cmd returns nonzero, runlog will raise an error runlog(cmd)
def import_machines(self, machines, dirname): dirname = path(dirname) current_machine = self.current_machine # make a queue for the machines machine_queue = [machine for machine in machines] # I hope this is correct. This is an # attempt to keep this function from # running in an infinite loop. num_machines = len(machine_queue) max_loops = (num_machines * (num_machines +1) ) / 2 count = 0 while machine_queue: machine = machine_queue.pop(0) machine_dir = dirname / machine try: self.import_machine(machine_dir) except UnbornError: print "The parent of machine %s hasn't been imported yet." % machine machine_queue.append(machine) count +=1 if count > max_loops: msg = "We appear to be in an infinite loop.\n" msg += "It's likely that there are unmet dependencies" msg += " in your list of machines." raise RuntimeError , msg if current_machine is not None: self.set_machine(current_machine)
def import_machine(self, dirname): dirname = path(dirname) current_machine = self.current_machine parser = self._parse_machine_xml(dirname) machine = parser.machine imported_machines = self.get_machine_list() if machine.parent is not None: if machine.parent not in imported_machines: raise UnbornError, "%s not imported yet." % machine.parent self.make_a_machine(machine.name) self.set_machine(machine.name) # attributes - these will fail with foreign key # errors if they're not present in the database self.set_profile(machine.profile) self.set_kernel(machine.kernel) self.set_diskconfig(machine.diskconfig) if machine.parent is not None: self.set_parent(machine.parent) for family in machine.families: print "import family", family self.relation.family.append_family(family) for scriptname in machine.scripts: script_filename ='script-%s' % scriptname script_filename = dirname / script_filename print "import script", scriptname, script_filename self.relation.scripts.insert_script(scriptname, file(script_filename)) for trait, name, value in machine.variables: print "import machine_variable -> %s" % str(tuple((trait, name, value))) self.relation.environment.append_variable(trait, name, value) # all done, set machine back to what it was, # unless it wasn't set in the first place, then # it remains set to what was just imported if current_machine is not None: self.set_machine(current_machine)
def export_kernels(self, exportdir): element = KernelsElement(self.conn) exportdir = path(exportdir) filename = exportdir / 'kernels.xml' xmlfile = file(filename, 'w') xmlfile.write(element.toprettyxml()) xmlfile.close()
def install_kernel_package(self): self.log.info('called install_kernel_package') kernel = self.machine.current.kernel cmd = self.chroot_precommand + self.aptinstall + [kernel] self.log.info('install cmd is: %s' % ' '.join(cmd)) kimgconf = self.target / 'etc' / 'kernel-img.conf' kimgconf_old = path('%s.paella-orig' % kimgconf) kimgconflines = ['do_bootloader = No', 'do_initrd = Yes', 'warn_initrd = No' ] if kimgconf.exists(): self.log.info('/etc/kernel-img.conf already exists') k = '/etc/kernel-img.conf' msg ='renaming %s to %s.paella-orig' % (k, k) self.log.info(msg) if kimgconf_old.exists(): raise RuntimeError, '%s already exists, aborting install.' % kimgconf_old os.rename(kimgconf, kimgconf_old) kimgconf.write_lines(kimgconflines) runlog(cmd) self.log.info('Kernel installation is complete.') if kimgconf_old.exists(): self.log.info('Restoring /etc/kernel-img.conf') os.remove(kimgconf) os.rename(kimgconf_old, kimgconf)
def __init__(self, conn=None, cfg=None): self.conn = conn UmlChroot.__init__(self, cfg=cfg) self.options['paella_action'] = 'install' paellarc = path(self.cfg['paellarc']).expand() self.paellarc = PaellaConfig(files=[paellarc]) self.options['paellarc'] = paellarc
def _bootstrap_with_tarball(self, suite): self.check_target_exists() suite_path = path(self.defenv.get('installer', 'suite_storage')) filename = '%s.tar.gz' % suite basefile = suite_path / filename taropts = '-xzf' # we normally expect a tar.gz # but we'll check for a plain tar also if not basefile.exists(): filename = '%s.tar' % suite basefile = suite_path / filename taropts = '-xf' if not basefile.exists(): # We don't really want to ruin an install # by not having a tarball, so we log a warning # and proceed with a debootstrap. msg = "base tarball not found, reverting to debootstrap" self.log.warn(msg) self._bootstrap_with_debootstrap(suite) else: #cmd = 'tar -C %s %s %s' % (self.target, taropts, basefile) cmd = ['tar', '-C', str(self.target), taropts, str(basefile)] # if cmd returns nonzero, runlog will raise an error runlog(cmd) # we need to do certain things after extraction # that debootstrap does for us, # like copy /etc/resolv.conf to the target. # these things should be done in the # ready_base_for_install process self._bootstrapped = True
def install_template(self, template, text): target_filename = self.target / template.template makepaths(target_filename.dirname()) if target_filename.isfile(): backup_filename = self.target / path('root/paella') / template.template if not backup_filename.isfile(): makepaths(backup_filename.dirname()) target_filename.copy(backup_filename) target_filename.write_bytes(text) mode = template.mode # a simple attempt to insure mode is a valid octal string # this is one of the very rare places eval is used # there are a few strings with 8's and 9's that will pass # the if statement, but the eval will raise SyntaxError then. # If the mode is unusable the install will fail at this point. if mode[0] == '0' and len(mode) <= 7 and mode.isdigit(): mode = eval(mode) target_filename.chmod(mode) else: raise InstallError, 'bad mode %s, please use octal prefixed by 0' % mode own = ':'.join([template.owner, template.grp_owner]) # This command is run in a chroot to make the correct uid, gid os.system(self.command('chown', "%s '%s'" %(own, join('/', template.template))))
def __init__(self, filename): self.count = 0 self.orig_filename = path(filename) # set this to False to keep from # creating empty log file after rotation self.make_empty = True
def decode_base64_templates(toolkit, trait=None, suffix='.b64', removefiles=True, verbose=False): it = toolkit current_trait = it.trait if trait is not None: if verbose: print "Setting trait to %s" % trait it.set_trait(trait) templates = it.db.trait.templates() b64_templates = [t for t in templates if t.endswith(suffix)] if verbose: print "base64 templates: %s" % b64_templates for template in b64_templates: if verbose: print "decoding %s" % template filename = it.target / template encoded_data = filename.bytes() decoded_data = base64.b64decode(encoded_data) truncate_position = - len(suffix) new_filename = path(filename[:truncate_position]) new_filename.write_bytes(decoded_data) if verbose: print "Created %s" % new_filename if removefiles: if verbose: print "Removing %s" % filename filename.remove() # set the trait back it.set_trait(current_trait)
def _select_import_export_directory(self, action): default_path = path(self.app.cfg.get('database', 'default_path')).expand() win = KDirSelectDialog(default_path, False, self) win.connect(win, SIGNAL('okClicked()'), self._import_export_directory_selected) win.db_action = action win.show() self._import_export_dirsel_dialog = win
def install_template(self, template, text): target_filename = self.target / template.template makepaths(target_filename.dirname()) if target_filename.isfile(): backup_filename = self.target / path( 'root/paella') / template.template if not backup_filename.isfile(): makepaths(backup_filename.dirname()) target_filename.copy(backup_filename) target_filename.write_bytes(text) mode = template.mode # a simple attempt to insure mode is a valid octal string # this is one of the very rare places eval is used # there are a few strings with 8's and 9's that will pass # the if statement, but the eval will raise SyntaxError then. # If the mode is unusable the install will fail at this point. if mode[0] == '0' and len(mode) <= 7 and mode.isdigit(): mode = eval(mode) target_filename.chmod(mode) else: raise InstallError, 'bad mode %s, please use octal prefixed by 0' % mode own = ':'.join([template.owner, template.grp_owner]) # This command is run in a chroot to make the correct uid, gid os.system( self.command('chown', "%s '%s'" % (own, join('/', template.template))))
def export_db_element(self, dirname=None, filename='database.xml'): if dirname is None: dirname = self.db_export_path filename = path(dirname) / filename dbfile = filename.open('w') self.dbelement.writexml(dbfile, indent='\t', newl='\n', addindent='\t') dbfile.close()
def __init__(self): object.__init__(self) self.cfg = PaellaConfig() self.conn = InstallerConnection() self.profile = os.environ["PAELLA_PROFILE"] self.target = path(os.environ["PAELLA_TARGET"]) self.machine = None self.trait = None self.suite = get_suite(self.conn, self.profile) self.pr = Profile(self.conn) self.pr.set_profile(self.profile) self.traitlist = self.pr.make_traitlist() self.pe = ProfileEnvironment(self.conn, self.profile) self.tp = TraitParent(self.conn, self.suite) self.fm = Family(self.conn) self.tr = Trait(self.conn, self.suite) self.families = list(self.fm.get_related_families(self.pr.get_families())) self._envv = None self.default = DefaultEnvironment(self.conn) # self.installer = TraitInstaller(self.conn, self.suite) self.installer = ProfileInstaller(self.conn) self.installer.set_logfile() self.installer.set_profile(self.profile) self.installer.set_target(self.target) if os.environ.has_key("PAELLA_MACHINE"): self.machine = os.environ["PAELLA_MACHINE"] if os.environ.has_key("PAELLA_TRAIT"): self.set_trait(os.environ["PAELLA_TRAIT"])
def export_machine(self, exportdir): self._check_machine_set() element = MachineElement(self.conn, self.current_machine) exportdir = path(exportdir) element.export(exportdir) subdir = element.export_directory(exportdir) self.relation.scripts.export_scripts(subdir)
def __init__(self, parent, logfile, name='LogBrowser'): BaseLogBrowser.__init__(self, parent, name=name) self.logfilename = path(logfile) if not self.logfilename.exists(): file(self.logfilename, 'w').close() self.logfile_size = 0 self.setVScrollBarMode(self.AlwaysOff)
def import_diskconfig(self, filename): filename = path(filename).abspath() basename = filename.basename() name = basename.split('.')[0] cursor = self.conn.cursor(statement=True) content = file(filename).read() data = dict(name=name, content=content) cursor.insert(table='diskconfig', data=data)
def __init__(self, conn): self.cfg = PaellaConfig() self.conn = conn default_path = path(self.cfg.get('database', 'default_path')).expand() self.import_dir = default_path self.export_dir = default_path self.exporter = PaellaExporter(self.conn) self.importer = PaellaImporter(self.conn)
def __init__(self, app): self.app = app # we need a config file for this # or a config table in the database self.main_path = path('~/toolbox').expand() if not self.main_path.exists(): self.main_path.mkdir() self.jobs = {}
def import_all_profiles(self, dirname=None): if dirname is None: dirname = self.main_path / 'profiles' dirname = path(dirname) xmlfiles = dirname.listdir('*.xml') self.report_total_profiles(len(xmlfiles)) for xmlfile in xmlfiles: self.profile.import_profile(xmlfile) self.report_profile_imported(xmlfile.namebase)
def backup_target_hostfs(self, name): self.mount_backup('/mnt', 'hostfs') #bkup_path = path(self.cfg.get('umlmachines', 'hostfs_backup_path')).expand() bkup_path = path(self.options['hostfs_backup_path'].value) while bkup_path.startswith('/'): bkup_path = bkup_path[1:] mnt = path('/mnt') tarname = mnt / bkup_path / path('%s.tar' % name) #tarname = os.path.join('/mnt', bkup_path, name) + '.tar' #dirname = os.path.dirname(tarname) dirname = tarname.dirname() if not dirname.isdir(): print dirname, "doesn't exist. Creating now." makepaths(dirname) tarcmd = backup_target_command(self.target, tarname) print 'tarcmd is', tarcmd shell(tarcmd) shell('umount /mnt')
def ready_base_for_install(target, conn, suite, fstabobj): deprecated('ready_base_for_install appears to be deprecated') set_root_passwd(target, myline) make_sources_list(conn, target, suite) make_interfaces_simple(target) make_fstab(fstabobj, target) target = path(target) resolvconf = file('/etc/resolv.conf').read() target_resolvconf = target / 'etc' / 'resolv.conf' target_resolvconf.write(resolvconf)
def export_aptkey(self, name=None, dirname=None, row=None): dirname = path(dirname) makepaths(dirname) if name is None and row is None: raise RuntimeError, "need to set either row or name" if row is None: row = self.aptkeys.get_row(name) basename = '%s.gpg' % row.name filename = dirname / basename filename.write_text(row.data)
def export_machine(self, machine, dirname=None): if dirname is None: dirname = self.db_export_path dirname = path(dirname) makepaths(dirname) current_machine = self.machines.current_machine self.machines.set_machine(machine) self.machines.export_machine(dirname) if current_machine is not None: self.machines.set_machine(current_machine)
def export_machine_database(self, exportdir): element = MachineDatabaseElement(self.conn) exportdir = path(exportdir) makepaths(exportdir) filename = exportdir / 'machine_database.xml' xmlfile = file(filename, 'w') xmlfile.write(element.toprettyxml()) xmlfile.close() machine_dir = exportdir / 'machines' self.export_all_machines(machine_dir)
def import_all_diskconfigs(self, dirname=None): if dirname is None: dirname = self.main_path / 'diskconfig' dirname = path(dirname) files = [afile for afile in dirname.listdir() if afile.isfile()] cursor = self.conn.cursor(statement=True) for diskconfig in files: name = diskconfig.basename() data = dict(name=name, content=file(diskconfig).read()) cursor.insert(table='diskconfig', data=data)