def remove_client(self, client): profiles, families, traits = self._client_schema(client) disks, mtypes, machines = self._client_mdata(client) cursor = StatementCursor(self.conn) if machines: cursor.delete(table='machines', clause=In('machine', machines)) for mtype in mtypes: cursor.execute("select * from delete_mtype('%s')" % mtype) for disk in disks: cursor.execute("select * from delete_disk('%s')" % disk) for profile in profiles: cursor.execute("select * from delete_profile('%s')" % profile) for family in families: cursor.execute("select * from delete_family('%s')" % family)
class VariablesConfig(Configuration): def __init__(self, conn, table, section, mainfield=None, mainvalue=None, option='name', value='value'): self.conn = conn self.cursor = StatementCursor(self.conn) self.cursor.set_table(table) self._secfield = section bothnone = mainfield is None and mainvalue is None bothset = mainfield and mainvalue if not bothnone and not bothset: raise Error, 'both mainfield and mainvalue need to be set/unset' self._mainclause = None if bothset: self._mainclause = Eq(mainfield, mainvalue) self._fields = [self._secfield, option, value] Configuration.__init__(self) for row in self.cursor.select(fields=self._fields, clause=self._mainclause): if row[0] not in self.sections(): self.add_section(row[0]) self.set(*row) def write(self, cfile): sections = self.sections() sections.sort() for section in sections: cfile.write('[%s]\n' % section) keys = self.options(section) keys.sort() for k in keys: if k != '__name__': v = str(self.get(section, k, raw=True)).replace('\n', '\n\t') cfile.write('%s:\t%s\n' % (k, v)) cfile.write('\n') def edit(self): tmp, path = tempfile.mkstemp('variables', 'config') tmp = file(path, 'w') self.write(tmp) tmp.close() os.system('$EDITOR %s' % path) tmp = file(path, 'r') newconfig = Configuration() newconfig.readfp(tmp) tmp.close() os.remove(path) return newconfig def diff(self, other): ltmp, lpath = tempfile.mkstemp('variables', 'config') ltmp = file(lpath, 'w') self.write(ltmp) ltmp.close() rtmp, rpath = tempfile.mkstemp('variables', 'config') rtmp = file(rpath, 'w') other.write(rtmp) rtmp.close() os.system('xxdiff %s %s' % (lpath, rpath)) ltmp, rtmp = file(lpath, 'r'), file(rpath, 'r') lcfg, rcfg = ConfigParser(), ConfigParser() lcfg.readfp(ltmp) rcfg.readfp(rtmp) ltmp.close() rtmp.close() self.update(lcfg) other.update(rcfg) def update(self, newconfig): removed = [x for x in self.sections() if x not in newconfig.sections()] for section in removed: print 'removing', section sclause = Eq(self._secfield, section) if self._mainclause: sclause &= self._mainclause self.cursor.delete(clause=sclause) for section in newconfig.sections(): print section sclause = Eq(self._secfield, section) if self._mainclause: sclause = self._mainclause & Eq(self._secfield, section) if not self.has_section(section): for k,v in newconfig.items(section): idata = dict(zip(self._fields, [section, k, v])) if self._mainclause: idata[self._mainclause.left] = self._mainclause.right print idata self.cursor.insert(data=idata) else: for name, value in newconfig.items(section): nclause = sclause & Eq(self._fields[1], name) #print 'nclause', nclause #print 'oldvalue', self.get(section, name) if self.has_option(section, name): oldvalue = self.get(section, name) if value != oldvalue: print 'updating', name, oldvalue, 'to', value self.cursor.update(data={self._fields[2] : value}, clause=nclause) #print self.cursor.select(clause=nclause) else: idata = dict(zip(self._fields, [section, name, value])) if self._mainclause: idata[self._mainclause.left] = self._mainclause.right self.cursor.insert(data=idata) if self.has_section(section): for name, value in self.items(section): if not newconfig.has_option(section, name): clause = sclause & Eq(self._fields[1], name) #print 'dclause', clause self.cursor.delete(clause=clause)
class Family(object): def __init__(self, conn): object.__init__(self) self.conn = conn self.cursor = StatementCursor(self.conn) self.current = None self.parent = SimpleRelation(self.conn, 'family_parent', 'family') self.env = FamilyEnvironment(self.conn) def set_family(self, family): self.current = family self.parent.set_current(family) self.env.set_family(family) def _check_family(self, family): if family is not None: return family else: family = self.current if family is None: raise Error, 'either pass a family argument or call set_family on this object' return family def get_related_families(self, families=[]): rows = self.cursor.select(table='family_parent') graph = kjGraph([(r.family, r.parent) for r in rows]) dfamilies = Set() for fam in families: dfamilies |= Set([fam]) | Set(graph.reachable(fam).items()) return dfamilies def parent_rows(self, family=None): family = self._check_family(family) self.parent.set_clause(family) rows = self.parent.cmd.select(fields=['parent'], order='parent') self.parent.reset_clause() return rows def parents(self, family=None): family = self._check_family(family) rows = self.parent_rows(family) return [x.parent for x in rows] def environment_rows(self, family=None): family = self._check_family(family) clause = Eq('family', family) args = dict(fields=['trait', 'name', 'value'], clause=clause, order=['trait', 'name']) return self.env.cursor.select(**args) def family_rows(self): return self.cursor.select(fields=['family'], table='families', order='family') def all_families(self): return [r.family for r in self.family_rows()] def get_all_defaults(self): suite_cursor = SuiteCursor(self.conn) suites = suite_cursor.get_suites() stmt = select_multisuite_union(suites, 'variables') print stmt self.cursor.execute(stmt) return self.cursor.fetchall() def create_family(self, family): if family not in self.all_families(): self.cursor.insert(table='families', data=dict(family=family)) else: raise ExistsError, '%s already exists' % family def delete_family(self, family=None): family = self._check_family(family) self.cursor.execute("select * from delete_family('%s')" % family) def insert_parents(self, parents, family=None): family = self._check_family(family) self.parent.insert('parent', parents) def delete_parents(self, parents=[], family=None): family = self._check_family(family) if not parents: parents = self.parents() if not parents: return table= 'family_parent' clause = Eq('family', family) & In('parent', parents) self.cursor.delete(table=table, clause=clause) def FamilyData(self, families=[]): # change sep here sep = PAELLA_TRAIT_NAME_SEP # we don't know what to do here # it is possible to have an empty # list of families, and if that's the # case we don't need to make the # list of [self.current] . I need to look # for everywhere this method is called. # In the installer, the family is never set, # and we use the list of families provided # by the profile and the machine. In this # case, the families argument will always # be a list, empty or not. # I can't think of any other circumstance # where this method would be called outside # of the installer, or a script, and the script # should be using either a profile or machine # to get the list of families anyway, make the # point moot. I will probably remove this part # of the code in the near future, once I'm sure # that there's no reason to pass None to the # families argument. if families is None: families = [self.current] all = self.make_familylist(families) superdict = {} for f in all: superdict.update(self.env.make_tagdict(f, sep=sep)) return superdict def make_familylist(self, families): deps = families all = list(self.get_related_families(families)) setfun = self.set_family parfun = self.parents return make_deplist(deps, all, setfun, parfun) def export_family(self, family=None): if family is None: family = self.current # row isn't used, except to determine that the family exists row = self.cursor.select_row(table='families', clause=Eq('family', family)) element = FamilyElement(family) element.append_parents(self.parents(family)) element.append_variables(self.environment_rows(family)) return element def write_family(self, family, path): fxml = file(join(path, '%s.xml' % family), 'w') data = self.export_family(family) data.writexml(fxml, indent='\t', newl='\n', addindent='\t') fxml.close() def export_families(self, path): families = self.all_families() self.report_total_families(len(families)) for f in families: self.write_family(f, path) self.report_family_exported(f, path) def import_family(self, element): parsed = FamilyParser(element) print 'inserting family', parsed.name all = self.all_families() for p in parsed.parents: if p not in all: print 'insertion failed for', parsed.name raise UnbornError self.create_family(parsed.name) self.set_family(parsed.name) self.insert_parents(parsed.parents) row = dict(family=parsed.name) for var in parsed.environ: row.update(var) self.cursor.insert(table='family_environment', data=row) def _import_family_xml(self, xmlfile): xml = parse_file(xmlfile) elements = xml.getElementsByTagName('family') if len(elements) != 1: raise Error, 'bad number of family tags %s' % len(elements) element = elements[0] return element def import_family_xml(self, xmlfile): element = self._import_family_xml(xmlfile) self.import_family(element) def import_families(self, path): xmlfiles = [join(path, x) for x in os.listdir(path) if x[-4:] == '.xml'] families = [] for f in xmlfiles: element = self._import_family_xml(f) families.append(element) while len(families): f = families[0] try: self.import_family(f) except UnbornError: families.append(f) del families[0] print len(families), 'families inserted' def getVariablesConfig(self, family=None): family = self._check_family(family) return FamilyVariablesConfig(self.conn, family) def deleteVariable(self, trait, name, family=None): family = self._check_family(family) data = dict(family=family, trait=trait, name=name) clause = reduce(and_, [Eq(k, v) for k,v in data.items()]) self.env.cursor.delete(clause=clause) def insertVariable(self, trait, name, value, family=None): family = self._check_family(family) data = dict(family=family, trait=trait, name=name) clause = reduce(and_, [Eq(k, v) for k,v in data.items()]) testrows = self.cursor.select(table='family_environment', clause=clause) if not len(testrows): data['value'] = value self.cursor.insert(table='family_environment', data=data) def report_family_exported(self, family, path): print 'family %s exported to %s' % (family, path) def report_total_families(self, total): print 'exporting %d families' % total
class ProfileBrowser(ListNoteBook, HasDialogs): def __init__(self, conn, suites, name='ProfileBrowser'): self.menu = self.__make_mainmenu_(suites) ListNoteBook.__init__(self, name=name) self.conn = conn self.profiles = Profile(self.conn) self.profiletrait = ProfileTrait(self.conn) self.family = Family(self.conn) self.pfamily = StatementCursor(self.conn) self.pfamily.set_table('profile_family') self.trait_menu = make_menu(['drop', 'order'], self.trait_command) self.pdata_menu = make_menu(['edit', 'drop'], self.variable_command) self.family_menu = make_menu(['drop'], self.family_command) self.reset_rows() self.append_page(ScrollCList(rcmenu=self.trait_menu), 'traits') self.append_page(ScrollCList(rcmenu=self.pdata_menu), 'variables') self.append_page(ScrollCList(rcmenu=self.family_menu), 'families') self.dialogs = {}.fromkeys(['order']) def __make_mainmenu_(self, suites): suite_commands = ['change to %s' % suite for suite in suites] profile_commands = ['drop', 'set defaults', 'append defaults'] commands = suite_commands + profile_commands return make_menu(commands, self.profile_command) def reset_rows(self): self.set_rows( self.profiles.select(fields=['profile', 'suite'], order='profile')) self.set_row_select(self.profile_selected) def profile_selected(self, listbox, row, column, event): row = listbox.get_selected_data()[0] self.current = row self.select_profile(self.current.profile) def select_profile(self, profile): self.variables = ProfileEnvironment(self.conn, profile) self.profiletrait.set_profile(profile) self.__set_pages(profile) def __set_pages(self, profile): pages = dict(self.pages) #set traits for profile pages['traits'].set_rows(self.profiletrait.trait_rows()) pages['traits'].set_select_mode('multi') clause = Eq('profile', self.current.profile) cursor = self.variables.env.cursor pages['variables'].set_rows(cursor.select(clause=clause), ['trait']) pages['variables'].set_select_mode('multi') pfrows = self.pfamily.select(fields=['family'], clause=clause) pages['families'].set_rows(pfrows) pages['families'].set_select_mode('multi') self.__set_droptargets__(pages) def __set_droptargets__(self, pages): set_receive_targets(pages['traits'].listbox, self.drop_trait, TARGETS.get('trait', self.current.suite)) set_receive_targets(pages['families'].listbox, self.drop_families, FTargets.get('family', 'flavor')) def trait_command(self, menuitem, action): traits = self._get_listbox('traits', 'trait') if action == 'drop': clause = In('trait', traits) & Eq('profile', self.current.profile) self.profiletrait.cmd.delete(clause=clause) self.__set_pages(self.current.profile) elif action == 'order': if not self.dialogs['order']: self.dialogs['order'] = dialogs.Entry('enter order', name='order') self.dialogs['order'].set_ok(self.set_order) self.dialogs['order'].set_cancel(self.destroy_dialog) def variable_command(self, menuitem, action): rows = self.pages['variables'].get_selected_data() cursor = self.variables.env.cursor if action == 'drop': for row in rows: clause = Eq('profile', self.current.profile) & Eq( 'trait', row.trait) clause &= Eq('name', row.name) cursor.delete(clause=clause) elif action == 'edit': self.edit_profilevars() def family_command(self, menuitem, action): print action families = [x[0] for x in self.pages['families'].get_selected_data()] if action == 'drop': clause = Eq('profile', self.current.profile) & In( 'family', families) self.pfamily.delete(clause=clause) def edit_profilevars(self): config = ProfileVariablesConfig(self.conn, self.current.profile) newconfig = config.edit() config.update(newconfig) self.select_profile(self.current.profile) def set_order(self, button): dialog = self.dialogs['order'] ord = dialog.get() rows = self.pages['traits'].get_selected_data() pclause = Eq('profile', self.current.profile) for row in rows: clause = pclause & Eq('trait', row.trait) self.profiletrait.update(data=dict(ord=ord), clause=clause) def drop_trait(self, listbox, context, x, y, selection, targettype, time): traits = keysplitter(selection) self.profiletrait.insert_traits(traits) self.__set_pages(self.current.profile) def drop_families(self, listbox, context, x, y, selection, targettype, time): families = keysplitter(selection) clause = Eq('profile', self.current.profile) data = dict(profile=self.current.profile) current = [x.family for x in self.pfamily.select(clause=clause)] for f in families: if f not in current: data['family'] = f self.pfamily.insert(data=data) self.__set_pages(self.current.profile) def _get_listbox(self, page, field): pages = dict(self.pages) return [row[field] for row in pages[page].listbox.get_selected_data()] def profile_command(self, menu, command): if command[:10] == 'change to ': self.change_suite(command[10:]) elif command == 'drop': self.profiletrait.drop_profile(self.current.profile) self.profiles.drop_profile(self.current.profile) self.current = None self.reset_rows() elif command == 'set defaults': self.variables.set_defaults() elif command == 'append defaults': self.variables.append_defaults() else: raise Error, 'bad command %s' % command def change_suite(self, suite): clause = Eq('profile', self.current.profile) self.profiles.update(data={'suite': suite}, clause=clause) print 'changing suite to ', suite self.current_suite = suite self.reset_rows()
class VariablesConfig(RawConfigParser): def __init__(self, conn, table, section, mainfield=None, mainvalue=None, option='name', value='value'): self.conn = conn self.cursor = StatementCursor(self.conn) self.cursor.set_table(table) self._secfield = section bothnone = mainfield is None and mainvalue is None bothset = mainfield and mainvalue if not bothnone and not bothset: raise Error, 'both mainfield and mainvalue need to be set/unset' self._mainclause = None if bothset: self._mainclause = Eq(mainfield, mainvalue) self._fields = [self._secfield, option, value] RawConfigParser.__init__(self) for row in self.cursor.select(fields=self._fields, clause=self._mainclause): if row[0] not in self.sections(): self.add_section(row[0]) self.set(*row) def write(self, cfile): sections = self.sections() sections.sort() for section in sections: cfile.write('[%s]\n' % section) keys = self.options(section) keys.sort() for k in keys: if k != '__name__': v = str(self.get(section, k)).replace('\n', '\n\t') cfile.write('%s:\t%s\n' % (k, v)) cfile.write('\n') def edit(self): tmp, path = tempfile.mkstemp('variables', 'config') tmp = file(path, 'w') self.write(tmp) tmp.close() os.system('$EDITOR %s' % path) tmp = file(path, 'r') newconfig = RawConfigParser() newconfig.readfp(tmp) tmp.close() os.remove(path) return newconfig def diff(self, other): ltmp, lpath = tempfile.mkstemp('variables', 'config') ltmp = file(lpath, 'w') self.write(ltmp) ltmp.close() rtmp, rpath = tempfile.mkstemp('variables', 'config') rtmp = file(rpath, 'w') other.write(rtmp) rtmp.close() os.system('xxdiff %s %s' % (lpath, rpath)) ltmp, rtmp = file(lpath, 'r'), file(rpath, 'r') lcfg, rcfg = RawConfigParser(), RawConfigParser() lcfg.readfp(ltmp) rcfg.readfp(rtmp) ltmp.close() rtmp.close() self.update(lcfg) other.update(rcfg) def update(self, newconfig): removed = [x for x in self.sections() if x not in newconfig.sections()] for section in removed: print 'removing', section sclause = Eq(self._secfield, section) if self._mainclause: sclause &= self._mainclause self.cursor.delete(clause=sclause) for section in newconfig.sections(): print section sclause = Eq(self._secfield, section) if self._mainclause: sclause = self._mainclause & Eq(self._secfield, section) if not self.has_section(section): for k, v in newconfig.items(section): idata = dict(zip(self._fields, [section, k, v])) if self._mainclause: idata[self._mainclause.left] = self._mainclause.right print idata self.cursor.insert(data=idata) else: for name, value in newconfig.items(section): nclause = sclause & Eq(self._fields[1], name) #print 'nclause', nclause #print 'value', self.get(section, name) if self.has_option(section, name): if value != self.get(section, name): #print 'updating' self.cursor.update(data={self._fields[2]: value}, clause=nclause) else: idata = dict(zip(self._fields, [section, name, value])) if self._mainclause: idata[ self._mainclause.left] = self._mainclause.right self.cursor.insert(data=idata) if self.has_section(section): for name, value in self.items(section): if not newconfig.has_option(section, name): clause = sclause & Eq(self._fields[1], name) #print 'dclause', clause self.cursor.delete(clause=clause)
class DiskManager(object): def __init__(self, conn): self.conn = conn self.parser = PartitionParser() self.cursor = StatementCursor(self.conn) def _quick_partition(self, device, data): i, o = os.popen2('sfdisk %s' % device) i.write(data) i.close() def get_partition_info(self, device, parser=None): if parser is None: parser = self.parser command = 'bash -c "sfdisk -d %s | grep %s"' % (device, device) part_info = commands.getoutput(command) return self._parse_diskconfig(device, part_info) def _parse_diskconfig(self, device, astring): parsed = self.parser.parseString(astring) partitions = [] for p in parsed: pnum = p[0].split(device)[1] pdict = dict(partition=pnum, start=p[1], size=p[2], Id=p[3]) partitions.append(pdict) return partitions def _submit_diskconfig(self, diskname, device, astring): workspace = 'partition_workspace' self.cursor.delete(table=workspace, clause=(Eq('diskname', diskname))) row = dict(diskname=diskname) for partition in self._parse_diskconfig(device, astring): print 'submitting', partition row.update(partition) self.cursor.insert(table=workspace, data=row) def submit_partitions(self, diskname, device): self.cursor.set_table('partition_workspace') self.cursor.delete(clause=(Eq('diskname', diskname))) row = dict(diskname=diskname) print 'submitting', device for partition in self.get_partition_info(device): print 'submitting', partition row.update(partition) self.cursor.insert(data=row) def approve_disk(self, diskname): clause = Eq('diskname', diskname) workspace = 'partition_workspace' sql = Statement('select') sql.table = workspace sql.clause = clause new_rows = sql.select(order='partition') if diskname not in [ r.diskname for r in self.cursor.select(table='disks') ]: self.cursor.insert(table='disks', data=dict(diskname=diskname)) else: self.cursor.delete(table='partitions', clause=clause) self.cursor.execute('insert into partitions %s' % new_rows) def get_partitions_by_name(self, diskname): return self.cursor.select(table='partitions', clause=Eq('diskname', diskname), order='partition') def make_partition_dump(self, device, partitions): output = '# partition table of %s\n' output += 'unit: sectors\n' for p in partitions: line = '%s%s : start= %8d, size= %8d, Id=%2d' % \ (device, p.partition, p.start, p.size, p.id) output += line + '\n' return output def partition_disk(self, diskname, device): partitions = self.get_partitions_by_name(diskname) data = self.make_partition_dump(device, partitions) self._quick_partition(device, data) def clear_partition_table(self, device): command = 'dd if=/dev/zero of=%s count=1 bs=512' % device os.system(command)
class VariablesConfig(RawConfigParser): def __init__(self, conn, table, section, mainfield=None, mainvalue=None, option="name", value="value"): self.conn = conn self.cursor = StatementCursor(self.conn) self.cursor.set_table(table) self._secfield = section bothnone = mainfield is None and mainvalue is None bothset = mainfield and mainvalue if not bothnone and not bothset: raise Error, "both mainfield and mainvalue need to be set/unset" self._mainclause = None if bothset: self._mainclause = Eq(mainfield, mainvalue) self._fields = [self._secfield, option, value] RawConfigParser.__init__(self) for row in self.cursor.select(fields=self._fields, clause=self._mainclause): if row[0] not in self.sections(): self.add_section(row[0]) self.set(*row) def write(self, cfile): sections = self.sections() sections.sort() for section in sections: cfile.write("[%s]\n" % section) keys = self.options(section) keys.sort() for k in keys: if k != "__name__": v = str(self.get(section, k)).replace("\n", "\n\t") cfile.write("%s:\t%s\n" % (k, v)) cfile.write("\n") def edit(self): tmp, path = tempfile.mkstemp("variables", "config") tmp = file(path, "w") self.write(tmp) tmp.close() os.system("$EDITOR %s" % path) tmp = file(path, "r") newconfig = RawConfigParser() newconfig.readfp(tmp) tmp.close() os.remove(path) return newconfig def diff(self, other): ltmp, lpath = tempfile.mkstemp("variables", "config") ltmp = file(lpath, "w") self.write(ltmp) ltmp.close() rtmp, rpath = tempfile.mkstemp("variables", "config") rtmp = file(rpath, "w") other.write(rtmp) rtmp.close() os.system("xxdiff %s %s" % (lpath, rpath)) ltmp, rtmp = file(lpath, "r"), file(rpath, "r") lcfg, rcfg = RawConfigParser(), RawConfigParser() lcfg.readfp(ltmp) rcfg.readfp(rtmp) ltmp.close() rtmp.close() self.update(lcfg) other.update(rcfg) def update(self, newconfig): removed = [x for x in self.sections() if x not in newconfig.sections()] for section in removed: print "removing", section sclause = Eq(self._secfield, section) if self._mainclause: sclause &= self._mainclause self.cursor.delete(clause=sclause) for section in newconfig.sections(): print section sclause = Eq(self._secfield, section) if self._mainclause: sclause = self._mainclause & Eq(self._secfield, section) if not self.has_section(section): for k, v in newconfig.items(section): idata = dict(zip(self._fields, [section, k, v])) if self._mainclause: idata[self._mainclause.left] = self._mainclause.right print idata self.cursor.insert(data=idata) else: for name, value in newconfig.items(section): nclause = sclause & Eq(self._fields[1], name) # print 'nclause', nclause # print 'value', self.get(section, name) if self.has_option(section, name): if value != self.get(section, name): # print 'updating' self.cursor.update(data={self._fields[2]: value}, clause=nclause) else: idata = dict(zip(self._fields, [section, name, value])) if self._mainclause: idata[self._mainclause.left] = self._mainclause.right self.cursor.insert(data=idata) if self.has_section(section): for name, value in self.items(section): if not newconfig.has_option(section, name): clause = sclause & Eq(self._fields[1], name) # print 'dclause', clause self.cursor.delete(clause=clause)
class Profile(StatementCursor): def __init__(self, conn): StatementCursor.__init__(self, conn) self.conn = conn self.set_table('profiles') self._traits = ProfileTrait(conn) self._env = ProfileEnvironment(conn) self._pfam = StatementCursor(conn) self._pfam.set_table('profile_family') self._fam = Family(conn) self.current = None def drop_profile(self, profile): self.delete(clause=Eq('profile', profile)) def set_profile(self, profile): self.clause = Eq('profile', profile) self.current = self.select_row(clause=self.clause) self._traits.set_profile(profile) self._env.set_profile(profile) def get_profile_data(self): return self._env.ProfileData() def get_family_data(self): families = self.get_families() return self._fam.FamilyData(families) def _make_traitlist(self, traits, log=None): tp = TraitParent(self.conn, self.current.suite) listed = traits all = list(tp.get_traitset(listed)) setfun = tp.set_trait parfun = tp.parents return make_deplist(listed, all, setfun, parfun, log) def make_traitlist(self, log=None): listed = [x.trait for x in self._traits.trait_rows()] return self._make_traitlist(listed, log=log) def get_traitlist_for_traits(self, traits): return self._make_traitlist(traits) def family_rows(self, profile=None): if profile is None: profile = self.current.profile return self._pfam.select(clause=Eq('profile', profile), order='family') def get_families(self, profile=None): return [r.family for r in self.family_rows(profile)] def get_trait_rows(self): return self._traits.trait_rows() def append_family(self, family): if family not in self.get_families(): self._pfam.insert( data=dict(profile=self.current.profile, family=family)) def append_trait(self, trait, ord): self._traits.insert_trait(trait, ord) def set_suite(self, suite): clause = Eq('profile', self.current.profile) self.update(data=dict(suite=suite), clause=clause) self.set_profile(self.current.profile) def copy_profile(self, src, dest): current = self.current self.set_profile(src) pfield = "'%s' as profile" % dest pclause = Eq('profile', src) pcursor = self tcursor = self._traits.cmd fcusor = self._pfam vcursor = self._env.env.cursor cursors = [pcursor, tcursor, fcusor, vcursor] for cursor in cursors: sel = str( cursor.stmt.select(fields=[pfield] + cursor.fields()[1:], clause=pclause)) cursor.execute('insert into %s (%s)' % (cursor.stmt.table, sel)) if current is not None: self.set_profile(current.profile) def get_profile_list(self, suite=None): if suite is None: plist = [r.profile for r in self.select()] elif suite == 'all': plist = [(r.profile, r.suite) for r in self.select()] else: clause = Eq('suite', suite) plist = [r.profile for r in self.select(clause=clause)] return plist def edit_variables(self): config = ProfileVariablesConfig(self.conn, self.current.profile) newconfig = config.edit() config.update(newconfig) def delete_trait(self, trait): self._traits.delete(trait) def delete_all_traits(self): self._traits.delete_all() def delete_family(self, family): clause = Eq('profile', self.current.profile) & Eq('family', family) self._pfam.delete(clause=clause) def delete_all_families(self): clause = Eq('profile', self.current.profile) self._pfam.delete(clause=clause) def insert_new_traits(self, traits): self.delete_all_traits() num = 0 for trait in traits: self.append_trait(trait, num) num += 1
class ProfileBrowser(ListNoteBook, HasDialogs): def __init__(self, conn, suites, name='ProfileBrowser'): self.menu = self.__make_mainmenu_(suites) ListNoteBook.__init__(self, name=name) self.conn = conn self.profiles = Profile(self.conn) self.profiletrait = ProfileTrait(self.conn) self.family = Family(self.conn) self.pfamily = StatementCursor(self.conn) self.pfamily.set_table('profile_family') self.trait_menu = make_menu(['drop', 'order'], self.trait_command) self.pdata_menu = make_menu(['edit', 'drop'], self.variable_command) self.family_menu = make_menu(['drop'], self.family_command) self.reset_rows() self.append_page(ScrollCList(rcmenu=self.trait_menu), 'traits') self.append_page(ScrollCList(rcmenu=self.pdata_menu), 'variables') self.append_page(ScrollCList(rcmenu=self.family_menu), 'families') self.dialogs = {}.fromkeys(['order']) def __make_mainmenu_(self, suites): suite_commands = ['change to %s' %suite for suite in suites] profile_commands = ['drop', 'set defaults', 'append defaults'] commands = suite_commands + profile_commands return make_menu(commands, self.profile_command) def reset_rows(self): self.set_rows(self.profiles.select(fields=['profile', 'suite'], order='profile')) self.set_row_select(self.profile_selected) def profile_selected(self, listbox, row, column, event): row = listbox.get_selected_data()[0] self.current = row self.select_profile(self.current.profile) def select_profile(self, profile): self.variables = ProfileEnvironment(self.conn, profile) self.profiletrait.set_profile(profile) self.__set_pages(profile) def __set_pages(self, profile): pages = dict(self.pages) #set traits for profile pages['traits'].set_rows(self.profiletrait.trait_rows()) pages['traits'].set_select_mode('multi') clause = Eq('profile', self.current.profile) cursor = self.variables.env.cursor pages['variables'].set_rows(cursor.select(clause=clause), ['trait']) pages['variables'].set_select_mode('multi') pfrows = self.pfamily.select(fields=['family'], clause=clause) pages['families'].set_rows(pfrows) pages['families'].set_select_mode('multi') self.__set_droptargets__(pages) def __set_droptargets__(self, pages): set_receive_targets(pages['traits'].listbox, self.drop_trait, TARGETS.get('trait', self.current.suite)) set_receive_targets(pages['families'].listbox, self.drop_families, FTargets.get('family', 'flavor')) def trait_command(self, menuitem, action): traits = self._get_listbox('traits', 'trait') if action == 'drop': clause = In('trait', traits) & Eq('profile', self.current.profile) self.profiletrait.cmd.delete(clause=clause) self.__set_pages(self.current.profile) elif action == 'order': if not self.dialogs['order']: self.dialogs['order'] = dialogs.Entry('enter order', name='order') self.dialogs['order'].set_ok(self.set_order) self.dialogs['order'].set_cancel(self.destroy_dialog) def variable_command(self, menuitem, action): rows = self.pages['variables'].get_selected_data() cursor = self.variables.env.cursor if action == 'drop': for row in rows: clause = Eq('profile', self.current.profile) & Eq('trait', row.trait) clause &= Eq('name', row.name) cursor.delete(clause=clause) elif action == 'edit': self.edit_profilevars() def family_command(self, menuitem, action): print action families = [x[0] for x in self.pages['families'].get_selected_data()] if action == 'drop': clause = Eq('profile', self.current.profile) & In('family', families) self.pfamily.delete(clause=clause) def edit_profilevars(self): config = ProfileVariablesConfig(self.conn, self.current.profile) newconfig = config.edit() config.update(newconfig) self.select_profile(self.current.profile) def set_order(self, button): dialog = self.dialogs['order'] ord = dialog.get() rows = self.pages['traits'].get_selected_data() pclause = Eq('profile', self.current.profile) for row in rows: clause = pclause & Eq('trait', row.trait) self.profiletrait.update(data=dict(ord=ord), clause=clause) def drop_trait(self, listbox, context, x, y, selection, targettype, time): traits = keysplitter(selection) self.profiletrait.insert_traits(traits) self.__set_pages(self.current.profile) def drop_families(self, listbox, context, x, y, selection, targettype, time): families = keysplitter(selection) clause = Eq('profile', self.current.profile) data = dict(profile=self.current.profile) current = [x.family for x in self.pfamily.select(clause=clause)] for f in families: if f not in current: data['family'] = f self.pfamily.insert(data=data) self.__set_pages(self.current.profile) def _get_listbox(self, page, field): pages = dict(self.pages) return [row[field] for row in pages[page].listbox.get_selected_data()] def profile_command(self, menu, command): if command[:10] == 'change to ': self.change_suite(command[10:]) elif command == 'drop': self.profiletrait.drop_profile(self.current.profile) self.profiles.drop_profile(self.current.profile) self.current = None self.reset_rows() elif command == 'set defaults': self.variables.set_defaults() elif command == 'append defaults': self.variables.append_defaults() else: raise Error, 'bad command %s' %command def change_suite(self, suite): clause = Eq('profile', self.current.profile) self.profiles.update(data={'suite' : suite}, clause=clause) print 'changing suite to ', suite self.current_suite = suite self.reset_rows()
def quick_wipe(conn): cursor = StatementCursor(conn) cursor.delete(table='machines') cursor.delete(table='partition_workspace') cursor.delete(table='partitions') cursor.delete(table='filesystem_mounts') cursor.delete(table='filesystem_disks') cursor.delete(table='partition_mounts') cursor.delete(table='machine_disks') cursor.delete(table='machine_types') cursor.delete(table='mounts') cursor.delete(table='disks') cursor.delete(table='filesystems') cursor.delete(table='kernels')
class Profile(StatementCursor): def __init__(self, conn): StatementCursor.__init__(self, conn) self.conn = conn self.set_table('profiles') self._traits = ProfileTrait(conn) self._env = ProfileEnvironment(conn) self._pfam = StatementCursor(conn) self._pfam.set_table('profile_family') self._fam = Family(conn) self.current = None def drop_profile(self, profile): self.delete(clause=Eq('profile', profile)) def set_profile(self, profile): self.clause = Eq('profile', profile) self.current = self.select_row(clause=self.clause) self._traits.set_profile(profile) self._env.set_profile(profile) def get_profile_data(self): return self._env.ProfileData() def get_family_data(self): families = self.get_families() return self._fam.FamilyData(families) def _make_traitlist(self, traits, log=None): tp = TraitParent(self.conn, self.current.suite) listed = traits all = list(tp.get_traitset(listed)) setfun = tp.set_trait parfun = tp.parents return make_deplist(listed, all, setfun, parfun, log) def make_traitlist(self, log=None): listed = [x.trait for x in self._traits.trait_rows()] return self._make_traitlist(listed, log=log) def get_traitlist_for_traits(self, traits): return self._make_traitlist(traits) def family_rows(self, profile=None): if profile is None: profile = self.current.profile return self._pfam.select(clause=Eq('profile', profile), order='family') def get_families(self, profile=None): return [r.family for r in self.family_rows(profile)] def get_trait_rows(self): return self._traits.trait_rows() def append_family(self, family): if family not in self.get_families(): self._pfam.insert(data=dict(profile=self.current.profile, family=family)) def append_trait(self, trait, ord): self._traits.insert_trait(trait, ord) def set_suite(self, suite): clause = Eq('profile', self.current.profile) self.update(data=dict(suite=suite), clause=clause) self.set_profile(self.current.profile) def copy_profile(self, src, dest): current = self.current self.set_profile(src) pfield = "'%s' as profile" % dest pclause = Eq('profile', src) pcursor = self tcursor = self._traits.cmd fcusor = self._pfam vcursor = self._env.env.cursor cursors = [ pcursor, tcursor, fcusor, vcursor] for cursor in cursors: sel = str(cursor.stmt.select(fields = [pfield] + cursor.fields()[1:], clause=pclause)) cursor.execute('insert into %s (%s)' % (cursor.stmt.table, sel)) if current is not None: self.set_profile(current.profile) def get_profile_list(self, suite=None): if suite is None: plist = [r.profile for r in self.select()] elif suite == 'all': plist = [(r.profile, r.suite) for r in self.select()] else: clause = Eq('suite', suite) plist = [r.profile for r in self.select(clause=clause)] return plist def edit_variables(self): config = ProfileVariablesConfig(self.conn, self.current.profile) newconfig = config.edit() config.update(newconfig) def delete_trait(self, trait): self._traits.delete(trait) def delete_all_traits(self): self._traits.delete_all() def delete_family(self, family): clause = Eq('profile', self.current.profile) & Eq('family', family) self._pfam.delete(clause=clause) def delete_all_families(self): clause = Eq('profile', self.current.profile) self._pfam.delete(clause=clause) def insert_new_traits(self, traits): self.delete_all_traits() num = 0 for trait in traits: self.append_trait(trait, num) num += 1
class Profile(StatementCursor): def __init__(self, conn): StatementCursor.__init__(self, conn) self.conn = conn self.set_table('profiles') self._traits = ProfileTrait(conn) self._env = ProfileEnvironment(conn) self._pfam = StatementCursor(conn) self._pfam.set_table('profile_family') self._fam = Family(conn) self.current = None def delete_profile(self, profile): self.execute("select * from delete_profile('%s')" % profile) def make_new_profile(self, profile, suite): data = dict(profile=profile, suite=suite) self.insert(data=data) def make_environment_object(self): return ProfileEnvironment(self.conn) def set_profile(self, profile): self.clause = Eq('profile', profile) self.current = self.select_row(clause=self.clause) self._traits.set_profile(profile) self._env.set_profile(profile) def get_profile_data(self): return self._env.ProfileData() def get_family_data(self): families = self.get_families() return self._fam.FamilyData(families) def _make_traitlist(self, traits, log=None): tp = TraitParent(self.conn, self.current.suite) listed = traits all = list(tp.get_traitset(listed)) setfun = tp.set_trait parfun = tp.parents return make_deplist(listed, all, setfun, parfun, log) def make_traitlist_with_traits(self, traits, log=None): return self._make_traitlist(traits, log=log) def make_traitlist(self, log=None): listed = [x.trait for x in self._traits.trait_rows()] return self._make_traitlist(listed, log=log) def get_traitlist_for_traits(self, traits): return self._make_traitlist(traits) def family_rows(self, profile=None): if profile is None: profile = self.current.profile return self._pfam.select(clause=Eq('profile', profile), order='family') def get_families(self, profile=None): return [r.family for r in self.family_rows(profile)] def get_trait_rows(self): return self._traits.trait_rows() def append_family(self, family): if family not in self.get_families(): self._pfam.insert(data=dict(profile=self.current.profile, family=family)) def append_trait(self, trait, ord): self._traits.insert_trait(trait, ord) def set_suite(self, suite): clause = Eq('profile', self.current.profile) self.update(data=dict(suite=suite), clause=clause) self.set_profile(self.current.profile) def copy_profile(self, src, dest): current = self.current self.set_profile(src) pfield = "'%s' as profile" % dest pclause = Eq('profile', src) pcursor = self tcursor = self._traits.cmd fcusor = self._pfam vcursor = self._env.env.cursor cursors = [ pcursor, tcursor, fcusor, vcursor] for cursor in cursors: sel = str(cursor.stmt.select(fields = [pfield] + cursor.fields()[1:], clause=pclause)) cursor.execute('insert into %s (%s)' % (cursor.stmt.table, sel)) if current is not None: self.set_profile(current.profile) def get_profile_list(self, suite=None): if suite is None: plist = [r.profile for r in self.select()] elif suite == 'all': plist = [(r.profile, r.suite) for r in self.select()] else: clause = Eq('suite', suite) plist = [r.profile for r in self.select(clause=clause)] return plist def edit_variables(self): config = ProfileVariablesConfig(self.conn, self.current.profile) newconfig = config.edit() config.update(newconfig) def delete_trait(self, trait): self._traits.delete(trait) def delete_all_traits(self): self._traits.delete_all() def delete_family(self, family): clause = Eq('profile', self.current.profile) & Eq('family', family) self._pfam.delete(clause=clause) def delete_all_families(self): clause = Eq('profile', self.current.profile) self._pfam.delete(clause=clause) def insert_new_traits(self, traits): self.delete_all_traits() num = 0 for trait in traits: self.append_trait(trait, num) num += 1 def generate_xml(self, profile=None, suite=None, env=None): if profile is None: profile = self.current.profile suite = self.current.suite if suite is None: row = self.select_row(clause=Eq('profile', profile)) suite = row.suite if env is None: env = ProfileEnvironment(self.conn, profile) element = ProfileElement(profile, suite) element.append_traits(self._traits.trait_rows(profile)) element.append_families(self.family_rows(profile)) element.append_variables(env.get_rows()) return element def import_profile(self, filename): profile = parse_profile(filename) if profile.name in self.get_profile_list(): raise AlreadyExistsError, '%s already exists.' % profile.name self.insert(data=dict(profile=profile.name, suite=profile.suite)) # insert profile traits idata = dict(profile=profile.name, trait=None, ord=0) for trait, ord in profile.traits: idata['trait'] = trait idata['ord'] = ord self.insert(table='profile_trait', data=idata) # insert profile families idata = dict(profile=profile.name) for family in profile.families: idata['family'] = family self.insert(table='profile_family', data=idata) # insert profile variables idata = dict(profile=profile.name, trait=None, name=None, value=None) for trait, name, value in profile.vars: idata.update(dict(trait=trait, name=name, value=value)) self.insert(table='profile_variables', data=idata) 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 import_all_profiles(self, dirname): dirname = path(dirname) files = [p for p in dirname.listdir() if p.endswith('.xml')] for filename in files: self.import_profile(filename) def export_all_profiles(self, dirname): for profile in self.get_profile_list(): self.export_profile(dirname, profile=profile)
class Profile(StatementCursor): def __init__(self, conn): StatementCursor.__init__(self, conn) self.conn = conn self.set_table('profiles') self._traits = ProfileTrait(conn) self._env = ProfileEnvironment(conn) self._pfam = StatementCursor(conn) self._pfam.set_table('profile_family') self._fam = Family(conn) self.current = None def drop_profile(self, profile): self.delete(clause=Eq('profile', profile)) def make_new_profile(self, profile, suite): data = dict(profile=profile, suite=suite) self.insert(data=data) def make_environment_object(self): return ProfileEnvironment(self.conn) def set_profile(self, profile): self.clause = Eq('profile', profile) self.current = self.select_row(clause=self.clause) self._traits.set_profile(profile) self._env.set_profile(profile) def get_profile_data(self): return self._env.ProfileData() def get_family_data(self): families = self.get_families() return self._fam.FamilyData(families) def _make_traitlist(self, traits, log=None): tp = TraitParent(self.conn, self.current.suite) listed = traits all = list(tp.get_traitset(listed)) setfun = tp.set_trait parfun = tp.parents return make_deplist(listed, all, setfun, parfun, log) def make_traitlist_with_traits(self, traits, log=None): return self._make_traitlist(traits, log=log) def make_traitlist(self, log=None): listed = [x.trait for x in self._traits.trait_rows()] return self._make_traitlist(listed, log=log) def get_traitlist_for_traits(self, traits): return self._make_traitlist(traits) def family_rows(self, profile=None): if profile is None: profile = self.current.profile return self._pfam.select(clause=Eq('profile', profile), order='family') def get_families(self, profile=None): return [r.family for r in self.family_rows(profile)] def get_trait_rows(self): return self._traits.trait_rows() def append_family(self, family): if family not in self.get_families(): self._pfam.insert(data=dict(profile=self.current.profile, family=family)) def append_trait(self, trait, ord): self._traits.insert_trait(trait, ord) def set_suite(self, suite): clause = Eq('profile', self.current.profile) self.update(data=dict(suite=suite), clause=clause) self.set_profile(self.current.profile) def copy_profile(self, src, dest): current = self.current self.set_profile(src) pfield = "'%s' as profile" % dest pclause = Eq('profile', src) pcursor = self tcursor = self._traits.cmd fcusor = self._pfam vcursor = self._env.env.cursor cursors = [ pcursor, tcursor, fcusor, vcursor] for cursor in cursors: sel = str(cursor.stmt.select(fields = [pfield] + cursor.fields()[1:], clause=pclause)) cursor.execute('insert into %s (%s)' % (cursor.stmt.table, sel)) if current is not None: self.set_profile(current.profile) def get_profile_list(self, suite=None): if suite is None: plist = [r.profile for r in self.select()] elif suite == 'all': plist = [(r.profile, r.suite) for r in self.select()] else: clause = Eq('suite', suite) plist = [r.profile for r in self.select(clause=clause)] return plist def edit_variables(self): config = ProfileVariablesConfig(self.conn, self.current.profile) newconfig = config.edit() config.update(newconfig) def delete_trait(self, trait): self._traits.delete(trait) def delete_all_traits(self): self._traits.delete_all() def delete_family(self, family): clause = Eq('profile', self.current.profile) & Eq('family', family) self._pfam.delete(clause=clause) def delete_all_families(self): clause = Eq('profile', self.current.profile) self._pfam.delete(clause=clause) def insert_new_traits(self, traits): self.delete_all_traits() num = 0 for trait in traits: self.append_trait(trait, num) num += 1 def generate_xml(self, profile=None, suite=None, env=None): if profile is None: profile = self.current.profile suite = self.current.suite if suite is None: row = self.select_row(clause=Eq('profile', profile)) suite = row.suite if env is None: env = ProfileEnvironment(self.conn, profile) element = ProfileElement(profile, suite) element.append_traits(self._traits.trait_rows(profile)) element.append_families(self.family_rows(profile)) element.append_variables(env.get_rows()) return element def import_profile(self, filename): profile = parse_profile(filename) if profile.name in self.get_profile_list(): raise AlreadyExistsError, '%s already exists.' % profile.name self.insert(data=dict(profile=profile.name, suite=profile.suite)) # insert profile traits idata = dict(profile=profile.name, trait=None, ord=0) for trait, ord in profile.traits: idata['trait'] = trait idata['ord'] = ord self.insert(table='profile_trait', data=idata) # insert profile families idata = dict(profile=profile.name) for family in profile.families: idata['family'] = family self.insert(table='profile_family', data=idata) # insert profile variables idata = dict(profile=profile.name, trait=None, name=None, value=None) for trait, name, value in profile.vars: idata.update(dict(trait=trait, name=name, value=value)) self.insert(table='profile_variables', data=idata) 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 import_all_profiles(self, dirname): dirname = path(dirname) files = [p for p in dirname.listdir() if p.endswith('.xml')] for filename in files: self.import_profile(filename) def export_all_profiles(self, dirname): for profile in self.get_profile_list(): self.export_profile(dirname, profile=profile)
class DiskManager(object): def __init__(self, conn): self.conn = conn self.parser = PartitionParser() self.cursor = StatementCursor(self.conn) def _quick_partition(self, device, data): i, o = os.popen2('sfdisk %s' % device) i.write(data) i.close() def get_partition_info(self, device, parser=None): if parser is None: parser = self.parser command = 'bash -c "sfdisk -d %s | grep %s"' % (device, device) part_info = commands.getoutput(command) return self._parse_diskconfig(device, part_info) def _parse_diskconfig(self, device, astring): parsed = self.parser.parseString(astring) partitions = [] for p in parsed: pnum = p[0].split(device)[1] pdict = dict(partition=pnum, start=p[1], size=p[2], Id=p[3]) partitions.append(pdict) return partitions def _submit_diskconfig(self, diskname, device, astring): workspace = 'partition_workspace' self.cursor.delete(table=workspace, clause=(Eq('diskname', diskname))) row = dict(diskname=diskname) for partition in self._parse_diskconfig(device, astring): print 'submitting', partition row.update(partition) self.cursor.insert(table=workspace, data=row) def submit_partitions(self, diskname, device): self.cursor.set_table('partition_workspace') self.cursor.delete(clause=(Eq('diskname', diskname))) row = dict(diskname=diskname) print 'submitting', device for partition in self.get_partition_info(device): print 'submitting', partition row.update(partition) self.cursor.insert(data=row) def approve_disk(self, diskname): clause = Eq('diskname', diskname) workspace = 'partition_workspace' sql = Statement('select') sql.table = workspace sql.clause = clause new_rows = sql.select(order='partition') if diskname not in [r.diskname for r in self.cursor.select(table='disks')]: self.cursor.insert(table='disks', data=dict(diskname=diskname)) else: self.cursor.delete(table='partitions', clause=clause) self.cursor.execute('insert into partitions %s' % new_rows) def get_partitions_by_name(self, diskname): return self.cursor.select(table='partitions', clause=Eq('diskname', diskname), order='partition') def make_partition_dump(self, device, partitions): output = '# partition table of %s\n' output += 'unit: sectors\n' for p in partitions: line = '%s%s : start= %8d, size= %8d, Id=%2d' % \ (device, p.partition, p.start, p.size, p.id) output += line + '\n' return output def partition_disk(self, diskname, device): partitions = self.get_partitions_by_name(diskname) data = self.make_partition_dump(device, partitions) self._quick_partition(device, data) def clear_partition_table(self, device): command = 'dd if=/dev/zero of=%s count=1 bs=512' % device os.system(command)
class Family(object): def __init__(self, conn): object.__init__(self) self.conn = conn self.cursor = StatementCursor(self.conn) self.current = None self.parent = SimpleRelation(self.conn, 'family_parent', 'family') self.env = FamilyEnvironment(self.conn) def set_family(self, family): self.current = family self.parent.set_current(family) self.env.set_family(family) def _check_family(self, family): if family is not None: return family else: family = self.current if family is None: raise Error, 'either pass a family argument or call set_family on this object' return family def get_related_families(self, families=[]): rows = self.cursor.select(table='family_parent') graph = kjGraph([(r.family, r.parent) for r in rows]) dfamilies = Set() for fam in families: dfamilies |= Set([fam]) | Set(graph.reachable(fam).items()) return dfamilies def parent_rows(self, family=None): family = self._check_family(family) self.parent.set_clause(family) rows = self.parent.cmd.select(fields=['parent'], order='parent') self.parent.reset_clause() return rows def parents(self, family=None): family = self._check_family(family) rows = self.parent_rows(family) return [x.parent for x in rows] def environment_rows(self, family=None): family = self._check_family(family) clause = Eq('family', family) args = dict(fields=['trait', 'name', 'value'], clause=clause, order=['trait', 'name']) return self.env.cursor.select(**args) def family_rows(self): return self.cursor.select(fields=['family'], table='families', order='family') def all_families(self): return [r.family for r in self.family_rows()] def get_all_defaults(self): suite_cursor = SuiteCursor(self.conn) suites = suite_cursor.get_suites() stmt = select_multisuite_union(suites, 'variables') print stmt self.cursor.execute(stmt) return self.cursor.fetchall() def create_family(self, family): if family not in self.all_families(): self.cursor.insert(table='families', data=dict(family=family)) else: raise ExistsError, '%s already exists' % family def delete_family(self, family=None): family = self._check_family(family) self.cursor.execute("select * from delete_family('%s')" % family) def insert_parents(self, parents, family=None): family = self._check_family(family) self.parent.insert('parent', parents) def delete_parents(self, parents=[], family=None): family = self._check_family(family) if not parents: parents = self.parents() if not parents: return table = 'family_parent' clause = Eq('family', family) & In('parent', parents) self.cursor.delete(table=table, clause=clause) def FamilyData(self, families=[]): # change sep here sep = PAELLA_TRAIT_NAME_SEP # we don't know what to do here # it is possible to have an empty # list of families, and if that's the # case we don't need to make the # list of [self.current] . I need to look # for everywhere this method is called. # In the installer, the family is never set, # and we use the list of families provided # by the profile and the machine. In this # case, the families argument will always # be a list, empty or not. # I can't think of any other circumstance # where this method would be called outside # of the installer, or a script, and the script # should be using either a profile or machine # to get the list of families anyway, make the # point moot. I will probably remove this part # of the code in the near future, once I'm sure # that there's no reason to pass None to the # families argument. if families is None: families = [self.current] all = self.make_familylist(families) superdict = {} for f in all: superdict.update(self.env.make_tagdict(f, sep=sep)) return superdict def make_familylist(self, families): deps = families all = list(self.get_related_families(families)) setfun = self.set_family parfun = self.parents return make_deplist(deps, all, setfun, parfun) def export_family(self, family=None): if family is None: family = self.current # row isn't used, except to determine that the family exists row = self.cursor.select_row(table='families', clause=Eq('family', family)) element = FamilyElement(family) element.append_parents(self.parents(family)) element.append_variables(self.environment_rows(family)) return element def write_family(self, family, path): fxml = file(join(path, '%s.xml' % family), 'w') data = self.export_family(family) data.writexml(fxml, indent='\t', newl='\n', addindent='\t') fxml.close() def export_families(self, path): families = self.all_families() self.report_total_families(len(families)) for f in families: self.write_family(f, path) self.report_family_exported(f, path) def import_family(self, element): parsed = FamilyParser(element) print 'inserting family', parsed.name all = self.all_families() for p in parsed.parents: if p not in all: print 'insertion failed for', parsed.name raise UnbornError self.create_family(parsed.name) self.set_family(parsed.name) self.insert_parents(parsed.parents) row = dict(family=parsed.name) for var in parsed.environ: row.update(var) self.cursor.insert(table='family_environment', data=row) def _import_family_xml(self, xmlfile): xml = parse_file(xmlfile) elements = xml.getElementsByTagName('family') if len(elements) != 1: raise Error, 'bad number of family tags %s' % len(elements) element = elements[0] return element def import_family_xml(self, xmlfile): element = self._import_family_xml(xmlfile) self.import_family(element) def import_families(self, path): xmlfiles = [ join(path, x) for x in os.listdir(path) if x[-4:] == '.xml' ] families = [] for f in xmlfiles: element = self._import_family_xml(f) families.append(element) while len(families): f = families[0] try: self.import_family(f) except UnbornError: families.append(f) del families[0] print len(families), 'families inserted' def getVariablesConfig(self, family=None): family = self._check_family(family) return FamilyVariablesConfig(self.conn, family) def deleteVariable(self, trait, name, family=None): family = self._check_family(family) data = dict(family=family, trait=trait, name=name) clause = reduce(and_, [Eq(k, v) for k, v in data.items()]) self.env.cursor.delete(clause=clause) def insertVariable(self, trait, name, value, family=None): family = self._check_family(family) data = dict(family=family, trait=trait, name=name) clause = reduce(and_, [Eq(k, v) for k, v in data.items()]) testrows = self.cursor.select(table='family_environment', clause=clause) if not len(testrows): data['value'] = value self.cursor.insert(table='family_environment', data=data) def report_family_exported(self, family, path): print 'family %s exported to %s' % (family, path) def report_total_families(self, total): print 'exporting %d families' % total