[csw-devel] SF.net SVN: gar:[18135] csw/mgar/gar/v2-solaris11/lib/python/system_pkgmap. py
chninkel at users.sourceforge.net
chninkel at users.sourceforge.net
Sun May 27 22:46:00 CEST 2012
Revision: 18135
http://gar.svn.sourceforge.net/gar/?rev=18135&view=rev
Author: chninkel
Date: 2012-05-27 20:45:59 +0000 (Sun, 27 May 2012)
Log Message:
-----------
also read pkg contents and info from IPS in Solaris >= 5.11
Modified Paths:
--------------
csw/mgar/gar/v2-solaris11/lib/python/system_pkgmap.py
Modified: csw/mgar/gar/v2-solaris11/lib/python/system_pkgmap.py
===================================================================
--- csw/mgar/gar/v2-solaris11/lib/python/system_pkgmap.py 2012-05-27 20:38:02 UTC (rev 18134)
+++ csw/mgar/gar/v2-solaris11/lib/python/system_pkgmap.py 2012-05-27 20:45:59 UTC (rev 18135)
@@ -109,6 +109,59 @@
pkg_desc = u" ".join(fields[2:])
return pkgname, pkg_desc
+ def _ParsePkgListLine(self, line):
+ fields = re.split(c.WS_RE, line)
+ pkgname = fields[0]
+ desc_field_start = 1
+ # The optional publisher field is always between
+ # parenthesis, we skip it if necessary
+ if fields[desc_field_start].startswith("("):
+ desc_field_start += 1
+ pkg_desc = u" ".join(fields[desc_field_start:])
+ return pkgname, pkg_desc
+
+ def _ParsePkgContentsLine(self, line):
+ """Parses one line of "pkg contents" output
+
+ Returns: A dictionary of fields, or none.
+ """
+ # we will map from IPS type to SVR4 type
+ type_mapping = { 'link': 's', 'hardlink': 'l', 'file': 'f', 'dir': 'd' }
+
+ parts = re.split(c.WS_RE, line.strip())
+ if len(parts) < 4:
+ raise ParsingError("Line does not have enough fields: %s"
+ % repr(parts))
+ # paths are relative to "/" in pkg contents output
+ f_path = "/" + parts[0]
+ f_target = None
+ try:
+ f_type = type_mapping[parts[1]]
+ except:
+ raise ParsingError("Wrong file type: %s in %s"
+ % (repr(parts[1]), repr(line)))
+ f_mode = None
+ f_owner = None
+ f_group = None
+ f_pkgname = None
+ pkgnames = [ parts[2] ]
+ if f_type == 's' or f_type == 'l':
+ f_target = parts[3]
+ else:
+ (f_mode, f_owner, f_group) = parts[3:6]
+
+ d = {
+ "path": f_path,
+ "target": f_target,
+ "type": f_type,
+ "mode": f_mode,
+ "owner": f_owner,
+ "group": f_group,
+ "pkgnames": pkgnames,
+ "line": line,
+ }
+ return d
+
def _ParsePkgmapLine(self, line):
"""Parses one line of /var/sadm/install/contents.
@@ -207,20 +260,23 @@
}
return d
- def _ParseInstallContents(self, stream, show_progress):
+ def _ParseInstallContents(self, streams, show_progress):
logging.debug("-> _ParseInstallContents()")
parsed_lines = []
c = itertools.count()
# Progressbar stuff can go here.
- for line in stream:
- if show_progress:
- if not c.next() % 1000:
- sys.stdout.write(".")
- sys.stdout.flush()
- d = self._ParsePkgmapLine(line)
- # d might be None if line was a comment
- if d:
- parsed_lines.append(d)
+ streams_and_parsers = zip(streams, (self._ParsePkgmapLine, self._ParsePkgContentsLine))
+ for stream_info in streams_and_parsers:
+ parseMethod = stream_info[1]
+ for line in stream_info[0]:
+ if show_progress:
+ if not c.next() % 1000:
+ sys.stdout.write(".")
+ sys.stdout.flush()
+ d = parseMethod(line)
+ # d might be None if line was a comment
+ if d:
+ parsed_lines.append(d)
if show_progress:
sys.stdout.write("\n")
logging.debug("<- _ParseInstallContents()")
@@ -247,7 +303,7 @@
def _GetArch(self):
return self._GetUname("-p")
- def GetDataStructure(self, contents_stream, pkginfo_stream, osrel, arch,
+ def GetDataStructure(self, contents_streams, pkginfo_streams, osrel, arch,
show_progress=False):
"""Gets the data structure to be pickled.
@@ -256,17 +312,17 @@
data = {
"osrel": osrel,
"arch": arch,
- "contents": self._ParseInstallContents(contents_stream, show_progress),
- "pkginfo": self._ParsePkginfoOutput(pkginfo_stream, show_progress),
+ "contents": self._ParseInstallContents(contents_streams, show_progress),
+ "pkginfo": self._ParsePkginfoOutput(pkginfo_streams, show_progress),
}
return data
def Index(self, show_progress=False):
# This function interacts with the OS.
- contents_stream = open(self.infile_contents, "r")
- pkginfo_stream = self._GetPkginfoStream()
+ contents_streams = self._GetPkgcontentsStreams()
+ pkginfo_streams = self._GetPkginfoStreams()
data = self.GetDataStructure(
- contents_stream, pkginfo_stream, self.osrel, self.arch, show_progress)
+ contents_streams, pkginfo_streams, self.osrel, self.arch, show_progress)
return data
def IndexAndSave(self):
@@ -277,24 +333,53 @@
cPickle.dump(data, out_fd, cPickle.HIGHEST_PROTOCOL)
logging.debug("IndexAndSave(): pickling done.")
- def _GetPkginfoStream(self):
+ def _GetPkgcontentsStreams(self):
+ contents_stream = open(self.infile_contents, "r")
+
+ if self.osrel in ["SunOS5.9", "SunOS5.10"]:
+ pkgcontents_stream = None
+ else:
+ args = ["pkg", "contents", "-H", "-o",
+ "path,action.name,pkg.name,target,mode,owner,group",
+ "-t", "dir,file,hardlink,link"]
+ pkg_proc = subprocess.Popen(args, stdout=subprocess.PIPE)
+ stdout, stderr = pkg_proc.communicate()
+ ret = pkg_proc.wait()
+ pkgcontents_stream = stdout.splitlines()
+
+ return (contents_stream, pkgcontents_stream)
+
+ def _GetPkginfoStreams(self):
"""Calls pkginfo if file is not specified."""
if self.infile_pkginfo:
- return open(self.infile_pkginfo, "r")
+ pkginfo_stream = open(self.infile_pkginfo, "r")
else:
args = ["pkginfo"]
pkginfo_proc = subprocess.Popen(args, stdout=subprocess.PIPE)
stdout, stderr = pkginfo_proc.communicate()
ret = pkginfo_proc.wait()
pkginfo_stream = stdout.splitlines()
- return pkginfo_stream
- def _ParsePkginfoOutput(self, pkginfo_stream, unused_show_progress):
+ if self.osrel in ["SunOS5.9", "SunOS5.10"]:
+ pkglist_stream = None
+ else:
+ args = ["pkg", "list", "-H", "-s"]
+ pkg_proc = subprocess.Popen(args, stdout=subprocess.PIPE)
+ stdout, stderr = pkg_proc.communicate()
+ ret = pkg_proc.wait()
+ pkglist_stream = stdout.splitlines()
+
+ return (pkginfo_stream, pkglist_stream)
+
+ def _ParsePkginfoOutput(self, streams, unused_show_progress):
logging.debug("-> _ParsePkginfoOutput()")
packages_by_pkgname = {}
- for line in pkginfo_stream:
+ for line in streams[0]:
pkgname, pkg_desc = self._ParsePkginfoLine(line)
packages_by_pkgname.setdefault(pkgname, pkg_desc)
+ for line in streams[1]:
+ pkgname, pkg_desc = self._ParsePkgListLine(line)
+ packages_by_pkgname.setdefault(pkgname, pkg_desc)
logging.debug("<- _ParsePkginfoOutput()")
return packages_by_pkgname
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the devel
mailing list