diff --git a/src/mio.py b/src/mio.py index 31152143df87403614fb162d420cfafc3ac3def7..465cf50c465c807fd073780065ed9e103cefdfd6 100755 --- a/src/mio.py +++ b/src/mio.py @@ -287,7 +287,8 @@ if __name__ == '__main__': options.exclude_rpm) log(NORMAL, "Testing files") - installer.test_groups(options.prefix) + installer.test_groups(options.prefix, + (options.backup, options.backup_suffix)) if options.install: installer = mio.installer.Installer(rules) diff --git a/src/mio/installer.py b/src/mio/installer.py index 7eed9762cc273dd6dc9eee5ace2cfd06a6c8ebce..a945b0f01e0141fd7d7d03b2e83662214d4917c7 100755 --- a/src/mio/installer.py +++ b/src/mio/installer.py @@ -7,12 +7,27 @@ from mio.node import * from mio.exception import * from mio.log import log, VERBOSE, CHATTY +try: + from collections import OrderedDict + pass +except ImportError: + try: + # 2.6 fallback if installed + from ordereddict import OrderedDict + pass + except ImportError: + # Use unordered dict if everything else fails + OrderedDict = dict + log(NORMAL, "No OrderedDict found") + pass + pass + class Installer: def __init__(self, repository): self.repository = repository self.rpmdir = [] self.group = {} - self.rpm = {} + self.rpm = OrderedDict() self.dir = {} self.file = {} self.symlink = {} @@ -160,7 +175,7 @@ class Installer: for r in self.rpm: rpms.append(str(r.name)) pass - rpms.sort() + #rpms.sort() return rpms def install_rpms(self, path, exclude): @@ -175,7 +190,7 @@ class Installer: def not_excluded(name): return not any(map(lambda x: fnmatch.fnmatch(name, x), exclude)) rpm = filter(not_excluded, rpm) - rpm.sort() + #rpm.sort() print rpm mio.yum.run(path + self.rpmdir, rpm, exclude) version_db = mio.rpmDB.VersionDB() @@ -191,8 +206,8 @@ class Installer: return result def install_groups(self, prefix, backup): - for g in self.group: - g.do_pre(prefix, backup) +# for g in self.group: +# g.do_pre(prefix, backup) for g in self.group: g.install(prefix, backup) @@ -200,9 +215,9 @@ class Installer: log(NORMAL, "Excluding rpms: "+ ",".join(exclude)) pass - def test_groups(self, prefix): + def test_groups(self, prefix, backup): for g in self.group: - g.test(prefix) + g.test(prefix, backup) def exclusion_closure(exclude, target): if not target._exclude_: diff --git a/src/mio/node.py b/src/mio/node.py index 71d741cdbec3359d226915b37fa4e3a401bf4d4e..b6704b8293c5021cbc896f31fa97e5d7392e122f 100755 --- a/src/mio/node.py +++ b/src/mio/node.py @@ -49,10 +49,17 @@ class target_node: def __hash__(self): return self.name.__hash__() - def trigged(self, prefix): + def trigged(self, prefix, backup, install=False): if self.is_trigged == None: try: - self.is_trigged = self.do_trig(prefix) + self.is_trigged = self.do_trig(prefix, backup, install) + if self.is_trigged: + if install: + self.do_install(prefix, backup) + else: + self.do_test(prefix) + pass + pass except SystemExit: raise except Exception, e: @@ -60,14 +67,12 @@ class target_node: return self.is_trigged def install(self, prefix, backup): - if self.trigged(prefix) and not self.is_installed: + if not self.is_installed and self.trigged(prefix, backup, install=True): self.is_installed = True - self.do_install(prefix, backup) - def test(self, prefix): - if self.trigged(prefix) and not self.is_tested: + def test(self, prefix, backup): + if not self.is_tested and self.trigged(prefix, backup, install=False): self.is_tested = True - self.do_test(prefix) class group_node(target_node): @@ -109,31 +114,33 @@ class group_node(target_node): def add_post(self, post): self.post.append(post) - def do_trig(self, prefix): - for t in self.target: - if t.trigged(prefix): - return True + def do_trig(self, prefix, backup, install): + result = False for d in self.dependency: - if d.trigged(prefix): - return True - return False + if d.trigged(prefix, backup, install): + result = True + pass + pass + for t in self.target: + if t.trigged(prefix, backup, install): + result = True + pass + pass + return result - def do_pre(self, prefix, backup): - if self.trigged(prefix): - for a in self.pre: - a.run("pre") - def do_install(self, prefix, backup): - for d in self.dependency: - d.install(prefix, backup) +# for d in self.dependency: +# d.install(prefix, backup) + for a in self.pre: + a.run("pre") for t in self.target: t.install(prefix, backup) for a in self.post: a.run("post") def do_test(self, prefix): - for d in self.dependency: - d.test(prefix) +# for d in self.dependency: +# d.test(prefix) for a in self.pre: a.test("pre") for t in self.target: @@ -145,7 +152,7 @@ class rpm_node(target_node): def __init__(self, name, target=None, group=None): target_node.__init__(self, 'rpm', name, target, group) - def do_trig(self, prefix): + def do_trig(self, prefix, backup, do_pre): result = False try: result = self.old_version != self.new_version @@ -164,22 +171,24 @@ class dir_node(target_node): target_node.__init__(self, 'dir', name, decl, group) self.action = [] self.mode = mio.util.dirmode(decl) - self.uid = mio.util.uid(decl) - self.gid = mio.util.gid(decl) + self.owner = mio.util.owner(decl) + self.group = mio.util.group(decl) def assert_identical(self, other): if self.__cmp__(other) != 0: raise Exception("%s %s" % (self.name, other.name)) if self.mode != other.mode: raise ModeException(self, other) - if self.uid != other.uid: + if self.owner != other.owner: raise OwnerException(self, other) - if self.gid != other.gid: + if self.group != other.group: raise GroupException(self, other) - def do_trig(self, prefix): + def do_trig(self, prefix, backup, do_pre): result = False self.target = mio.filecache.locatedir([prefix, self.decl.name[0]]) + self.uid = mio.util.uid(self.owner) + self.gid = mio.util.uid(self.group) if not os.path.exists(self.target): self.action.append(self.mkdir) @@ -231,8 +240,8 @@ class file_node(target_node): self.action = [] if decl: self.mode = mio.util.filemode(decl) - self.uid = mio.util.uid(decl) - self.gid = mio.util.gid(decl) + self.owner = mio.util.owner(decl) + self.group = mio.util.group(decl) self.delete = parse_boolean(self.decl.delete[0]) self.touch = parse_boolean(self.decl.touch_when_copied[0]) @@ -245,9 +254,9 @@ class file_node(target_node): raise SourceException(self, other) if self.decl.files[0:] != other.decl.files[0:]: raise SourceException(self, other) - if self.uid != other.uid: + if self.owner != other.owner: raise OwnerException(self, other) - if self.gid != other.gid: + if self.group != other.group: raise GroupException(self, other) if self.delete != other.delete: raise DeleteException(self, other) @@ -258,10 +267,13 @@ class file_node(target_node): f.close() return digest - def do_trig(self, prefix): + def do_trig(self, prefix, backup, do_pre): result = False dir = os.path.dirname(self.decl._url) self.target = mio.filecache.locatefile([prefix, self.decl.name[0]]) + self.uid = mio.util.uid(self.owner) + self.gid = mio.util.uid(self.group) + if self.delete: if os.path.exists(self.target): if os.path.islink(self.target): @@ -304,7 +316,6 @@ class file_node(target_node): # No source file, we will only set owner and mode tstat = os.stat(self.target) - if self.uid != tstat.st_uid or self.gid != tstat.st_gid: result = True self.action.append(self.chown) @@ -392,8 +403,8 @@ class symlink_node(target_node): target_node.__init__(self, 'symlink', name, decl, group) self.action = [] if decl: - self.uid = mio.util.uid(decl) - self.gid = mio.util.gid(decl) + self.owner = mio.util.owner(decl) + self.group = mio.util.group(decl) self.delete = parse_boolean(self.decl.delete[0]) def assert_identical(self, other): @@ -401,17 +412,19 @@ class symlink_node(target_node): raise Exception("%s %s" % (self.name, other.name)) if self.decl.value[0] == None or self.decl.value[0] != other.decl.value[0]: raise SymlinkValueException(self, other) - if self.uid != other.uid: + if self.owner != other.owner: raise OwnerException(self, other) - if self.gid != other.gid: + if self.group != other.group: raise GroupException(self, other) if self.delete != other.delete: raise DeleteException(self, other) - def do_trig(self, prefix): + def do_trig(self, prefix, backup, do_pre): result = False self.target = mio.filecache.locatedir([prefix, self.decl.name[0]]) + self.uid = mio.util.uid(self.owner) + self.gid = mio.util.uid(self.group) if self.delete: if os.path.exists(self.target): if not os.path.islink(self.target): diff --git a/src/mio/parser.py b/src/mio/parser.py index 111b8c31da0fd9cd5dba8f9a4e929437184f347b..2c4e4a760a16e3f5525b2e27965ffe4bfa645946 100755 --- a/src/mio/parser.py +++ b/src/mio/parser.py @@ -1,7 +1,9 @@ +import calendar import os import stat import sys import time +import xml.sax import xml.parsers.expat import traceback import urlparse @@ -378,7 +380,10 @@ class Node: result += "%s/>\n" % line else: result += "%s>\n" % line - result += xml_escape("".join(self._char)) + if self._char: + result += '\n'.join(self._char) + result += '\n' + pass child = self._children child.sort(TagSortWrapper(self, tag_sort)) for c in child: @@ -431,6 +436,8 @@ class Comment: self._content = content self._line = line self._parent = None + self._tag = '' + self._attribute = { '': content} def __copy__(self): """Copy self""" @@ -452,11 +459,12 @@ class Comment: return self._xml() class Parser: - def __init__(self, url, include_comments=False): - """Parse the given url inti .tree + def __init__(self, data, url=None, mtime=None, include_comments=False): + """Parse the given url into .tree augment the tree with - ._mtime == url modification time if url is a file, 0 otherwise + ._mtime == url modification time if url is a file, + current time otherwise ._url == the url that was parsed """ self.include_comments = include_comments @@ -471,15 +479,8 @@ class Parser: # Parse the url self.current = [ self ] - (scheme, host, path, param, query, frag) = urlparse.urlparse(url) try: - if not scheme: - self.parser.Parse(open(url).read()) - pass - else: - self.parser.Parse(urllib2.urlopen(url).read()) - pass - pass + self.parser.Parse(data) except xml.parsers.expat.ExpatError: reason = xml.parsers.expat.ErrorString(self.parser.ErrorCode) line = self.parser.ErrorLineNumber @@ -487,13 +488,6 @@ class Parser: raise Exception("%s at line %d, column %d in %s" % (reason, line, column, url)) pass - # Set the mtime - mtime = 0 - try: - mtime = os.stat(url)[stat.ST_MTIME] - except Exception,e: - mtime = int(time.time()) - self.tree._mtime = mtime self.tree._url = url @@ -527,7 +521,28 @@ class Parser: parent = self.current[-1] parent._add(Comment(data, self.parser.CurrentLineNumber)) -def parse(url): - """Parse the given 'url' returning an easily traversable tree""" - return Parser(url).tree - +def parse(source, include_comments=False): + """Parse the given 'source' returning an easily traversable tree""" + (scheme, host, path, param, query, frag) = urlparse.urlparse(source) + if not scheme: + data = open(source).read() + mtime = os.stat(source)[stat.ST_MTIME] + pass + else: + u = urllib2.urlopen(source) + data = u.read() + try: + modified = u.info()["Last-Modified"] + mtime = calendar.timegm( + time.strptime(modified, "%a, %d %b %Y %H:%M:%S %Z")) + except: + mtime = None + pass + pass + pass + return Parser(data, url=source, mtime=mtime, + include_comments=include_comments).tree + +def parse_string(source, include_comments=False): + return Parser(source, url=None, mtime=None, + include_comments=include_comments).tree diff --git a/src/mio/util.py b/src/mio/util.py index dcf2d04543b9041c3b764dcdf0ff32e364ac9dd0..e13195267b009c86d446b9791ba39c3f3bcee5a5 100755 --- a/src/mio/util.py +++ b/src/mio/util.py @@ -62,40 +62,41 @@ def dirmode(dir): mode.append(0700) return mode_combine(mode) -def uid(decl): - owner = decl.owner[0:] +def uid(owner): if owner == None: - owner = os.getuid() + uid = os.getuid() pass - if owner.__class__ != int: + elif owner.isdigit(): + uid = int(owner) + pass + else: try: - if owner.isdigit(): - owner = int(owner) - pass - else: - owner = pwd.getpwnam(owner)[2] - pass + uid = pwd.getpwnam(owner)[2] pass except: raise Exception("user '%s' not found" % owner) pass - return owner + return uid -def gid(decl): - group = decl.group[0:] +def gid(group): if group == None: - group = os.getgid() + gid = os.getgid() + pass + elif group.isdigit(): + gid = int(group) pass - if group.__class__ != int: + else: try: - if group.isdigit(): - group = int(group) - pass - else: - group = grp.getgrnam(group)[2] - pass + gid = grp.getgrnam(group)[2] pass except: raise Exception("group '%s' not found" % group) pass - return group + return gid + +def owner(decl): + return decl.owner[0:] + +def group(decl): + return decl.group[0:] +