summaryrefslogtreecommitdiffstats
path: root/lib/sunhpc/core/files.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sunhpc/core/files.py')
-rw-r--r--lib/sunhpc/core/files.py445
1 files changed, 445 insertions, 0 deletions
diff --git a/lib/sunhpc/core/files.py b/lib/sunhpc/core/files.py
new file mode 100644
index 0000000..886a059
--- /dev/null
+++ b/lib/sunhpc/core/files.py
@@ -0,0 +1,445 @@
+#coding:utf-8
+import os
+import re
+import sys
+import stat
+import time
+import shutil
+import string
+import xml.sax
+import datetime
+
+class File:
+
+ def __init__(self, file, timestamp=None, size=None):
+ self.setFile(file, timestamp, size)
+ self.imortal = 0
+
+ def __cmp__(self, file):
+ if self.getBaseName() != file.getBaseName() or \
+ self.timestamp == file.timestamp:
+ rc = 0
+ elif self.timestamp > file.timestamp:
+ rc = 1
+ else:
+ rc = -1
+
+ if rc and self.imortal + file.imortal == 1:
+ if self.imortal:
+ rc = 1
+ else:
+ rc = -1
+
+ return rc
+
+ def setFile(self, file, timestamp=None, size=None):
+ self.pathname = os.path.dirname(file)
+ self.filename = os.path.basename(file)
+
+ if None not in (timestamp, size):
+ self.timestamp = timestamp
+ self.size = size
+ elif not os.path.islink(file):
+ self.timestamp = os.path.getmtime(file)
+ self.size = os.path.getsize(file)
+ else:
+ orig = os.readlink(file)
+ if os.path.isfile(orig):
+ self.timestamp = os.path.getmtime(orig)
+ self.size = os.path.getsize(file)
+ else:
+ self.timestamp = 0
+ self.size = 0
+
+ def explode(self):
+
+ file = self.getFullName()
+ if os.path.islink(file):
+ orig = os.readlink(file)
+ if os.path.isfile(orig):
+ os.unlink(file)
+ shutil.copy2(orig, file)
+
+ tm = os.path.getmtime(orig)
+ os.utime(file, (tm, tm))
+
+ def setImortal(self):
+ self.imortal = 1
+
+ def getTimestamp(self):
+ return self.timestamp
+
+ def getSize(self):
+ return float(self.size) / (1024*1024)
+
+ def getUniqueName(self):
+ return self.filename
+
+ def getBaseName(self):
+ return self.filename
+
+ def getName(self):
+ return self.filename
+
+ def getShortName(self):
+ return os.path.splitext(self.filename)[0]
+
+ def getPath(self):
+ return self.pathname
+
+ def getFullName(self):
+ return str(os.path.join(self.pathname, self.filename))
+
+ def getFileMode(self):
+ return self.getMode(self.getFullName())
+
+ def getMode(self, path):
+ dirs = os.stat(path)
+ mode = oct(dirs.st_mode)[-3:] # 目录权限0o750 -3:750
+ return (mode, dirs.st_uid, dirs.st_gid)
+
+ def symlink(self, target, base=''):
+ if os.path.isfile(target) or os.path.islink(target):
+ os.unlink(target)
+ os.symlink(self.getFullName(), target)
+
+ def chmod(self, mode):
+ # python2 : 0664
+ # python3 : 0o664
+ if os.path.exists(self.getFullName()):
+ os.chmod(self.getFullName(), mode)
+
+ def dump(self):
+ print ('%s(%s)' % (self.filename, self.pathname))
+
+class Tree:
+
+ def __init__(self, root):
+ self.root = root
+ self.tree = {}
+ self.build('')
+
+ def getRoot(self):
+ return self.root
+
+ def getDirs(self):
+ return list(self.tree.keys())
+
+ def getSize(self):
+ len = 0
+ for key in self.tree.keys():
+ for file in self.tree[key]:
+ len = len + file.getSize()
+ return float(len)
+
+ def getFiles(self, path=''):
+
+ try:
+ list = self.tree[path]
+ except KeyError:
+ list = []
+ return list
+
+ def setFiles(self, path, files):
+ self.tree[path] = files
+
+ def build(self, dir):
+ path = os.path.join(self.root, dir)
+ if not os.path.isdir(path):
+ return
+
+ try:
+ files = os.listdir(path)
+ # 移除python缓存文件夹
+ if '__pycache__' in files: files.remove('__pycache__')
+ except:
+ files = []
+
+ v = []
+ for f in files:
+ filepath = os.path.join(path, f)
+ if os.path.isdir(filepath) and not \
+ os.path.islink(filepath):
+ self.build(os.path.join(dir, f))
+ else:
+ if re.match('.*\.rpm$', f) != None:
+ v.append(RPMFile(filepath))
+ elif re.match('roll-.*\.iso$', f) != None:
+ v.append(RollFile(filepath))
+ else:
+ v.append(File(filepath))
+ self.tree[dir] = v
+
+ def apply(self, func, root=None):
+ for key in self.tree.keys():
+ for e in self.tree[key]:
+ func(key, e, root)
+
+
+class RPMBaseFile(File):
+
+ def __init__(self, file, timestamp=None, size=None, ext=1):
+ File.__init__(self, file, timestamp, size)
+ self.list = []
+
+ s = self.filename # name-ver-rpmver.arch.rpm
+ for x in range(0, ext):
+ i = s.rfind(".")
+ s = self.filename[:i]
+
+ i = s.rfind(".")
+ self.list.append(s[i+1:]) # get architecture string
+ s = self.filename[:i]
+
+ i = s.rfind("-") # get RPM version string
+ self.release = s[i+1:]
+ self.list.append(self.versionList(s[i+1:]))
+ s = self.filename[:i]
+
+ i = s.rfind("-") # get software version string
+ self.version = s[i+1:]
+ self.list.append(self.versionList(s[i+1:]))
+ self.list.append(self.filename[:i]) # get package name
+ self.list.reverse() # we built the list backwards
+
+ def versionList(self, s):
+ list = []
+ for e in re.split('\.+|_+', s):
+ l = []
+ num = ''
+ alpha = ''
+ for c in e:
+ if c in string.digits:
+ num = num + c
+ if alpha:
+ l.append(alpha)
+ alpha = ''
+ else:
+ alpha = alpha + c
+ if num:
+ l.append(num)
+ num = ''
+ if alpha:
+ l.append(alpha)
+ if num:
+ l.append(num)
+ list.append(l)
+ return list
+
+ def getBaseName(self):
+ return self.list[0]
+
+ def getUniqueName(self):
+ return '%s-%s' % (self.list[0], self.list[3])
+
+class RPMFile(RPMBaseFile):
+
+ def __init__(self, file, timestamp=None, size=None):
+ RPMBaseFile.__init__(self, file, timestamp, size)
+
+ def __cmp__(self, file):
+ if self.getPackageArch() != file.getPackageArch():
+ rc = 0
+ else:
+ if abs(int(self.timestamp) - int(file.timestamp)) < 120 :
+ # print "CMP %s:%s" % (self.getFullName(), file.getFullName())
+ f1=os.popen("rpm -qp --qf '%%{BUILDTIME}' %s" % self.getFullName())
+ self.timestamp=float(f1.readline())
+ f1.close()
+ f2=os.popen("rpm -qp --qf '%%{BUILDTIME}' %s" % file.getFullName())
+ file.timestamp=float(f2.readline())
+ f2.close()
+
+ rc = File.__cmp__(self, file)
+ return rc
+
+ def getPackageName(self):
+ return self.getBaseName()
+
+ def getPackageVersion(self):
+ return self.list[1]
+
+ def getPackageRelease(self):
+ return self.list[2]
+
+ def getPackageVersionString(self):
+ return self.version
+
+ def getPackageReleaseString(self):
+ return self.release
+
+ def getPackageArch(self):
+ return self.list[3]
+
+class RollInfoFile(File,
+ xml.sax.handler.ContentHandler, xml.sax.handler.DTDHandler,
+ xml.sax.handler.EntityResolver, xml.sax.handler.ErrorHandler):
+
+ def __init__(self, file):
+ File.__init__(self, file)
+
+ self.attrs = {}
+ parser = xml.sax.make_parser()
+ parser.setContentHandler(self)
+ fin = open(file, 'r')
+ parser.parse(fin)
+ fin.close()
+
+ def startElement(self, name, attrs):
+ self.attrs[str(name)] = {}
+ for (attrName, attrVal) in attrs.items():
+ self.attrs[str(name)][str(attrName)] = str(attrVal)
+
+ def getXML(self):
+
+ xml = []
+ xml.append('<roll name="%s" interface="%s">' %
+ (self.getRollName(), self.getRollInterface()))
+ for tag in self.attrs.keys():
+ if tag == 'roll':
+ continue
+ attrs = ''
+ for key,val in self.attrs[tag].items():
+ attrs += ' %s="%s"' % (key, val)
+ xml.append('\t<%s%s/>' % (tag, attrs))
+ xml.append('</roll>')
+
+ return string.join(xml, '\n')
+
+ def getRollName(self):
+ return self.attrs['roll']['name']
+
+ def getRollInterface(self):
+ return self.attrs['roll']['interface']
+
+ def getRollVersion(self):
+ return self.attrs['info']['version']
+
+ def getRollRelease(self):
+ return self.attrs['info']['release']
+
+ def setRollOS(self, os):
+ self.attrs['info']['os'] = os
+
+ def getRollOS(self):
+ try:
+ return self.attrs['info']['os']
+ except KeyError:
+ return 'linux'
+
+ def setRollArch(self, arch):
+ self.attrs['info']['arch'] = arch
+
+ def getRollArch(self):
+ return self.attrs['info']['arch']
+
+ def getISOMaxSize(self):
+ return float(self.attrs['iso']['maxsize'])
+
+ def setISOMaxSize(self, size):
+ self.attrs['iso']['maxsize'] = size
+
+ def getISOFlags(self):
+ return self.attrs['iso']['mkisofs']
+
+ def getRollRolls(self):
+ return self.attrs['rpm']['rolls']
+
+ def isBootable(self):
+ return int(self.attrs['iso']['bootable'])
+
+ def hasRolls(self):
+ if self.attrs['rpm']['rolls'] != '0':
+ return 1
+ else:
+ return 0
+
+ def hasRPMS(self):
+ return int(self.attrs['rpm']['bin'])
+
+ def hasSRPMS(self):
+ return int(self.attrs['rpm']['src'])
+
+ def getDepsName(self):
+ return self.attrs['deps']['name']
+
+ def getDepsHost(self):
+ return self.attrs['deps']['host']
+
+class RPMbuild:
+ def __init__(self, root):
+ self.root = root
+ self.tree = {}
+ self.fulldirs = {}
+ self.build('')
+
+ def getRoot(self):
+ return self.root
+
+ def getRootName(self):
+ return self.root.split('/')[-1]
+
+ def getRootMode(self):
+ return self.getMode(self.root)
+
+ def getPathMode(self, path):
+ return self.getMode(path)
+
+ def getMode(self, path):
+ dirs = os.stat(path)
+ mode = oct(dirs.st_mode)[-3:] # 目录权限0o750 -3:750
+ return (mode, dirs.st_uid, dirs.st_gid)
+
+ def getDirs(self):
+ return list(self.tree.keys())
+
+ def getDirMode(self, path):
+ return self.fulldirs[path]
+
+ def getFiles(self, path=''):
+ try:
+ list = self.tree[path]
+ except KeyError:
+ list = []
+ return list
+
+ def build(self, dir):
+
+ path = os.path.join(self.root, dir)
+ if not os.path.isdir(path):
+ return
+
+ try:
+ files = os.listdir(path)
+ # 移除python缓存文件夹
+ #if '__pycache__' in files: files.remove('__pycache__')
+ except:
+ raise
+ files = []
+
+ v = []
+ for f in files:
+ filepath = os.path.join(path, f)
+ if os.path.isdir(filepath) and not os.path.islink(filepath):
+ self.build(os.path.join(dir, f))
+ else:
+ v.append(File(filepath))
+
+ dirs = os.stat(path)
+ mode = oct(dirs[stat.ST_MODE])[-3:] # 目录权限0o750 -3:750
+ uid = dirs.st_uid #目录的uid
+ gid = dirs.st_gid #目录的gid
+
+ # 格式: (dirname, owner, uid, gid)
+ self.fulldirs[dir] = (mode, uid, gid)
+ self.tree[dir] = v
+
+
+
+
+
+
+
+
+
+