From b411cbfbc74dd7d0cb8e633532d76341503c3e7b Mon Sep 17 00:00:00 2001 From: Narayan Desai Date: Thu, 21 Oct 2004 19:26:15 +0000 Subject: pylint fixes (Logical change 1.104) git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@475 ce84e21b-d406-0410-9b95-82705330c041 --- src/lib/Client/Debian.py | 35 ++++++++--------- src/lib/Client/Redhat.py | 94 +++++++++++++++++++++------------------------ src/lib/Client/Toolset.py | 93 +++++++++++++++++++++++--------------------- src/lib/Server/Generator.py | 17 ++++---- src/lib/Server/Metadata.py | 75 ++++++++---------------------------- 5 files changed, 134 insertions(+), 180 deletions(-) (limited to 'src') diff --git a/src/lib/Client/Debian.py b/src/lib/Client/Debian.py index 3af97077a..fe1c8266c 100644 --- a/src/lib/Client/Debian.py +++ b/src/lib/Client/Debian.py @@ -1,12 +1,11 @@ -# This is the bcfg2 support for debian -# $Id $ +#!/usr/bin/env python +'''This is the bcfg2 support for debian''' +__revision__ = '$Revision$' from copy import deepcopy -from glob import glob from os import environ, stat, system from popen2 import Popen4 from string import join, split -from sys import argv import apt_pkg @@ -30,7 +29,7 @@ class Debian(Toolset): if not self.setup['build']: system("dpkg-reconfigure -f noninteractive debconf") system("apt-get -q=2 -y update") - environ["DEBIAN_FRONTEND"]='noninteractive' + environ["DEBIAN_FRONTEND"] = 'noninteractive' self.Refresh() def Refresh(self): @@ -45,10 +44,10 @@ class Debian(Toolset): def VerifyService(self, entry): if entry.attrib['status'] == 'off': - cmd = Popen4("/usr/sbin/update-rc.d -n -f %s remove"%(entry.attrib['name'])) + cmd = Popen4("/usr/sbin/update-rc.d -n -f %s remove" % (entry.attrib['name'])) num = 1 else: - cmd = Popen4("/usr/sbin/update-rc.d -n -f %s remove"%(entry.attrib['name'])) + cmd = Popen4("/usr/sbin/update-rc.d -n -f %s remove" % (entry.attrib['name'])) num = 2 cstat = cmd.poll() output = '' @@ -62,16 +61,16 @@ class Debian(Toolset): def InstallService(self, entry): if entry.attrib['status'] == 'off': if self.setup['dryrun']: - print "Disabling service %s"%(entry.attrib['name']) + print "Disabling service %s" % (entry.attrib['name']) rc = 1 else: - rc = system("update-rc.d -f %s remove"%entry.attrib['name']) + rc = system("update-rc.d -f %s remove" % entry.attrib['name']) else: if self.setup['dryrun']: - print "Enabling service %s"%(entry.attrib['name']) + print "Enabling service %s" % (entry.attrib['name']) rc = 1 else: - rc = system("update-rc.d %s defaults"%(entry.attrib['name'])) + rc = system("update-rc.d %s defaults" % (entry.attrib['name'])) if rc: return False return True @@ -94,11 +93,11 @@ class Debian(Toolset): def InstallPackage(self, entry): if not entry.attrib.has_key('version'): - print "Package entry for %s is malformed"%(entry.attrib['name']) + print "Package entry for %s is malformed" % (entry.attrib['name']) return False if self.setup['dryrun'] or self.setup['verbose']: - print "Installing package %s %s"%(entry.attrib['name'], entry.attrib['version']) + print "Installing package %s %s" % (entry.attrib['name'], entry.attrib['version']) if self.setup['dryrun']: return False @@ -135,13 +134,13 @@ class Debian(Toolset): print "Installing" cmd = "apt-get --reinstall -q=2 -y install %s" print "Need to remove:", self.pkgwork['remove'] - print "%s new, %s update, %s remove"%(len(self.pkgwork['add']),len(self.pkgwork['update']), len(self.pkgwork['remove'])) + print "%s new, %s update, %s remove" % (len(self.pkgwork['add']), len(self.pkgwork['update']), len(self.pkgwork['remove'])) # try single large install rc = system(cmd%join(map(lambda x:"%s=%s"%(x.attrib['name'], x.attrib['version']), self.pkgwork['add'] + self.pkgwork['update']))) if rc == 0: # set installed to true for pkgtodo for pkg in self.pkgwork['add'] + self.pkgwork['update']: - self.states[pkg]=True + self.states[pkg] = True self.pkgtodo = [] self.Refresh() else: @@ -157,12 +156,12 @@ class Debian(Toolset): while (len(work) < oldlen): oldlen = len(work) for pkg in work: - print cmd%("%s=%s"%(pkg.attrib['name'], pkg.attrib['version'])) - rc = system(cmd%("%s=%s"%(pkg.attrib['name'], pkg.attrib['version']))) + print cmd % ("%s=%s"%(pkg.attrib['name'], pkg.attrib['version'])) + rc = system(cmd % ("%s=%s" % (pkg.attrib['name'], pkg.attrib['version']))) if rc == 0: self.states[pkg] = True work.remove(pkg) else: - print "Failed to install package %s"%(pkg.attrib['name']) + print "Failed to install package %s" % (pkg.attrib['name']) for entry in [x for x in self.states if not self.states[x] and x.tag != 'Package']: self.InstallEntry(entry) diff --git a/src/lib/Client/Redhat.py b/src/lib/Client/Redhat.py index 1d1ae62bb..c3c0da4ac 100644 --- a/src/lib/Client/Redhat.py +++ b/src/lib/Client/Redhat.py @@ -1,12 +1,13 @@ # This is the bcfg2 support for redhat # $Id: $ +__revision__ = '$Revision$' +'''This is redhat client support''' + from os import popen, system from popen2 import Popen4 -from re import compile -from string import join -from Toolset import Toolset +from Bcfg2.Client.Toolset import Toolset def Detect(): # until the code works @@ -14,10 +15,6 @@ def Detect(): class Redhat(Toolset): '''This class implelements support for rpm packages and standard chkconfig services''' - chkre=compile("(?P\S+)\s+(?P0:(?P\S+)\s+1:(?P\S+)\s+2:(?P\S+)\s+3:(?P\S+)\s+4:(?P\S+)\s+5:(?P\S+)\s+6:(?P\S+))") - onre=compile(".*on.*") - offre=compile(".*off.*") - xre=compile("(?P\S+)\s+(?P\S+)") rpmcmd = "rpm --oldpackage --replacepkgs --quiet -U %s" def __init__(self, cfg, setup): @@ -25,63 +22,58 @@ class Redhat(Toolset): self.pkgtodo = [] def VerifyService(self, entry): - ckline = popen("/sbin/chkconfig --list %s"%entry.attrib['name']).readlines() - if len(ckline) > 1: - print "got too many lines from for service %s"%(entry.attrib['name']) - return False + srvdata = popen("/sbin/chkconfig --list %s"%entry.attrib['name']).readlines()[0].split() + if entry.attrib['type'] == 'xinetd': + if entry.attrib['status'] == srvdata[1]: + return True + else: + return False else: - if entry.attrib['type'] == 'chkconfig': - cstatus = chkre.match(ckline[0]).group('status') - if entry.attrib['status'] == 'off': - if onre.match(cstatus) == None: - return True - else: - return False - else: # status == on - if not onre.match(cstatus): + # chkconfig/init.d service + if entry.attrib['status'] == 'off': + for level in srvdata[1:]: + if level.split(':')[1] != 'off': return False + return True + else: + # services should be on for 2345 + for level in srvdata[1:]: + [num, status] = level.split(':') + if num in '2345': + if status == 'off': + return False else: - levels = popen("grep chkconfig /etc/init.d/%s | awk '{print $3}' "%(name)).readlines()[0] - if levels[0] == '-' : levels = '345' - for i in range(7): - if str(i) in levels: - if cdata[i] == 'off': - return False - else: - if cdata[i] == 'on': - return False - if i == 6: - return True - elif entry.attrib['type'] == 'xinetd': - if xre.match(ckline[0]).group("status") == entry.attrib['status']: - return True - return False + if status == 'on': + return False + return True def InstallService(self, entry): system("/sbin/chkconfig --add %s"%(entry.attrib['name'])) - if status == 'off': - rc = system("/sbin/chkconfig --level 0123456 %s %s"%(entry.attrib['name'],entry.attrib['status'])) + if entry.attrib['status'] == 'off': + rc = system("/sbin/chkconfig --level 0123456 %s %s" % (entry.attrib['name'], entry.attrib['status'])) else: - rc = system("/sbin/chkconfig %s %s"%(entry.attrib['name'],entry.attrib['status'])) + rc = system("/sbin/chkconfig %s %s" % + (entry.attrib['name'], entry.attrib['status'])) if rc == 0: return True else: return False def VerifyPackage(self, entry, modlist = []): - instp=Popen4("rpm -qi %s-%s"%(entry.attrib['name'],entry.attrib['version'])) - istat=instp.wait()/256 + instp = Popen4("rpm -qi %s-%s" % (entry.attrib['name'], entry.attrib['version'])) + istat = instp.wait()/256 if istat == 0: if entry.attrib.get('verify', 'true') == 'true': if self.setup['quick']: return True - verp=Popen4("rpm --verify --nomd5 -q %s-%s"%(entry.attrib['name'],entry.attrib['version']), bufsize=16384) - odata='' - vstat=verp.poll() + verp = Popen4("rpm --verify --nomd5 -q %s-%s" % + (entry.attrib['name'],entry.attrib['version']), bufsize=16384) + odata = '' + vstat = verp.poll() while vstat == -1: - odata+=verp.fromchild.read() - vstat=verp.poll() >> 8 - output=filter(lambda x:x,odata.split('\n')) + odata += verp.fromchild.read() + vstat = verp.poll() >> 8 + output = [x for x in odata.split("\n") if x] if vstat == 0: return True else: @@ -93,13 +85,13 @@ class Redhat(Toolset): self.pkgtodo.append(entry) return False - def Commit(self, entrystate): + def Install(self): # try single install - rc = system(self.rpmcmd%(join(map(lambda x:x.attrib['url'], self.pkgtodo)))) + rc = system(self.rpmcmd % (" ".join([x.attrib['url'] for x in self.pkgtodo]))) if rc == 0: # set state == True for all just-installed packages for pkg in self.pkgtodo: - entrystate[x] = True + self.states[pkg] = True self.pkgtodo = [] else: # fall back to single package installs @@ -109,10 +101,10 @@ class Redhat(Toolset): for entry in self.pkgtodo: rc = system(self.rpmcmd%(entry.attrib['url'])) if rc == 0: - entrystate[entry] = True + self.states[entry] = True self.pkgtodo.remove(entry) else: if self.setup['verbose']: - print "package %s-%s failed to install"%(entry.attrib['name'], entry.attrib['version']) + print "package %s-%s failed to install" % (entry.attrib['name'], entry.attrib['version']) diff --git a/src/lib/Client/Toolset.py b/src/lib/Client/Toolset.py index 5f338d17f..f30be7c11 100644 --- a/src/lib/Client/Toolset.py +++ b/src/lib/Client/Toolset.py @@ -4,24 +4,20 @@ from binascii import a2b_base64 from grp import getgrgid, getgrnam from os import chown, chmod, lstat, mkdir, stat, system, unlink, rename, readlink, symlink from pwd import getpwuid, getpwnam -from stat import * -from string import join, split +from stat import S_ISVTX, S_ISGID, S_ISUID, S_IXUSR, S_IWUSR, S_IRUSR, S_IXGRP +from stat import S_IWGRP, S_IRGRP, S_IXOTH, S_IWOTH, S_IROTH, ST_MODE, S_ISDIR +from stat import S_IFREG, ST_UID, ST_GID, S_ISREG, S_IFDIR, S_ISLNK from sys import exc_info from time import asctime, localtime from traceback import extract_tb from elementtree.ElementTree import Element, SubElement, tostring -def print_failure(): - if '-v' in argv: print "\033[60G[\033[1;31mFAILED\033[0;39m]\r" - -def print_success(): - if '-v' in argv: print "\033[60G[ \033[1;32mOK\033[0;39m ]\r" - -def CalcPerms(initial,perms): +def CalcPerms(initial, perms): tempperms = initial - if len(perms) == 3: perms = '0%s'%(perms) - (s,u,g,o) = map(int, map(lambda x:perms[x], range(4))) + if len(perms) == 3: + perms = '0%s' % (perms) + [s, u, g, o] = [perms[int(x)] for x in range(4)] if s & 1: tempperms |= S_ISVTX if s & 2: @@ -66,25 +62,33 @@ class Toolset(object): def LogFailure(self, area, entry): '''Print tracebacks in unexpected cases''' - print "Failure in %s for entry: %s"%(area, tostring(entry)) - (t,v,tb) = exc_info() + print "Failure in %s for entry: %s" % (area, tostring(entry)) + (t, v, tb) = exc_info() for line in extract_tb(tb): - print "File %s, line %i, in %s\n %s\n"%(line) - print "%s: %s\n"%(t,v) - del t,v,tb + print "File %s, line %i, in %s\n %s\n" % (line) + print "%s: %s\n" % (t, v) + del t, v, tb + + def print_failure(self): + if self.setup['verbose']: + print "\033[60G[\033[1;31mFAILED\033[0;39m]\r" + + def print_success(self): + if self.setup['verbose']: + print "\033[60G[ \033[1;32mOK\033[0;39m ]\r" # These next functions form the external API def Inventory(self): # build initial set of states - unexamined = map(lambda x:(x,[]), self.cfg.getchildren()) + unexamined = [(x, []) for x in self.cfg.getchildren()] while unexamined: (r, modlist) = unexamined.pop() if r.tag not in ['Bundle', 'Independant']: self.VerifyEntry(r, modlist) else: modlist = [x.attrib['name'] for x in r.getchildren() if x.tag == 'ConfigFile'] - unexamined += map(lambda x:(x,modlist), r.getchildren()) + unexamined += [(x, modlist) for x in r.getchildren()] self.structures[r] = False for structure in self.cfg.getchildren(): @@ -100,16 +104,16 @@ class Toolset(object): for entry in structure.getchildren(): self.VerifyEntry(entry, modlist) try: - state = map(lambda x:self.states[x], structure.getchildren()) + state = [self.states[x] for x in structure.getchildren()] if False not in state: self.structures[structure] = True except KeyError, k: - print "State verify evidently failed for %s"%(k) + print "State verify evidently failed for %s" % (k) self.structures[structure] = False def Install(self): - self.modified = [k for (k,v) in self.structures.iteritems() if not v] - for entry in [k for (k,v) in self.states.iteritems() if not v]: + self.modified = [k for (k, v) in self.structures.iteritems() if not v] + for entry in [k for (k, v) in self.states.iteritems() if not v]: self.InstallEntry(entry) def Commit(self): @@ -120,11 +124,11 @@ class Toolset(object): def GenerateStats(self): '''Generate XML summary of execution statistics''' stats = Element("Statistics") - SubElement(stats, "Structures", good=str(len([k for k,v in self.structures.iteritems() if v])), \ - bad=str(len([k for k,v in self.structures.iteritems() if not v]))) - SubElement(stats, "Entries", good=str(len([k for k,v in self.states.iteritems() if v])), \ - bad=str(len([k for k,v in self.states.iteritems() if not v]))) - if len([k for k,v in self.structures.iteritems() if not v]) == 0: + SubElement(stats, "Structures", good=str(len([k for k, v in self.structures.iteritems() if v])), \ + bad=str(len([k for k, v in self.structures.iteritems() if not v]))) + SubElement(stats, "Entries", good=str(len([k for k, v in self.states.iteritems() if v])), \ + bad=str(len([k for k, v in self.states.iteritems() if not v]))) + if len([k for k, v in self.structures.iteritems() if not v]) == 0: stats.attrib['state'] = 'clean' else: stats.attrib['state'] = 'dirty' @@ -173,7 +177,7 @@ class Toolset(object): if S_ISREG(fmode) or S_ISLNK(fmode): unlink(entry.attrib['name']) elif S_ISDIR(fmode): - system("mv %s/ %s.bak"%(entry.attrib['name'], entry.attrib['name'])) + system("mv %s/ %s.bak" % (entry.attrib['name'], entry.attrib['name'])) else: unlink(entry.attrib['name']) except OSError, e: @@ -185,16 +189,16 @@ class Toolset(object): def VerifyDirectory(self, entry): try: - ondisk=stat(entry.attrib['name']) + ondisk = stat(entry.attrib['name']) except OSError: return False try: - owner=getpwuid(ondisk[ST_UID])[0] - group=getgrgid(ondisk[ST_GID])[0] + owner = getpwuid(ondisk[ST_UID])[0] + group = getgrgid(ondisk[ST_GID])[0] except OSError: - owner='root' - group='root' - perms=stat(entry.attrib['name'])[ST_MODE] + owner = 'root' + group = 'root' + perms = stat(entry.attrib['name'])[ST_MODE] if ((owner == entry.attrib['owner']) and (group == entry.attrib['group']) and (perms == CalcPerms(S_IFDIR, entry.attrib['perms']))): @@ -217,26 +221,27 @@ class Toolset(object): except OSError: return False try: - chown(entry.attrib['name'],getpwnam(self.attrib['owner'])[2],getgrnam(entry.attrib['group'])[2]) - chmod(entry.attrib['name'],entry.attrib['perms']) + chown(entry.attrib['name'], + getpwnam(entry.attrib['owner'])[2], getgrnam(entry.attrib['group'])[2]) + chmod(entry.attrib['name'], entry.attrib['perms']) except: return False def VerifyConfigFile(self, entry): try: - ondisk=stat(entry.attrib['name']) + ondisk = stat(entry.attrib['name']) except OSError: return False try: - data=open(entry.attrib['name']).read() + data = open(entry.attrib['name']).read() except IOError: return False try: - owner=getpwuid(ondisk[ST_UID])[0] - group=getgrgid(ondisk[ST_GID])[0] + owner = getpwuid(ondisk[ST_UID])[0] + group = getgrgid(ondisk[ST_GID])[0] except KeyError: return False - perms=stat(entry.attrib['name'])[ST_MODE] + perms = stat(entry.attrib['name'])[ST_MODE] if entry.attrib.get('encoding', 'ascii') == 'base64': tempdata = a2b_base64(entry.text) else: @@ -248,10 +253,10 @@ class Toolset(object): def InstallConfigFile(self, entry): if self.setup['dryrun'] or self.setup['verbose']: - print "Installing ConfigFile %s"%(entry.attrib['name']) + print "Installing ConfigFile %s" % (entry.attrib['name']) if self.setup['dryrun']: return False - parent = join(split(entry.attrib['name'],"/")[:-1],"/") + parent = "/".join(entry.attrib['name'].split('/')[:-1]) if parent: try: s = lstat(parent) @@ -276,7 +281,7 @@ class Toolset(object): newfile.close() chown(newfile.name, getpwnam(entry.attrib['owner'])[2], getgrnam(entry.attrib['group'])[2]) chmod(newfile.name, CalcPerms(S_IFREG, entry.attrib['perms'])) - if entry.attrib.get("paranoid", False) and setup.get("paranoid", False): + if entry.attrib.get("paranoid", False) and self.setup.get("paranoid", False): system("diff -u %s %s.new"%(entry.attrib['name'], entry.attrib['name'])) rename(newfile.name, entry.attrib['name']) return True diff --git a/src/lib/Server/Generator.py b/src/lib/Server/Generator.py index 4e43dc562..85b187043 100644 --- a/src/lib/Server/Generator.py +++ b/src/lib/Server/Generator.py @@ -30,7 +30,7 @@ class Generator(object): def CompleteSetup(self): self.ReadAll() - print "%s loaded"%(self.__version__) + print "%s loaded" % (self.__version__) def Cron(self): '''Cron defines periodic tasks to maintain data coherence''' @@ -69,13 +69,15 @@ class FileBacked(object): This object is meant to be used as a part of DirectoryBacked.''' def __init__(self, name): + object.__init__(self) + self.data = '' self.name = name self.HandleEvent() def HandleEvent(self, event=None): try: self.data = file(self.name).read() - except IOError, e: + except IOError: syslog(LOG_ERR, "Failed to read file %s" % (self.name)) self.Index() @@ -87,6 +89,7 @@ class DirectoryBacked(object): __child__ = FileBacked def __init__(self, name, fam): + object.__init__(self) self.name = name self.fam = fam self.entries = {} @@ -131,12 +134,12 @@ class XMLFileBacked(FileBacked): def Index(self): try: - a = XML(self.data) + xdata = XML(self.data) except: syslog(LOG_ERR, "Failed to parse %s"%(self.name)) return - self.label = a.attrib[self.__identifier__] - self.entries = a.getchildren() + self.label = xdata.attrib[self.__identifier__] + self.entries = xdata.getchildren() def __iter__(self): return iter(self.entries) @@ -159,12 +162,12 @@ class ScopedXMLFile(SingleXMLFileBacked): def Index(self): try: - a = XML(self.data) + xdata = XML(self.data) except: syslog(LOG_ERR, "Failed to parse %s"%(self.name)) return self.store = {} - for e in a.getchildren(): + for e in xdata.getchildren(): if e.tag not in self.__containers__: self.StoreRecord(('Global','all'), e) else: diff --git a/src/lib/Server/Metadata.py b/src/lib/Server/Metadata.py index 5346dd5cf..21ac519a0 100644 --- a/src/lib/Server/Metadata.py +++ b/src/lib/Server/Metadata.py @@ -1,60 +1,14 @@ #!/usr/bin/env python -from elementtree.ElementTree import XML, tostring, SubElement -from time import localtime, mktime - -from Generator import SingleXMLFileBacked - '''This file stores persistent metadata for the BCFG Configuration Repository''' +__revision__ = '$Revision$' -class NodeStatistics(object): - '''Statistics type for Nodes. - self.last => time of last successful run - self.status => final status of last run - self.changeset -> the id of the last config successfully configured - self.count => number of times client run - self.fail => failure count''' - - def __init__(self): - self.last = 0 - self.status = False - self.changeset = 0 - self.count = 0 - self.fail = 0 - - def GetStats(self): - return (self.status, self.count, self.last, self.fail) - - def Suceed(self,changeset): - self.count += 1 - self.last = mktime(localtime()) - self.status = True - self.changeset=changeset - - def Fail(self,changeset): - self.count += 1 - self.fail += 1 - self.status = False - -class Client(object): - def __init__(self,name,image,tags): - self.name = name - self.image = image - self.tags = tags - self.stats = NodeStatistics() - self.dirty = [] - - def UpdateStats(self,status,changeset): - if status: - self.stats.Suceed(changeset) - else: - self.stats.Fail(changeset) +from elementtree.ElementTree import XML, tostring, SubElement - def GetStats(self): - return self.stats.GetStats() +from Bcfg2.Server.Generator import SingleXMLFileBacked class ConfigurationRegion(object): - def __init__(self,name,scope,stype): + def __init__(self, name, scope, stype): self.name = name self.scope = scope self.stype = stype @@ -84,8 +38,9 @@ class Metadata(object): class Profile(object): def __init__(self, xml): - self.classes = map(lambda x:x.attrib['name'], xml.findall("Class")) - self.attributes = map(lambda x:"%s.%s"%(x.attrib['scope'],x.attrib['name']), xml.findall("Attribute")) + object.__init__(self) + self.classes = [x.attrib['name'] for x in xml.findall("Class")] + self.attributes = ["%s.%s" % (x.attrib['scope'], x.attrib['name']) for x in xml.findall("Attribute")] class MetadataStore(SingleXMLFileBacked): def Index(self): @@ -99,16 +54,16 @@ class MetadataStore(SingleXMLFileBacked): for c in self.element.findall("Client"): self.clients[c.attrib['name']] = (c.attrib['image'], c.attrib['profile']) for c in self.element.findall("Class"): - self.classes[c.attrib['name']] = map(lambda x:x.attrib['name'], c.findall("Bundle")) - for (k,v) in self.element.attrib.iteritems(): + self.classes[c.attrib['name']] = [x.attrib['name'] for x in c.findall("Bundle")] + for (k, v) in self.element.attrib.iteritems(): if k[:8] == 'default_': self.defaults[k[8:]] = v - def FetchMetadata(self,client, image=None, profile=None): + def FetchMetadata(self, client, image=None, profile=None): if ((image != None) and (profile != None)): # Client asserted profile/image - self.clients[client] = (image,profile) - f = filter(lambda x:x.attrib['name'] == client, self.element.findall("Client")) + self.clients[client] = (image, profile) + f = [x for x in self.element.findall("Client") if x.attrib['name'] == client] if len(f) == 0: # non-existent client SubElement(self.element, "Client", name=client, image=image, profile=profile) @@ -119,15 +74,15 @@ class MetadataStore(SingleXMLFileBacked): f[0].attrib['image'] = image self.WriteBack() elif self.clients.has_key(client): - (image,profile) = self.clients[client] + (image, profile) = self.clients[client] else: # default profile stuff goes here - (image,profile) = (self.defaults['image'], self.defaults['profile']) + (image, profile) = (self.defaults['image'], self.defaults['profile']) SubElement(self.element, "Client", name=client, profile=profile, image=image) self.WriteBack() p = self.profiles[profile] # should we uniq here? V - bundles = reduce(lambda x,y:x+y, map(self.classes.get, p.classes)) + bundles = reduce(lambda x, y:x + y, [self.classes.get[x] for x in p.classes]) return Metadata(False, image, p.classes, bundles, p.attributes, client) def WriteBack(self): -- cgit v1.2.3-1-g7c22