public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/autodep:master commit in: /
@ 2011-08-21 11:24 Александр Берсенев
  0 siblings, 0 replies; 4+ messages in thread
From: Александр Берсенев @ 2011-08-21 11:24 UTC (permalink / raw
  To: gentoo-commits

commit:     cd034f40e6f1e6d8bcaac924083d7029a2429159
Author:     Alexander Bersenev <bay <AT> hackerdom <DOT> ru>
AuthorDate: Sun Aug 21 17:23:29 2011 +0000
Commit:     Александр Берсенев <bay <AT> hackerdom <DOT> ru>
CommitDate: Sun Aug 21 17:23:29 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/autodep.git;a=commit;h=cd034f40

portage integration patch is added

---
 integration_with_portage.patch |  899 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 899 insertions(+), 0 deletions(-)

diff --git a/integration_with_portage.patch b/integration_with_portage.patch
new file mode 100644
index 0000000..a74beed
--- /dev/null
+++ b/integration_with_portage.patch
@@ -0,0 +1,899 @@
+diff --git a/pym/_emerge/EbuildBuild.py b/pym/_emerge/EbuildBuild.py
+index 0144cfc..1c423a3 100644
+--- a/pym/_emerge/EbuildBuild.py
++++ b/pym/_emerge/EbuildBuild.py
+@@ -9,6 +9,8 @@ from _emerge.CompositeTask import CompositeTask
+ from _emerge.EbuildMerge import EbuildMerge
+ from _emerge.EbuildFetchonly import EbuildFetchonly
+ from _emerge.EbuildBuildDir import EbuildBuildDir
++from _emerge.EventsAnalyser import EventsAnalyser, FilterProcGenerator
++from _emerge.EventsLogger import EventsLogger
+ from _emerge.MiscFunctionsProcess import MiscFunctionsProcess
+ from portage.util import writemsg
+ import portage
+@@ -21,7 +23,7 @@ from portage.package.ebuild._spawn_nofetch import spawn_nofetch
+ class EbuildBuild(CompositeTask):
+ 
+ 	__slots__ = ("args_set", "config_pool", "find_blockers",
+-		"ldpath_mtimes", "logger", "opts", "pkg", "pkg_count",
++		"ldpath_mtimes", "logger", "logserver", "opts", "pkg", "pkg_count",
+ 		"prefetcher", "settings", "world_atom") + \
+ 		("_build_dir", "_buildpkg", "_ebuild_path", "_issyspkg", "_tree")
+ 
+@@ -244,8 +246,54 @@ class EbuildBuild(CompositeTask):
+ 
+ 		build = EbuildExecuter(background=self.background, pkg=pkg,
+ 			scheduler=scheduler, settings=settings)
++
++		build.addStartListener(self._build_start)
++		build.addExitListener(self._build_stop)
++
+ 		self._start_task(build, self._build_exit)
+ 
++	def _build_start(self,phase):
++		if  "depcheck" in self.settings["FEATURES"] or \
++			"depcheckstrict" in self.settings["FEATURES"]:
++			# Lets start a log listening server
++			temp_path=self.settings.get("T",self.settings["PORTAGE_TMPDIR"])
++			
++			if "depcheckstrict" not in self.settings["FEATURES"]:
++				# use default filter_proc
++				self.logserver=EventsLogger(socket_dir=temp_path)
++			else:
++				portage.util.writemsg("Getting list of allowed files..." + \
++					"This may take some time\n")
++				filter_gen=FilterProcGenerator(self.pkg.cpv, self.settings)
++				filter_proc=filter_gen.get_filter_proc()
++				self.logserver=EventsLogger(socket_dir=temp_path, 
++					filter_proc=filter_proc)
++	
++			self.logserver.start()
++			
++			# Copy socket path to LOG_SOCKET environment variable
++			env=self.settings.configdict["pkg"]
++			env['LOG_SOCKET'] = self.logserver.socket_name
++
++			#import pdb; pdb.set_trace()
++
++	def _build_stop(self,phase):
++		if  "depcheck" in self.settings["FEATURES"] or \
++			"depcheckstrict" in self.settings["FEATURES"]:
++			# Delete LOG_SOCKET from environment
++			env=self.settings.configdict["pkg"]
++			if 'LOG_SOCKET' in env:
++				del env['LOG_SOCKET']
++						
++			events=self.logserver.stop()
++			self.logserver=None
++			analyser=EventsAnalyser(self.pkg.cpv, events, self.settings)
++			analyser.display() # show the analyse
++
++			#import pdb; pdb.set_trace()
++	  
++
++
+ 	def _fetch_failed(self):
+ 		# We only call the pkg_nofetch phase if either RESTRICT=fetch
+ 		# is set or the package has explicitly overridden the default
+diff --git a/pym/_emerge/EbuildPhase.py b/pym/_emerge/EbuildPhase.py
+index f53570a..82c165d 100644
+--- a/pym/_emerge/EbuildPhase.py
++++ b/pym/_emerge/EbuildPhase.py
+@@ -33,7 +33,8 @@ class EbuildPhase(CompositeTask):
+ 		("_ebuild_lock",)
+ 
+ 	# FEATURES displayed prior to setup phase
+-	_features_display = ("ccache", "distcc", "distcc-pump", "fakeroot",
++	_features_display = ("ccache", "depcheck", "depcheckstrict" "distcc", 
++		"distcc-pump", "fakeroot",
+ 		"installsources", "keeptemp", "keepwork", "nostrip",
+ 		"preserve-libs", "sandbox", "selinux", "sesandbox",
+ 		"splitdebug", "suidctl", "test", "userpriv",
+diff --git a/pym/_emerge/EventsAnalyser.py b/pym/_emerge/EventsAnalyser.py
+new file mode 100644
+index 0000000..65ece7b
+--- /dev/null
++++ b/pym/_emerge/EventsAnalyser.py
+@@ -0,0 +1,511 @@
++# Distributed under the terms of the GNU General Public License v2
++
++import portage
++from portage.dbapi._expand_new_virt import expand_new_virt
++from portage import os
++
++import subprocess
++import re
++
++class PortageUtils:
++	""" class for accessing the portage api """
++	def __init__(self, settings):
++		""" test """
++		self.settings=settings
++		self.vartree=portage.vartree(settings=settings)
++		self.vardbapi=portage.vardbapi(settings=settings, vartree=self.vartree)
++		self.portdbapi=portage.portdbapi(mysettings=settings)
++		self.metadata_keys = [k for k in portage.auxdbkeys if not k.startswith("UNUSED_")]
++		self.use=self.settings["USE"]
++
++	def get_best_visible_pkg(self,pkg):
++		"""
++		Gets best candidate on installing. Returns empty string if no found
++
++		:param pkg: package name
++
++		"""
++		try:
++			return self.portdbapi.xmatch("bestmatch-visible", pkg)
++		except:
++			return ''
++
++	# non-recursive dependency getter
++	def get_dep(self,pkg,dep_type=["RDEPEND","DEPEND"]):
++	  """
++	  Gets current dependencies of a package. Looks in portage db
++	  
++	  :param pkg: name of package
++	  :param dep_type: type of dependencies to recurse. Can be ["DEPEND"] or 
++		["RDEPEND", "DEPEND"]
++	  :returns: **set** of packages names
++	  """
++	  ret=set()
++	  
++	  pkg = self.get_best_visible_pkg(pkg)	
++	  if not pkg:
++		  return ret
++	  
++	  # we found the best visible match in common tree
++
++
++	  metadata = dict(zip(self.metadata_keys, 
++		  self.portdbapi.aux_get(pkg, self.metadata_keys)))
++	  dep_str = " ".join(metadata[k] for k in dep_type)
++
++	  # the IUSE default are very important for us
++	  iuse_defaults=[
++		u[1:] for u in metadata.get("IUSE",'').split() if u.startswith("+")]
++	  
++	  use=self.use.split()
++	  
++	  for u in iuse_defaults:
++		  if u not in use:
++			  use.append(u)
++
++	  success, atoms = portage.dep_check(dep_str, None, self.settings, 
++		  myuse=use, myroot=self.settings["ROOT"],
++		  trees={self.settings["ROOT"]:{"vartree":self.vartree, "porttree": self.vartree}})
++	  if not success:
++		  return ret
++
++	  for atom in atoms:
++		  atomname = self.vartree.dep_bestmatch(atom)
++
++		  if not atomname:
++			  continue
++		
++		  for unvirt_pkg in expand_new_virt(self.vardbapi,'='+atomname):
++			  for pkg in self.vartree.dep_match(unvirt_pkg):
++				  ret.add(pkg)
++
++	  return ret
++
++	# recursive dependency getter
++	def get_deps(self,pkg,dep_type=["RDEPEND","DEPEND"]):
++		""" 
++		Gets current dependencies of a package on any depth 
++		All dependencies **must** be installed
++		
++		:param pkg: name of package
++		:param dep_type: type of dependencies to recurse. Can be ["DEPEND"] or 
++		  ["RDEPEND", "DEPEND"]
++		:returns: **set** of packages names
++		"""
++		ret=set()
++
++
++		# get porttree dependencies on the first package
++
++		pkg = self.portdbapi.xmatch("bestmatch-visible", pkg)	
++		if not pkg:
++			return ret
++
++		known_packages=set()
++		unknown_packages=self.get_dep(pkg,dep_type)
++		ret=ret.union(unknown_packages)
++		
++		while unknown_packages:
++			p=unknown_packages.pop()
++			if p in known_packages:
++				continue
++			known_packages.add(p)
++
++			metadata = dict(zip(self.metadata_keys, self.vardbapi.aux_get(p, self.metadata_keys)))
++
++			dep_str = " ".join(metadata[k] for k in dep_type)
++			
++			# the IUSE default are very important for us
++			iuse_defaults=[
++			  u[1:] for u in metadata.get("IUSE",'').split() if u.startswith("+")]
++	  
++			use=self.use.split()
++	  
++			for u in iuse_defaults:
++				if u not in use:
++					use.append(u)
++			
++			success, atoms = portage.dep_check(dep_str, None, self.settings, 
++				myuse=use,	myroot=self.settings["ROOT"],
++				trees={self.settings["ROOT"]:{"vartree":self.vartree,"porttree": self.vartree}})
++
++			if not success:
++			  continue
++
++			for atom in atoms:
++				atomname = self.vartree.dep_bestmatch(atom)
++				if not atomname:
++					continue
++								
++				for unvirt_pkg in expand_new_virt(self.vardbapi,'='+atomname):
++					for pkg in self.vartree.dep_match(unvirt_pkg):
++						ret.add(pkg)
++						unknown_packages.add(pkg)
++		return ret
++
++	def get_deps_for_package_building(self, pkg):
++		""" 
++		  returns buildtime dependencies of current package and 
++		  all runtime dependencies of that buildtime dependencies
++		"""
++		buildtime_deps=self.get_dep(pkg, ["DEPEND"])
++		runtime_deps=set()
++		for dep in buildtime_deps:
++			runtime_deps=runtime_deps.union(self.get_deps(dep,["RDEPEND"]))
++
++		ret=buildtime_deps.union(runtime_deps)
++		return ret
++
++	def get_system_packages_list(self):
++		""" 
++		returns all packages from system set. They are always implicit dependencies
++		
++		:returns: **list** of package names
++		"""
++		ret=[]
++		for atom in self.settings.packages:
++			for pre_pkg in self.vartree.dep_match(atom):
++				for unvirt_pkg in expand_new_virt(self.vardbapi,'='+pre_pkg):
++					for pkg in self.vartree.dep_match(unvirt_pkg):
++						ret.append(pkg)
++		return ret
++
++
++class GentoolkitUtils:
++	""" 
++	Interface with qfile and qlist utils. They are much faster than 
++	internals.
++	"""
++
++	def getpackagesbyfiles(files):
++		"""
++		:param files: list of filenames
++		:returns: **dictionary** file->package, if file doesn't belong to any
++		  package it not returned as key of this dictionary
++		"""
++		ret={}
++		listtocheck=[]
++		for f in files:
++			if os.path.isdir(f):
++				ret[f]="directory"
++			else:
++				listtocheck.append(f)
++			
++		try:
++			proc=subprocess.Popen(['qfile']+['--nocolor','--exact','','--from','-'],
++				stdin=subprocess.PIPE, stdout=subprocess.PIPE,stderr=subprocess.PIPE, 
++				bufsize=4096)
++						
++			out,err=proc.communicate("\n".join(listtocheck).encode("utf8"))
++			
++			lines=out.decode("utf8").split("\n")
++			#print lines
++			line_re=re.compile(r"^([^ ]+)\s+\(([^)]+)\)$")
++			for line in lines:
++				if len(line)==0:
++					continue
++				match=line_re.match(line)
++				if match:
++					ret[match.group(2)]=match.group(1)
++				else:
++					portage.util.writemsg("Util qfile returned unparsable string: %s\n" % line)
++
++		except OSError as e:
++			portage.util.writemsg("Error while launching qfile: %s\n" % e)
++		  
++		  
++		return ret
++	  
++	def getfilesbypackages(packagenames):
++		"""
++		
++		:param packagename: name of package
++		:returns: **list** of files in package with name *packagename*
++		"""
++		ret=[]
++		try:
++			proc=subprocess.Popen(['qlist']+['--nocolor',"--obj"]+packagenames,
++				stdout=subprocess.PIPE,stderr=subprocess.PIPE, 
++				bufsize=4096)
++			
++			out,err=proc.communicate()
++			
++			ret=out.decode("utf8").split("\n")
++			if ret==['']:
++				ret=[]
++		except OSError as e:
++			portage.util.writemsg("Error while launching qfile: %s\n" % e)
++
++		return ret
++	  
++	def get_all_packages_files():   
++		"""
++		Memory-hungry operation
++		
++		:returns: **set** of all files that belongs to package
++		"""
++		ret=[]
++		try:
++			proc=subprocess.Popen(['qlist']+['--all',"--obj"],
++				stdout=subprocess.PIPE,stderr=subprocess.PIPE, 
++				bufsize=4096)
++			  
++			out,err=proc.communicate()
++			
++			ret=out.decode("utf8").split("\n")
++		except OSError as e:
++			portage.util.writemsg("Error while launching qfile: %s\n" % e)
++
++		return set(ret)
++   
++class FilterProcGenerator:
++	def __init__(self, pkgname, settings):
++		portageutils=PortageUtils(settings=settings)
++
++		deps_all=portageutils.get_deps_for_package_building(pkgname)
++		deps_portage=portageutils.get_dep('portage',["RDEPEND"])
++		
++		system_packages=portageutils.get_system_packages_list()
++
++		allfiles=GentoolkitUtils.get_all_packages_files()
++		portage.util.writemsg("All files list recieved, waiting for " \
++			"a list of allowed files\n")
++
++
++		allowedpkgs=system_packages+list(deps_portage)+list(deps_all)	
++		
++		allowedfiles=GentoolkitUtils.getfilesbypackages(allowedpkgs)
++		#for pkg in allowedpkgs:
++		#	allowedfiles+=GentoolkitUtils.getfilesbypackage(pkg)
++
++		#import pdb; pdb.set_trace()
++
++		# manually add all python interpreters to this list
++		allowedfiles+=GentoolkitUtils.getfilesbypackages(['python'])
++		allowedfiles=set(allowedfiles)
++		
++		deniedfiles=allfiles-allowedfiles
++
++		def filter_proc(eventname,filename,stage):
++			if filename in deniedfiles:
++				return False
++			return True
++			
++		self.filter_proc=filter_proc
++	def get_filter_proc(self):
++		return self.filter_proc
++
++class EventsAnalyser:
++	def __init__(self, pkgname, events, settings):
++		self.pkgname=pkgname
++		self.events=events
++		self.settings=settings
++		self.portageutils=PortageUtils(settings=settings)
++
++		self.deps_all=self.portageutils.get_deps_for_package_building(pkgname)
++		self.deps_direct=self.portageutils.get_dep(pkgname,["DEPEND"])
++		self.deps_portage=self.portageutils.get_dep('portage',["RDEPEND"])
++		
++		self.system_packages=self.portageutils.get_system_packages_list()
++		# All analyse work is here
++		
++		# get unique filenames
++		filenames=set()
++		for stage in events:
++			succ_events=set(events[stage][0])
++			fail_events=set(events[stage][1])
++			filenames=filenames.union(succ_events)
++			filenames=filenames.union(fail_events)
++		filenames=list(filenames)
++
++		file_to_package=GentoolkitUtils.getpackagesbyfiles(filenames)
++		# This part is completly unreadable. 
++		# It converting one complex struct(returned by getfsevents) to another complex
++		# struct which good for generating output.
++		#
++		# Old struct is also used during output
++
++		packagesinfo={}
++
++		for stage in sorted(events):
++			  succ_events=events[stage][0]
++			  fail_events=events[stage][1]
++			  
++			  for filename in succ_events:
++				  if filename in file_to_package:
++					  package=file_to_package[filename]
++				  else:
++					  package="unknown"
++					
++				  if not package in packagesinfo:
++					  packagesinfo[package]={}
++				  stageinfo=packagesinfo[package]
++				  if not stage in stageinfo:
++					  stageinfo[stage]={}
++					
++				  filesinfo=stageinfo[stage]
++				  if not filename in filesinfo:
++					  filesinfo[filename]={"found":[],"notfound":[]}
++				  filesinfo[filename]["found"]=succ_events[filename]
++				
++			  for filename in fail_events:
++				  if filename in file_to_package:
++					  package=file_to_package[filename]
++				  else:
++					  package="unknown"
++				  if not package in packagesinfo:
++					  packagesinfo[package]={}
++				  stageinfo=packagesinfo[package]
++				  if not stage in stageinfo:
++					  stageinfo[stage]={}
++					
++				  filesinfo=stageinfo[stage]
++				  if not filename in filesinfo:
++					  filesinfo[filename]={"found":[],"notfound":[]}
++				  filesinfo[filename]["notfound"]=fail_events[filename]
++		self.packagesinfo=packagesinfo
++		  
++	def display(self):
++		portage.util.writemsg(
++			portage.output.colorize(
++				"WARN", "\nFile access report for %s:\n" % self.pkgname))
++
++		stagesorder={"clean":1,"setup":2,"unpack":3,"prepare":4,"configure":5,"compile":6,"test":7,
++			 "install":8,"preinst":9,"postinst":10,"prerm":11,"postrm":12,"unknown":13}
++		packagesinfo=self.packagesinfo
++		# print information grouped by package	  
++		for package in sorted(packagesinfo):
++			# not showing special directory package
++			if package=="directory":
++				continue
++			
++			if package=="unknown":
++				continue
++
++
++			is_pkg_in_dep=package in self.deps_all
++			is_pkg_in_portage_dep=package in self.deps_portage
++			is_pkg_in_system=package in self.system_packages
++			is_pkg_python="dev-lang/python" in package
++
++			stages=[]
++			for stage in sorted(packagesinfo[package].keys(), key=stagesorder.get):
++				if stage!="unknown":
++					stages.append(stage)
++
++			if len(stages)==0:
++				continue
++	
++			filenames={}
++			for stage in stages:
++				for filename in packagesinfo[package][stage]:
++					if len(packagesinfo[package][stage][filename]["found"])!=0:
++						was_readed,was_writed=packagesinfo[package][stage][filename]["found"]
++						if not filename in filenames:
++							filenames[filename]=['ok',was_readed,was_writed]
++						else:
++							status, old_was_readed, old_was_writed=filenames[filename]
++							filenames[filename]=[
++							  'ok',old_was_readed | was_readed, old_was_writed | was_writed 
++							]
++					if len(packagesinfo[package][stage][filename]["notfound"])!=0:
++						was_notfound,was_blocked=packagesinfo[package][stage][filename]["notfound"]
++						if not filename in filenames:
++							filenames[filename]=['err',was_notfound,was_blocked]
++						else:
++							status, old_was_notfound, old_was_blocked=filenames[filename]
++							filenames[filename]=[
++							  'err',old_was_notfound | was_notfound, old_was_blocked | was_blocked 
++							]
++				  
++
++			if is_pkg_in_dep:
++				portage.util.writemsg("[OK]")
++			elif is_pkg_in_system:
++				portage.util.writemsg("[SYSTEM]")
++			elif is_pkg_in_portage_dep:
++				portage.util.writemsg("[PORTAGE DEP]")
++			elif is_pkg_python:
++				portage.util.writemsg("[INTERPRETER]")
++			elif not self.is_package_useful(package,stages,filenames.keys()):
++				portage.util.writemsg("[LIKELY OK]")
++			else:
++				portage.util.writemsg(portage.output.colorize("BAD", "[NOT IN DEPS]"))
++			# show information about accessed files
++
++			portage.util.writemsg(" %-40s: %s\n" % (package,stages))
++
++			# this is here for readability
++			action={
++				('ok',False,False):"accessed",
++				('ok',True,False):"readed",
++				('ok',False,True):"writed",
++				('ok',True,True):"readed and writed",
++				('err',False,False):"other error",
++				('err',True,False):"not found",
++				('err',False,True):"blocked",
++				('err',True,True):"not found and blocked"
++			}
++			
++			filescounter=0
++			
++			for filename in filenames:
++				event_info=tuple(filenames[filename])
++				portage.util.writemsg("  %-56s %-21s\n" % (filename,action[event_info]))
++				filescounter+=1
++				if filescounter>10:
++					portage.util.writemsg("  ... and %d more ...\n" % (len(filenames)-10))
++					break
++		# ... and one more check. Making sure that direct build time 
++		# dependencies were accessed
++		#import pdb; pdb.set_trace()
++		not_accessed_deps=set(self.deps_direct)-set(self.packagesinfo.keys())
++		if not_accessed_deps:
++			portage.util.writemsg(portage.output.colorize("WARN", "!!! "))
++			portage.util.writemsg("Warning! Some build time dependencies " + \
++				"of packages were not accessed: " + \
++				" ".join(not_accessed_deps) + "\n")
++					
++	def is_package_useful(self,pkg,stages,files):
++		""" some basic heuristics here to cut part of packages """
++
++		excluded_paths=set(
++			['/etc/sandbox.d/']
++		)
++
++		excluded_packages=set(
++			# autodep shows these two packages every time
++			['net-zope/zope-fixers', 'net-zope/zope-interface']
++		)
++
++
++		def is_pkg_excluded(p):
++			for pkg in excluded_packages:
++				if p.startswith(pkg): # if package is excluded
++					return True
++			return False
++
++
++		def is_file_excluded(f):
++			for path in excluded_paths:
++				if f.startswith(path): # if path is excluded
++					return True
++			return False
++
++
++		if is_pkg_excluded(pkg):
++			return False
++
++		for f in files:
++			if is_file_excluded(f):
++			  continue
++			
++			# test 1: package is not useful if all files are *.desktop or *.xml or *.m4		
++			if not (f.endswith(".desktop") or f.endswith(".xml") or f.endswith(".m4") or f.endswith(".pc")):
++			  break
++		else:
++			return False # we get here if cycle ends not with break
++		  
++		return True
++		
++    
+\ No newline at end of file
+diff --git a/pym/_emerge/EventsLogger.py b/pym/_emerge/EventsLogger.py
+new file mode 100644
+index 0000000..68b3c67
+--- /dev/null
++++ b/pym/_emerge/EventsLogger.py
+@@ -0,0 +1,180 @@
++# Distributed under the terms of the GNU General Public License v2
++
++import io
++import sys
++import stat
++import socket
++import select
++import tempfile
++
++import threading
++
++from portage import os
++
++class EventsLogger(threading.Thread):
++	def default_filter(eventname, filename, stage):
++		return True
++		
++	def __init__(self, socket_dir="/tmp/", filter_proc=default_filter):
++		threading.Thread.__init__(self) # init the Thread
++		
++		self.alive=False
++		
++		self.main_thread=threading.currentThread()
++		
++		self.socket_dir=socket_dir
++		self.filter_proc=filter_proc
++		
++		self.socket_name=None
++		self.socket_logger=None
++
++		self.events={}
++
++		try:
++			socket_dir_name = tempfile.mkdtemp(dir=self.socket_dir,
++				prefix="log_socket_")
++			
++			socket_name = os.path.join(socket_dir_name, 'socket')
++
++		except OSError as e:
++			return
++		
++		self.socket_name=socket_name
++		
++		#print(self.socket_name)
++		
++		try:
++			socket_logger=socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
++			socket_logger.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
++
++			socket_logger.bind(self.socket_name)
++			socket_logger.listen(64)
++
++		except socket.error as e:
++			return
++
++		self.socket_logger=socket_logger
++
++		try:
++  			# Allow connecting to socket for anyone
++			os.chmod(socket_dir_name,
++				stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR|
++				stat.S_IROTH|stat.S_IWOTH|stat.S_IXOTH)
++			os.chmod(socket_name,
++				stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR|
++				stat.S_IROTH|stat.S_IWOTH|stat.S_IXOTH)
++		except OSError as e:
++			return
++		  
++	def run(self):
++		""" Starts the log server """
++
++		self.alive=True
++		self.listen_thread=threading.currentThread()
++		clients={}
++		
++		epoll=select.epoll()
++		epoll.register(self.socket_logger.fileno(), select.EPOLLIN)
++
++		while self.alive:
++			try:
++				sock_events = epoll.poll(3)
++				
++				for fileno, sock_event in sock_events:
++					if fileno == self.socket_logger.fileno():
++						ret = self.socket_logger.accept()
++						if ret is None:
++							pass
++						else:
++							(client,addr)=ret
++							epoll.register(client.fileno(), select.EPOLLIN)
++							clients[client.fileno()]=client
++					elif sock_event & select.EPOLLIN:
++						s=clients[fileno]
++						record=s.recv(8192)
++					
++						if not record: # if connection was closed
++							epoll.unregister(fileno)
++							clients[fileno].close()
++							del clients[fileno]
++							continue
++					
++						#import pdb; pdb.set_trace()
++						try:
++							message=record.decode("utf8").split("\0")
++						except UnicodeDecodeError:
++  							print("Bad message %s" % record)
++  							continue
++
++						#  continue
++
++						#print(message)
++					
++						try:
++							if message[4]=="ASKING":
++								if self.filter_proc(message[1],message[2],message[3]):
++									s.sendall(b"ALLOW\0")
++								else:
++									# TODO: log through portage infrastructure
++									#print("Blocking an access to %s" % message[2])
++									s.sendall(b"DENY\0")
++							else:
++								eventname,filename,stage,result=message[1:5]
++
++								if not stage in self.events:
++									self.events[stage]=[{},{}]
++						
++								hashofsucesses=self.events[stage][0]
++								hashoffailures=self.events[stage][1]
++
++								if result=="DENIED":
++									print("Blocking an access to %s" % filename)
++
++								if result=="OK":
++									if not filename in hashofsucesses:
++										hashofsucesses[filename]=[False,False]
++						  
++									readed_or_writed=hashofsucesses[filename]
++						  
++									if eventname=="read":
++										readed_or_writed[0]=True
++									elif eventname=="write":
++										readed_or_writed[1]=True
++							
++								elif result[0:3]=="ERR" or result=="DENIED":
++									if not filename in hashoffailures:
++										hashoffailures[filename]=[False,False]
++									notfound_or_blocked=hashoffailures[filename]
++								  
++									if result=="ERR/2":
++										notfound_or_blocked[0]=True
++									elif result=="DENIED":
++										notfound_or_blocked[1]=True
++
++								else:
++									print("Error in logger module<->analyser protocol")
++						
++						except IndexError:
++								print("IndexError while parsing %s" % record)
++			except IOError as e:
++				if e.errno!=4: # handling "Interrupted system call" errors
++					raise
++				  
++			# if main thread doesnt exists then exit	  
++			if not self.main_thread.is_alive():
++				break
++		epoll.unregister(self.socket_logger.fileno())
++		epoll.close()
++		self.socket_logger.close()
++		
++	def stop(self):
++		""" Stops the log server. Returns all events """
++
++		self.alive=False
++		
++		# Block the main thread until listener exists
++		self.listen_thread.join()
++		
++		# We assume portage clears tmp folder, so no deleting a socket file
++		# We assume that no new socket data will arrive after this moment
++		return self.events
+diff --git a/pym/portage/const.py b/pym/portage/const.py
+index ecaa8f1..f34398d 100644
+--- a/pym/portage/const.py
++++ b/pym/portage/const.py
+@@ -67,6 +67,8 @@ FAKEROOT_BINARY          = "/usr/bin/fakeroot"
+ BASH_BINARY              = "/bin/bash"
+ MOVE_BINARY              = "/bin/mv"
+ PRELINK_BINARY           = "/usr/sbin/prelink"
++AUTODEP_LIBRARY			 = "/usr/lib/file_hook.so"
++
+ 
+ INVALID_ENV_FILE         = "/etc/spork/is/not/valid/profile.env"
+ REPO_NAME_FILE           = "repo_name"
+@@ -88,7 +90,8 @@ EBUILD_PHASES            = ("pretend", "setup", "unpack", "prepare", "configure"
+ SUPPORTED_FEATURES       = frozenset([
+                            "allow-missing-manifests",
+                            "assume-digests", "binpkg-logs", "buildpkg", "buildsyspkg", "candy",
+-                           "ccache", "chflags", "collision-protect", "compress-build-logs",
++                           "ccache", "chflags", "collision-protect", "compress-build-logs", 
++                           "depcheck", "depcheckstrict",
+                            "digest", "distcc", "distcc-pump", "distlocks", "ebuild-locks", "fakeroot",
+                            "fail-clean", "fixpackages", "force-mirror", "getbinpkg",
+                            "installsources", "keeptemp", "keepwork", "fixlafiles", "lmirror",
+diff --git a/pym/portage/package/ebuild/_config/special_env_vars.py b/pym/portage/package/ebuild/_config/special_env_vars.py
+index 87aa606..6d42809 100644
+--- a/pym/portage/package/ebuild/_config/special_env_vars.py
++++ b/pym/portage/package/ebuild/_config/special_env_vars.py
+@@ -101,8 +101,8 @@ environ_whitelist += [
+ # other variables inherited from the calling environment
+ environ_whitelist += [
+ 	"CVS_RSH", "ECHANGELOG_USER",
+-	"GPG_AGENT_INFO",
+-	"SSH_AGENT_PID", "SSH_AUTH_SOCK",
++	"GPG_AGENT_INFO", "LOG_SOCKET",
++	"SSH_AGENT_PID", "SSH_AUTH_SOCK"
+ 	"STY", "WINDOW", "XAUTHORITY",
+ ]
+ 
+diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py
+index 49b67ac..c76c1ed 100644
+--- a/pym/portage/package/ebuild/doebuild.py
++++ b/pym/portage/package/ebuild/doebuild.py
+@@ -1038,6 +1038,9 @@ def _spawn_actionmap(settings):
+ 		nosandbox = ("sandbox" not in features and \
+ 			"usersandbox" not in features)
+ 
++	if "depcheck" in features or "depcheckstrict" in features:
++		nosandbox = True
++
+ 	if not portage.process.sandbox_capable:
+ 		nosandbox = True
+ 
+@@ -1215,7 +1218,10 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero
+ 		keywords["opt_name"] = "[%s/%s]" % \
+ 			(mysettings.get("CATEGORY",""), mysettings.get("PF",""))
+ 
+-	if free or "SANDBOX_ACTIVE" in os.environ:
++	if "depcheck" in features or "depcheckstrict" in features:
++		keywords["opt_name"] += " bash"
++		spawn_func = portage.process.spawn_autodep
++	elif free or "SANDBOX_ACTIVE" in os.environ:
+ 		keywords["opt_name"] += " bash"
+ 		spawn_func = portage.process.spawn_bash
+ 	elif fakeroot:
+diff --git a/pym/portage/process.py b/pym/portage/process.py
+index 3c15370..6866a2f 100644
+--- a/pym/portage/process.py
++++ b/pym/portage/process.py
+@@ -16,7 +16,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
+ 	'portage.util:dump_traceback',
+ )
+ 
+-from portage.const import BASH_BINARY, SANDBOX_BINARY, FAKEROOT_BINARY
++from portage.const import BASH_BINARY, SANDBOX_BINARY, FAKEROOT_BINARY, AUTODEP_LIBRARY
+ from portage.exception import CommandNotFound
+ 
+ try:
+@@ -39,6 +39,9 @@ else:
+ sandbox_capable = (os.path.isfile(SANDBOX_BINARY) and
+                    os.access(SANDBOX_BINARY, os.X_OK))
+ 
++autodep_capable = (os.path.isfile(AUTODEP_LIBRARY) and
++                   os.access(AUTODEP_LIBRARY, os.X_OK))
++
+ fakeroot_capable = (os.path.isfile(FAKEROOT_BINARY) and
+                     os.access(FAKEROOT_BINARY, os.X_OK))
+ 
+@@ -66,6 +69,16 @@ def spawn_bash(mycommand, debug=False, opt_name=None, **keywords):
+ 	args.append(mycommand)
+ 	return spawn(args, opt_name=opt_name, **keywords)
+ 
++def spawn_autodep(mycommand, opt_name=None, **keywords):
++	if not autodep_capable:
++		return spawn_bash(mycommand, opt_name=opt_name, **keywords)
++	if "env" not in keywords or "LOG_SOCKET" not in keywords["env"]:
++		return spawn_bash(mycommand, opt_name=opt_name, **keywords)
++
++	# Core part: tell the loader to preload logging library
++	keywords["env"]["LD_PRELOAD"]=AUTODEP_LIBRARY
++	return spawn_bash(mycommand, opt_name=opt_name, **keywords)	
++
+ def spawn_sandbox(mycommand, opt_name=None, **keywords):
+ 	if not sandbox_capable:
+ 		return spawn_bash(mycommand, opt_name=opt_name, **keywords)



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [gentoo-commits] proj/autodep:master commit in: /
@ 2011-08-21 11:39 Александр Берсенев
  0 siblings, 0 replies; 4+ messages in thread
From: Александр Берсенев @ 2011-08-21 11:39 UTC (permalink / raw
  To: gentoo-commits

commit:     4161e981fd764f039fec2fff2afe3af380d33b83
Author:     Alexander Bersenev <bay <AT> hackerdom <DOT> ru>
AuthorDate: Sun Aug 21 17:38:24 2011 +0000
Commit:     Александр Берсенев <bay <AT> hackerdom <DOT> ru>
CommitDate: Sun Aug 21 17:38:24 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/autodep.git;a=commit;h=4161e981

first version of toplevel makefile

---
 Makefile |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..96e3763
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,15 @@
+all: hookfs file_hook.so
+
+hookfs: src/hook_fusefs/hookfs.c
+	$(CC) -std=c99 -Wall `pkg-config fuse --cflags --libs` -lulockmgr \
+	$(CFLAGS) $(LDFLAGS) src/hook_fusefs/hookfs.c -o hookfs
+
+file_hook.so: file_hook.o
+	ld -shared -o file_hook.so -ldl -lc file_hook.o
+
+file_hook.o: src/hook_lib/file_hook.c
+	cc -Wall -fPIC -o file_hook.o -c src/hook_lib/file_hook.c
+
+
+clean:
+	rm -f hookfs file_hook.o file_hook.so



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [gentoo-commits] proj/autodep:master commit in: /
@ 2011-08-21 18:50 Александр Берсенев
  0 siblings, 0 replies; 4+ messages in thread
From: Александр Берсенев @ 2011-08-21 18:50 UTC (permalink / raw
  To: gentoo-commits

commit:     c007096bf7d0f6033c0806230b7f780a7b98ee46
Author:     Alexander Bersenev <bay <AT> hackerdom <DOT> ru>
AuthorDate: Sun Aug 21 21:01:59 2011 +0000
Commit:     Александр Берсенев <bay <AT> hackerdom <DOT> ru>
CommitDate: Sun Aug 21 21:01:59 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/autodep.git;a=commit;h=c007096b

revert previous: some version of gcc doesnt support it

---
 Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/Makefile b/Makefile
index f9f93dc..01c92f1 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ all: hookfs file_hook.so
 
 hookfs: src/hook_fusefs/hookfs.c
 	$(CC) -std=c99 -Wall `pkg-config fuse --cflags --libs` -lulockmgr \
-	$(CFLAGS) $(LDFLAGS) -Wno-unused-result src/hook_fusefs/hookfs.c -o hookfs
+	$(CFLAGS) $(LDFLAGS) src/hook_fusefs/hookfs.c -o hookfs
 
 file_hook.so: file_hook.o
 	ld -shared -o file_hook.so -ldl -lc file_hook.o



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [gentoo-commits] proj/autodep:master commit in: /
@ 2011-11-07  9:26 Александр Берсенев
  0 siblings, 0 replies; 4+ messages in thread
From: Александр Берсенев @ 2011-11-07  9:26 UTC (permalink / raw
  To: gentoo-commits

commit:     f977b3fa9027da066809d42adad3eb479c488a2c
Author:     Alexander Bersenev <bay <AT> hackerdom <DOT> ru>
AuthorDate: Mon Nov  7 15:25:50 2011 +0000
Commit:     Александр Берсенев <bay <AT> hackerdom <DOT> ru>
CommitDate: Mon Nov  7 15:25:50 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/autodep.git;a=commit;h=f977b3fa

Peter Volkov's patch to fix building

---
 Makefile |   18 ++++++++++--------
 1 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/Makefile b/Makefile
index 01c92f1..0e4c2fc 100644
--- a/Makefile
+++ b/Makefile
@@ -1,24 +1,26 @@
 all: hookfs file_hook.so
 
+libdir ?= lib
+
 hookfs: src/hook_fusefs/hookfs.c
 	$(CC) -std=c99 -Wall `pkg-config fuse --cflags --libs` -lulockmgr \
-	$(CFLAGS) $(LDFLAGS) src/hook_fusefs/hookfs.c -o hookfs
+		$(CFLAGS) $(LDFLAGS) src/hook_fusefs/hookfs.c -o hookfs
 
 file_hook.so: file_hook.o
-	ld -shared -o file_hook.so -ldl -lc file_hook.o
+	ld -ldl $(RAW_LDFLAGS) -shared -o file_hook.so -lc file_hook.o
 
 file_hook.o: src/hook_lib/file_hook.c
-	cc -Wall -fPIC -o file_hook.o -c src/hook_lib/file_hook.c
+	$(CC) -Wall -fPIC -o file_hook.o -c src/hook_lib/file_hook.c
 
 install:
-	mkdir -p "${DESTDIR}/usr/lib/"
-	cp file_hook.so "${DESTDIR}/usr/lib/"
-	cp -R src/autodep "${DESTDIR}/usr/lib/"
-	cp -R portage_with_autodep "${DESTDIR}/usr/lib/"
+	mkdir -p "${DESTDIR}/usr/$(libdir)/"
+	cp file_hook.so "${DESTDIR}/usr/$(libdir)/"
+	cp -R src/autodep "${DESTDIR}/usr/$(libdir)/"
+	cp -R portage_with_autodep "${DESTDIR}/usr/$(libdir)/"
 
 	mkdir -p "${DESTDIR}/usr/bin/"
 	cp hookfs emerge_strict "${DESTDIR}/usr/bin/"
-	ln -s "${DESTDIR}/usr/lib/autodep/autodep" "${DESTDIR}/usr/bin/"
+	ln -s "${DESTDIR}/usr/$(libdir)/autodep/autodep" "${DESTDIR}/usr/bin/"
 
 clean:
 	rm -f hookfs file_hook.o file_hook.so



^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-11-07  9:27 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-08-21 18:50 [gentoo-commits] proj/autodep:master commit in: / Александр Берсенев
  -- strict thread matches above, loose matches on Subject: below --
2011-11-07  9:26 Александр Берсенев
2011-08-21 11:39 Александр Берсенев
2011-08-21 11:24 Александр Берсенев

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox