From 5e12dbfeba941ed009229a3d497827bdbc7fb881 Mon Sep 17 00:00:00 2001 From: Marius Mauch Date: Thu, 25 Jan 2007 16:20:19 +0000 Subject: Namespace sanitizing, step 2 Rename portage.exec to portage.process to avoid syntax errors svn path=/main/trunk/; revision=5780 --- pym/portage/__init__.py | 360 ++++++++++++++++++++++---------------------- pym/portage/checksum.py | 28 ++-- pym/portage/data.py | 4 +- pym/portage/debug.py | 6 +- pym/portage/dep.py | 20 +-- pym/portage/eclass_cache.py | 4 +- pym/portage/exec.py | 336 ----------------------------------------- pym/portage/gpg.py | 44 +++--- pym/portage/localization.py | 2 +- pym/portage/locks.py | 8 +- pym/portage/mail.py | 8 +- pym/portage/manifest.py | 48 +++--- pym/portage/news.py | 10 +- pym/portage/output.py | 6 +- pym/portage/process.py | 336 +++++++++++++++++++++++++++++++++++++++++ pym/portage/update.py | 10 +- pym/portage/util.py | 24 +-- pym/portage/versions.py | 18 +-- 18 files changed, 636 insertions(+), 636 deletions(-) delete mode 100644 pym/portage/exec.py create mode 100644 pym/portage/process.py diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 98303857b..044468fe6 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -54,8 +54,8 @@ try: import cvstree import xpak import getbinpkg - import portage_dep - from portage_dep import dep_getcpv, dep_getkey, get_operator, \ + import portage.dep + from portage.dep import dep_getcpv, dep_getkey, get_operator, \ isjustname, isspecific, isvalidatom, \ match_from_list, match_to_list, best_match_to_list @@ -63,8 +63,8 @@ try: import output from output import bold, colorize, green, red, yellow - import portage_const - from portage_const import VDB_PATH, PRIVATE_PATH, CACHE_PATH, DEPCACHE_PATH, \ + import portage.const + from portage.const import VDB_PATH, PRIVATE_PATH, CACHE_PATH, DEPCACHE_PATH, \ USER_CONFIG_PATH, MODULES_FILE_PATH, CUSTOM_PROFILE_PATH, PORTAGE_BASE_PATH, \ PORTAGE_BIN_PATH, PORTAGE_PYM_PATH, PROFILE_PATH, LOCALE_DATA_PATH, \ EBUILD_SH_BINARY, SANDBOX_BINARY, BASH_BINARY, \ @@ -73,36 +73,36 @@ try: INVALID_ENV_FILE, CUSTOM_MIRRORS_FILE, CONFIG_MEMORY_FILE,\ INCREMENTALS, EAPI, MISC_SH_BINARY, REPO_NAME_LOC, REPO_NAME_FILE - from portage_data import ostype, lchown, userland, secpass, uid, wheelgid, \ + from portage.data import ostype, lchown, userland, secpass, uid, wheelgid, \ portage_uid, portage_gid, userpriv_groups - from portage_manifest import Manifest + from portage.manifest import Manifest - import portage_util - from portage_util import atomic_ofstream, apply_secpass_permissions, apply_recursive_permissions, \ + import portage.util + from portage.util import atomic_ofstream, apply_secpass_permissions, apply_recursive_permissions, \ dump_traceback, getconfig, grabdict, grabdict_package, grabfile, grabfile_package, \ map_dictlist_vals, new_protect_filename, normalize_path, \ pickle_read, pickle_write, stack_dictlist, stack_dicts, stack_lists, \ unique_array, varexpand, writedict, writemsg, writemsg_stdout, write_atomic - import portage_exception - import portage_gpg - import portage_locks - import portage_exec - from portage_exec import atexit_register, run_exitfuncs - from portage_locks import unlockfile,unlockdir,lockfile,lockdir - import portage_checksum - from portage_checksum import perform_md5,perform_checksum,prelink_capable + import portage.exception + import portage.gpg + import portage.locks + import portage.process + from portage.process import atexit_register, run_exitfuncs + from portage.locks import unlockfile,unlockdir,lockfile,lockdir + import portage.checksum + from portage.checksum import perform_md5,perform_checksum,prelink_capable import eclass_cache - from portage_localization import _ - from portage_update import dep_transform, fixdbentries, grab_updates, \ + from portage.localization import _ + from portage.update import dep_transform, fixdbentries, grab_updates, \ parse_updates, update_config_files, update_dbentries # Need these functions directly in portage namespace to not break every external tool in existence - from portage_versions import best, catpkgsplit, catsplit, pkgcmp, \ + from portage.versions import best, catpkgsplit, catsplit, pkgcmp, \ pkgsplit, vercmp, ververify # endversion and endversion_keys are for backward compatibility only. - from portage_versions import endversion_keys - from portage_versions import suffix_value as endversion + from portage.versions import endversion_keys + from portage.versions import suffix_value as endversion except ImportError, e: sys.stderr.write("\n\n") @@ -117,7 +117,7 @@ except ImportError, e: try: - import portage_selinux as selinux + import portage.selinux as selinux except OSError, e: writemsg("!!! SELinux not loaded: %s\n" % str(e), noiselevel=-1) del e @@ -184,8 +184,8 @@ def cacheddir(my_original_path, ignorecvs, ignorelist, EmptyOnError, followSymli if stat.S_ISDIR(pathstat[stat.ST_MODE]): mtime = pathstat[stat.ST_MTIME] else: - raise portage_exception.DirectoryNotFound(mypath) - except (IOError,OSError,portage_exception.PortageException): + raise portage.exception.DirectoryNotFound(mypath) + except (IOError,OSError,portage.exception.PortageException): if EmptyOnError: return [], [] return None, None @@ -469,7 +469,7 @@ def elog_process(cpv, mysettings): all_logentries = {} for f in mylogfiles: msgfunction, msgtype = f.split(".") - if msgfunction not in portage_const.EBUILD_PHASES: + if msgfunction not in portage.const.EBUILD_PHASES: writemsg("!!! can't process invalid log file: %s\n" % f, noiselevel=-1) continue @@ -500,7 +500,7 @@ def elog_process(cpv, mysettings): def combine_logentries(logentries): # generate a single string with all log messages rValue = "" - for phase in portage_const.EBUILD_PHASES: + for phase in portage.const.EBUILD_PHASES: if not phase in logentries: continue for msgtype,msgcontent in logentries[phase]: @@ -534,7 +534,7 @@ def elog_process(cpv, mysettings): logmodule = __import__("elog_modules.mod_"+s) m = getattr(logmodule, "mod_"+s) def timeout_handler(signum, frame): - raise portage_exception.PortageException( + raise portage.exception.PortageException( "Timeout in elog_process for system '%s'" % s) import signal signal.signal(signal.SIGALRM, timeout_handler) @@ -552,7 +552,7 @@ def elog_process(cpv, mysettings): writemsg("!!! Error while importing logging modules " + \ "while loading \"mod_%s\":\n" % str(s)) writemsg("%s\n" % str(e), noiselevel=-1) - except portage_exception.PortageException, e: + except portage.exception.PortageException, e: writemsg("%s\n" % str(e), noiselevel=-1) # clean logfiles to avoid repetitions @@ -572,7 +572,7 @@ def env_update(makelinks=1, target_root=None, prev_mtimes=None, contents=None): global mtimedb prev_mtimes = mtimedb["ldpath"] envd_dir = os.path.join(target_root, "etc", "env.d") - portage_util.ensure_dirs(envd_dir, mode=0755) + portage.util.ensure_dirs(envd_dir, mode=0755) fns = listdir(envd_dir, EmptyOnError=1) fns.sort() templist = [] @@ -599,7 +599,7 @@ def env_update(makelinks=1, target_root=None, prev_mtimes=None, contents=None): file_path = os.path.join(envd_dir, x) try: myconfig = getconfig(file_path, expand=False) - except portage_exception.ParseError, e: + except portage.exception.ParseError, e: writemsg("!!! '%s'\n" % str(e), noiselevel=-1) del e continue @@ -702,7 +702,7 @@ def env_update(makelinks=1, target_root=None, prev_mtimes=None, contents=None): mtime_changed = False lib_dirs = set() - for lib_dir in portage_util.unique_array(specials["LDPATH"]+['usr/lib','usr/lib64','usr/lib32','lib','lib64','lib32']): + for lib_dir in portage.util.unique_array(specials["LDPATH"]+['usr/lib','usr/lib64','usr/lib32','lib','lib64','lib32']): x = os.path.join(target_root, lib_dir.lstrip(os.sep)) try: newldpathtime = os.stat(x)[stat.ST_MTIME] @@ -906,9 +906,9 @@ class config: @param mycpv: CPV to load up (see setcpv), this is the same as calling init with mycpv=None and then calling instance.setcpv(mycpv). @type mycpv: String - @param config_profile_path: Configurable path to the profile (usually PROFILE_PATH from portage_const) + @param config_profile_path: Configurable path to the profile (usually PROFILE_PATH from portage.const) @type config_profile_path: String - @param config_incrementals: List of incremental variables (usually portage_const.INCREMENTALS) + @param config_incrementals: List of incremental variables (usually portage.const.INCREMENTALS) @type config_incrementals: List @param config_root: path to read local config from (defaults to "/", see PORTAGE_CONFIGROOT) @type config_root: String @@ -1009,7 +1009,7 @@ class config: writemsg(("!!! Error: %s='%s' is not a directory. " + \ "Please correct this.\n") % (varname, var), noiselevel=-1) - raise portage_exception.DirectoryNotFound(var) + raise portage.exception.DirectoryNotFound(var) if config_root is None: config_root = "/" @@ -1033,7 +1033,7 @@ class config: if not config_incrementals: writemsg("incrementals not specified to class config\n") - self.incrementals = copy.deepcopy(portage_const.INCREMENTALS) + self.incrementals = copy.deepcopy(portage.const.INCREMENTALS) else: self.incrementals = copy.deepcopy(config_incrementals) @@ -1070,7 +1070,7 @@ class config: if os.path.exists(parentsFile): parents = grabfile(parentsFile) if not parents: - raise portage_exception.ParseError( + raise portage.exception.ParseError( "Empty parent file: '%s'" % parents_file) for parentPath in parents: parentPath = normalize_path(os.path.join( @@ -1078,7 +1078,7 @@ class config: if os.path.exists(parentPath): addProfile(parentPath) else: - raise portage_exception.ParseError( + raise portage.exception.ParseError( "Parent '%s' not found: '%s'" % \ (parentPath, parentsFile)) self.profiles.append(currentPath) @@ -1180,7 +1180,7 @@ class config: self.make_defaults_use.append(cfg.get("USE", "")) else: self.make_defaults_use.append("") - self.mygcfg = stack_dicts(mygcfg_dlists, incrementals=portage_const.INCREMENTALS, ignore_none=1) + self.mygcfg = stack_dicts(mygcfg_dlists, incrementals=portage.const.INCREMENTALS, ignore_none=1) #self.mygcfg = grab_stacked("make.defaults", self.profiles, getconfig) if self.mygcfg is None: self.mygcfg = {} @@ -1465,7 +1465,7 @@ class config: self.backup_changes(var) self.regenerate() - self.features = portage_util.unique_array(self["FEATURES"].split()) + self.features = portage.util.unique_array(self["FEATURES"].split()) if "gpg" in self.features: if not os.path.exists(self["PORTAGE_GPG_DIR"]) or \ @@ -1474,7 +1474,7 @@ class config: " Removing gpg from FEATURES.\n"), noiselevel=-1) self.features.remove("gpg") - if not portage_exec.sandbox_capable and \ + if not portage.process.sandbox_capable and \ ("sandbox" in self.features or "usersandbox" in self.features): if self.profile_path is not None and \ os.path.realpath(self.profile_path) == \ @@ -1515,8 +1515,8 @@ class config: for mypath, (gid, mode, modemask) in dir_mode_map.iteritems(): try: mydir = os.path.join(self["ROOT"], mypath) - portage_util.ensure_dirs(mydir, gid=gid, mode=mode, mask=modemask) - except portage_exception.PortageException, e: + portage.util.ensure_dirs(mydir, gid=gid, mode=mode, mask=modemask) + except portage.exception.PortageException, e: writemsg("!!! Directory initialization failed: '%s'\n" % mydir, noiselevel=-1) writemsg("!!! %s\n" % str(e), @@ -1751,7 +1751,7 @@ class config: myuse = self["USE"] else: myuse = mydbapi.aux_get(mycpv, ["USE"])[0] - virts = flatten(portage_dep.use_reduce(portage_dep.paren_reduce(provides), uselist=myuse.split())) + virts = flatten(portage.dep.use_reduce(portage.dep.paren_reduce(provides), uselist=myuse.split())) cp = dep_getkey(mycpv) for virt in virts: @@ -2159,7 +2159,7 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keyw instead of as root. Notes: os.system cannot be used because it messes with signal handling. Instead we - use the portage_exec spawn* family of functions. + use the portage.process spawn* family of functions. This function waits for the process to terminate. @@ -2206,7 +2206,7 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keyw elif 1 not in fd_pipes or 2 not in fd_pipes: raise ValueError(fd_pipes) pr, pw = os.pipe() - mypids.extend(portage_exec.spawn(('tee', '-i', '-a', logfile), + mypids.extend(portage.process.spawn(('tee', '-i', '-a', logfile), returnpid=True, fd_pipes={0:pr, 1:fd_pipes[1], 2:fd_pipes[2]})) os.close(pr) fd_pipes[1] = pw @@ -2228,10 +2228,10 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keyw if free: keywords["opt_name"] += " bash" - spawn_func = portage_exec.spawn_bash + spawn_func = portage.process.spawn_bash else: keywords["opt_name"] += " sandbox" - spawn_func = portage_exec.spawn_sandbox + spawn_func = portage.process.spawn_sandbox if sesandbox: con = selinux.getcontext() @@ -2254,13 +2254,13 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keyw while mypids: pid = mypids.pop(0) retval = os.waitpid(pid, 0)[1] - portage_exec.spawned_pids.remove(pid) + portage.process.spawned_pids.remove(pid) if retval != os.EX_OK: for pid in mypids: if os.waitpid(pid, os.WNOHANG) == (0,0): os.kill(pid, signal.SIGTERM) os.waitpid(pid, 0) - portage_exec.spawned_pids.remove(pid) + portage.process.spawned_pids.remove(pid) if retval & 0xff: return (retval & 0xff) << 8 return retval >> 8 @@ -2401,7 +2401,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks", for x in distdir_dirs: mydir = os.path.join(mysettings["DISTDIR"], x) - if portage_util.ensure_dirs(mydir, gid=portage_gid, mode=dirmode, mask=modemask): + if portage.util.ensure_dirs(mydir, gid=portage_gid, mode=dirmode, mask=modemask): writemsg("Adjusting permissions recursively: '%s'\n" % mydir, noiselevel=-1) def onerror(e): @@ -2409,9 +2409,9 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks", if not apply_recursive_permissions(mydir, gid=portage_gid, dirmode=dirmode, dirmask=modemask, filemode=filemode, filemask=modemask, onerror=onerror): - raise portage_exception.OperationNotPermitted( + raise portage.exception.OperationNotPermitted( "Failed to apply recursive permissions for the portage group.") - except portage_exception.PortageException, e: + except portage.exception.PortageException, e: if not os.path.isdir(mysettings["DISTDIR"]): writemsg("!!! %s\n" % str(e), noiselevel=-1) writemsg("!!! Directory Not Found: DISTDIR='%s'\n" % mysettings["DISTDIR"], noiselevel=-1) @@ -2446,9 +2446,9 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks", else: if use_locks and can_fetch: if locks_in_subdir: - file_lock = portage_locks.lockfile(mysettings["DISTDIR"]+"/"+locks_in_subdir+"/"+myfile,wantnewlockfile=1) + file_lock = portage.locks.lockfile(mysettings["DISTDIR"]+"/"+locks_in_subdir+"/"+myfile,wantnewlockfile=1) else: - file_lock = portage_locks.lockfile(mysettings["DISTDIR"]+"/"+myfile,wantnewlockfile=1) + file_lock = portage.locks.lockfile(mysettings["DISTDIR"]+"/"+myfile,wantnewlockfile=1) try: if not listonly: if fsmirrors and not os.path.exists(myfile_path): @@ -2475,7 +2475,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks", apply_secpass_permissions( myfile_path, gid=portage_gid, mode=0664, mask=02, stat_cached=mystat) - except portage_exception.PortageException, e: + except portage.exception.PortageException, e: if not os.access(myfile_path, os.R_OK): writemsg("!!! Failed to adjust permissions:" + \ " %s\n" % str(e), noiselevel=-1) @@ -2488,7 +2488,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks", not restrict_fetch: fetched = 1 # Try to resume this download. else: - verified_ok, reason = portage_checksum.verify_all( + verified_ok, reason = portage.checksum.verify_all( myfile_path, mydigests[myfile]) if not verified_ok: writemsg("!!! Previously fetched" + \ @@ -2578,7 +2578,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks", con = con.replace(mysettings["PORTAGE_T"], mysettings["PORTAGE_FETCH_T"]) selinux.setexec(con) - myret = portage_exec.spawn_bash(myfetch, + myret = portage.process.spawn_bash(myfetch, env=mysettings.environ(), **spawn_keywords) if mysettings.selinux_enabled(): @@ -2588,9 +2588,9 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks", try: apply_secpass_permissions(myfile_path, gid=portage_gid, mode=0664, mask=02) - except portage_exception.FileNotFound, e: + except portage.exception.FileNotFound, e: pass - except portage_exception.PortageException, e: + except portage.exception.PortageException, e: if not os.access(myfile_path, os.R_OK): writemsg("!!! Failed to adjust permissions:" + \ " %s\n" % str(e), noiselevel=-1) @@ -2628,7 +2628,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks", # file NOW, for those users who don't have a stable/continuous # net connection. This way we have a chance to try to download # from another mirror... - verified_ok,reason = portage_checksum.verify_all(mysettings["DISTDIR"]+"/"+myfile, mydigests[myfile]) + verified_ok,reason = portage.checksum.verify_all(mysettings["DISTDIR"]+"/"+myfile, mydigests[myfile]) if not verified_ok: print reason writemsg("!!! Fetched file: "+str(myfile)+" VERIFY FAILED!\n", @@ -2657,7 +2657,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks", noiselevel=-1) finally: if use_locks and file_lock: - portage_locks.unlockfile(file_lock) + portage.locks.unlockfile(file_lock) if listonly: writemsg_stdout("\n", noiselevel=-1) @@ -2685,7 +2685,7 @@ def digestgen(myarchives, mysettings, overwrite=1, manifestonly=0, myportdb=None """ Generates a digest file if missing. Assumes all files are available. DEPRECATED: this now only is a compability wrapper for - portage_manifest.Manifest() + portage.manifest.Manifest() NOTE: manifestonly and overwrite are useless with manifest2 and are therefore ignored.""" if myportdb is None: @@ -2706,8 +2706,8 @@ def digestgen(myarchives, mysettings, overwrite=1, manifestonly=0, myportdb=None # fetches when sufficient digests already exist. To ease transition # while Manifest 1 is being removed, only require hashes that will # exist before and after the transition. - required_hash_types = set(portage_const.MANIFEST1_HASH_FUNCTIONS - ).intersection(portage_const.MANIFEST2_HASH_FUNCTIONS) + required_hash_types = set(portage.const.MANIFEST1_HASH_FUNCTIONS + ).intersection(portage.const.MANIFEST2_HASH_FUNCTIONS) required_hash_types.add("size") dist_hashes = mf.fhashdict.get("DIST", {}) missing_hashes = set() @@ -2750,7 +2750,7 @@ def digestgen(myarchives, mysettings, overwrite=1, manifestonly=0, myportdb=None assumeDistHashesSometimes=True, assumeDistHashesAlways=( "assume-digests" in mysettings.features)) - except portage_exception.FileNotFound, e: + except portage.exception.FileNotFound, e: writemsg(("!!! File %s doesn't exist, can't update " + \ "Manifest\n") % e, noiselevel=-1) return 0 @@ -2790,7 +2790,7 @@ def digestParseFile(myfilename, mysettings=None): and returns a dict with the filenames as keys and {checksumkey:checksum} as the values. DEPRECATED: this function is now only a compability wrapper for - portage_manifest.Manifest().""" + portage.manifest.Manifest().""" mysplit = myfilename.split(os.sep) if mysplit[-2] == "files" and mysplit[-1].startswith("digest-"): @@ -2807,7 +2807,7 @@ def digestParseFile(myfilename, mysettings=None): def digestcheck(myfiles, mysettings, strict=0, justmanifest=0): """Verifies checksums. Assumes all files have been downloaded. DEPRECATED: this is now only a compability wrapper for - portage_manifest.Manifest().""" + portage.manifest.Manifest().""" if not strict: return 1 pkgdir = mysettings["O"] @@ -2838,12 +2838,12 @@ def digestcheck(myfiles, mysettings, strict=0, justmanifest=0): eout.eend(1) writemsg("\n!!! Missing digest for %s\n" % str(e), noiselevel=-1) return 0 - except portage_exception.FileNotFound, e: + except portage.exception.FileNotFound, e: eout.eend(1) writemsg("\n!!! A file listed in the Manifest could not be found: %s\n" % str(e), noiselevel=-1) return 0 - except portage_exception.DigestException, e: + except portage.exception.DigestException, e: eout.eend(1) writemsg("\n!!! Digest verification failed:\n", noiselevel=-1) writemsg("!!! %s\n" % e.value[0], noiselevel=-1) @@ -2929,7 +2929,7 @@ def spawnebuild(mydo,actionmap,mysettings,debug,alwaysdep=0,logfile=None): def eapi_is_supported(eapi): - return str(eapi).strip() == str(portage_const.EAPI).strip() + return str(eapi).strip() == str(portage.const.EAPI).strip() def doebuild_environment(myebuild, mydo, myroot, mysettings, debug, use_cache, mydbapi): @@ -2944,7 +2944,7 @@ def doebuild_environment(myebuild, mydo, myroot, mysettings, debug, use_cache, m mycpv = cat+"/"+mypv mysplit=pkgsplit(mypv,silent=0) if mysplit is None: - raise portage_exception.IncorrectParameter( + raise portage.exception.IncorrectParameter( "Invalid ebuild path: '%s'" % myebuild) if mydo != "depend": @@ -2985,7 +2985,7 @@ def doebuild_environment(myebuild, mydo, myroot, mysettings, debug, use_cache, m mysettings["PV"] = mysplit[1] mysettings["PR"] = mysplit[2] - if portage_util.noiselimit < 0: + if portage.util.noiselimit < 0: mysettings["PORTAGE_QUIET"] = "1" if mydo != "depend": @@ -2993,9 +2993,9 @@ def doebuild_environment(myebuild, mydo, myroot, mysettings, debug, use_cache, m mydbapi.aux_get(mycpv, ["EAPI", "INHERITED", "SLOT", "RESTRICT"]) if not eapi_is_supported(eapi): # can't do anything with this. - raise portage_exception.UnsupportedAPIException(mycpv, eapi) + raise portage.exception.UnsupportedAPIException(mycpv, eapi) mysettings["PORTAGE_RESTRICT"] = " ".join(flatten( - portage_dep.use_reduce(portage_dep.paren_reduce( + portage.dep.use_reduce(portage.dep.paren_reduce( mysettings["RESTRICT"]), uselist=mysettings["USE"].split()))) if mysplit[2] == "r0": @@ -3099,8 +3099,8 @@ def prepare_build_dirs(myroot, mysettings, cleanup): try: for mydir in mydirs: - portage_util.ensure_dirs(mydir) - portage_util.apply_secpass_permissions(mydir, + portage.util.ensure_dirs(mydir) + portage.util.apply_secpass_permissions(mydir, gid=portage_gid, uid=portage_uid, mode=070, mask=0) for dir_key in ("PORTAGE_BUILDDIR", "HOME", "PKG_LOGDIR", "T"): """These directories don't necessarily need to be group writable. @@ -3108,16 +3108,16 @@ def prepare_build_dirs(myroot, mysettings, cleanup): to the other phases being run by an unprivileged user. Currently, we use the portage group to ensure that the unprivleged user still has write access to these directories in any case.""" - portage_util.ensure_dirs(mysettings[dir_key], mode=0775) - portage_util.apply_secpass_permissions(mysettings[dir_key], + portage.util.ensure_dirs(mysettings[dir_key], mode=0775) + portage.util.apply_secpass_permissions(mysettings[dir_key], uid=portage_uid, gid=portage_gid) - except portage_exception.PermissionDenied, e: + except portage.exception.PermissionDenied, e: writemsg("Permission Denied: %s\n" % str(e), noiselevel=-1) return 1 - except portage_exception.OperationNotPermitted, e: + except portage.exception.OperationNotPermitted, e: writemsg("Operation Not Permitted: %s\n" % str(e), noiselevel=-1) return 1 - except portage_exception.FileNotFound, e: + except portage.exception.FileNotFound, e: writemsg("File Not Found: '%s'\n" % str(e), noiselevel=-1) return 1 @@ -3151,7 +3151,7 @@ def prepare_build_dirs(myroot, mysettings, cleanup): for subdir in kwargs["subdirs"]: mydirs.append(os.path.join(basedir, subdir)) for mydir in mydirs: - modified = portage_util.ensure_dirs(mydir, + modified = portage.util.ensure_dirs(mydir, gid=portage_gid, mode=dirmode, mask=modemask) # To avoid excessive recursive stat calls, we trigger # recursion when the top level directory does not initially @@ -3166,9 +3166,9 @@ def prepare_build_dirs(myroot, mysettings, cleanup): if not apply_recursive_permissions(mydir, gid=portage_gid, dirmode=dirmode, dirmask=modemask, filemode=filemode, filemask=modemask, onerror=onerror): - raise portage_exception.OperationNotPermitted( + raise portage.exception.OperationNotPermitted( "Failed to apply recursive permissions for the portage group.") - except portage_exception.PortageException, e: + except portage.exception.PortageException, e: mysettings.features.remove(myfeature) mysettings["FEATURES"] = " ".join(mysettings.features) writemsg("!!! %s\n" % str(e), noiselevel=-1) @@ -3202,7 +3202,7 @@ def prepare_build_dirs(myroot, mysettings, cleanup): try: apply_secpass_permissions(mysettings["WORKDIR"], uid=portage_uid, gid=portage_gid, mode=workdir_mode) - except portage_exception.FileNotFound: + except portage.exception.FileNotFound: pass # ebuild.sh will create it if mysettings.get("PORT_LOGDIR", "") == "": @@ -3210,9 +3210,9 @@ def prepare_build_dirs(myroot, mysettings, cleanup): del mysettings["PORT_LOGDIR"] if "PORT_LOGDIR" in mysettings: try: - portage_util.ensure_dirs(mysettings["PORT_LOGDIR"], + portage.util.ensure_dirs(mysettings["PORT_LOGDIR"], uid=portage_uid, gid=portage_gid, mode=02770) - except portage_exception.PortageException, e: + except portage.exception.PortageException, e: writemsg("!!! %s\n" % str(e), noiselevel=-1) writemsg("!!! Permission issues with PORT_LOGDIR='%s'\n" % \ mysettings["PORT_LOGDIR"], noiselevel=-1) @@ -3362,11 +3362,11 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, mf = Manifest(pkgdir, mysettings["DISTDIR"]) try: mf.checkTypeHashes("EBUILD") - except portage_exception.FileNotFound, e: + except portage.exception.FileNotFound, e: writemsg("!!! A file listed in the Manifest " + \ "could not be found: %s\n" % str(e), noiselevel=-1) return 1 - except portage_exception.DigestException, e: + except portage.exception.DigestException, e: writemsg("!!! Digest verification failed:\n", noiselevel=-1) writemsg("!!! %s\n" % e.value[0], noiselevel=-1) writemsg("!!! Reason: %s\n" % e.value[1], noiselevel=-1) @@ -3416,10 +3416,10 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, for k, v in izip(auxdbkeys, mybytes.splitlines()): dbkey[k] = v retval = os.waitpid(mypids[0], 0)[1] - portage_exec.spawned_pids.remove(mypids[0]) + portage.process.spawned_pids.remove(mypids[0]) # If it got a signal, return the signal that was sent, but # shift in order to distinguish it from a return value. (just - # like portage_exec.spawn() would do). + # like portage.process.spawn() would do). if retval & 0xff: return (retval & 0xff) << 8 # Otherwise, return its exit code. @@ -3589,7 +3589,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, myportdb=mydbapi) elif "digest" in mysettings.features: digestgen(aalist, mysettings, overwrite=0, myportdb=mydbapi) - except portage_exception.PermissionDenied, e: + except portage.exception.PermissionDenied, e: writemsg("!!! %s\n" % str(e), noiselevel=-1) if mydo in ("digest", "manifest"): return 1 @@ -3666,9 +3666,9 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, if mydo in actionmap.keys(): if mydo=="package": - portage_util.ensure_dirs( + portage.util.ensure_dirs( os.path.join(mysettings["PKGDIR"], mysettings["CATEGORY"])) - portage_util.ensure_dirs( + portage.util.ensure_dirs( os.path.join(mysettings["PKGDIR"], "All")) retval = spawnebuild(mydo, actionmap, mysettings, debug, logfile=logfile) @@ -3719,7 +3719,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, finally: if builddir_lock: - portage_locks.unlockdir(builddir_lock) + portage.locks.unlockdir(builddir_lock) # Make sure that DISTDIR is restored to it's normal value before we return! if "PORTAGE_ACTUAL_DISTDIR" in mysettings: @@ -3980,9 +3980,9 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", newsplit.append(_expand_new_virtuals(x, edebug, mydbapi, mysettings, myroot=myroot, trees=trees, **kwargs)) continue - if portage_dep._dep_check_strict and \ + if portage.dep._dep_check_strict and \ not isvalidatom(x, allow_blockers=True): - raise portage_exception.ParseError( + raise portage.exception.ParseError( "invalid atom: '%s'" % x) mykey = dep_getkey(x) if not mykey.startswith("virtual/"): @@ -4031,7 +4031,7 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", mycheck = dep_check(depstring, mydbapi, mysettings, myroot=myroot, trees=trees, **kwargs) if not mycheck[0]: - raise portage_exception.ParseError( + raise portage.exception.ParseError( "%s: %s '%s'" % (y[0], mycheck[1], depstring)) if isblocker: virtual_atoms = [atom for atom in mycheck[1] \ @@ -4276,7 +4276,7 @@ def dep_check(depstring, mydbapi, mysettings, use="yes", mode=None, myuse=None, myusesplit=[] #convert parenthesis to sublists - mysplit = portage_dep.paren_reduce(depstring) + mysplit = portage.dep.paren_reduce(depstring) mymasks = set() useforce = set() @@ -4295,13 +4295,13 @@ def dep_check(depstring, mydbapi, mysettings, use="yes", mode=None, myuse=None, useforce.update(mysettings.useforce) useforce.difference_update(mymasks) try: - mysplit = portage_dep.use_reduce(mysplit, uselist=myusesplit, + mysplit = portage.dep.use_reduce(mysplit, uselist=myusesplit, masklist=mymasks, matchall=(use=="all"), excludeall=useforce) - except portage_exception.InvalidDependString, e: + except portage.exception.InvalidDependString, e: return [0, str(e)] # Do the || conversions - mysplit=portage_dep.dep_opconvert(mysplit) + mysplit=portage.dep.dep_opconvert(mysplit) if mysplit == []: #dependencies were reduced to nothing @@ -4313,7 +4313,7 @@ def dep_check(depstring, mydbapi, mysettings, use="yes", mode=None, myuse=None, mysplit = _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, use=use, mode=mode, myuse=myuse, use_cache=use_cache, use_binaries=use_binaries, myroot=myroot, trees=trees) - except portage_exception.ParseError, e: + except portage.exception.ParseError, e: return [0, str(e)] mysplit2=mysplit[:] @@ -4470,7 +4470,7 @@ def cpv_expand(mycpv, mydb=None, use_cache=1, settings=None): return mykey def getmaskingreason(mycpv, settings=None, portdb=None): - from portage_util import grablines + from portage.util import grablines if settings is None: settings = globals()["settings"] if portdb is None: @@ -4571,7 +4571,7 @@ def getmaskingstatus(mycpv, settings=None, portdb=None): # error message will have already been printed to stderr. return ["corruption"] if not eapi_is_supported(eapi): - return ["required EAPI %s, supported EAPI %s" % (eapi, portage_const.EAPI)] + return ["required EAPI %s, supported EAPI %s" % (eapi, portage.const.EAPI)] mygroups = mygroups.split() pgroups = settings["ACCEPT_KEYWORDS"].split() myarch = settings["ARCH"] @@ -4733,7 +4733,7 @@ class dbapi: mydep = dep_expand(origdep, mydb=self, settings=self.settings) mykey=dep_getkey(mydep) mylist = match_from_list(mydep,self.cp_list(mykey,use_cache=use_cache)) - myslot = portage_dep.dep_getslot(mydep) + myslot = portage.dep.dep_getslot(mydep) if myslot is not None: mylist = [cpv for cpv in mylist \ if self.aux_get(cpv, ["SLOT"])[0] == myslot] @@ -4747,7 +4747,7 @@ class dbapi: if re.search("portage_lockfile$",mypath): if not os.environ.has_key("PORTAGE_MASTER_PID"): writemsg("Lockfile removed: %s\n" % mypath, 1) - portage_locks.unlockfile((mypath,None,None)) + portage.locks.unlockfile((mypath,None,None)) else: # Nothing we can do about it. We're probably sandboxed. pass @@ -5028,7 +5028,7 @@ class vardbapi(dbapi): # sanity check for cp in [origcp,newcp]: if not (isvalidatom(cp) and isjustname(cp)): - raise portage_exception.InvalidPackageName(cp) + raise portage.exception.InvalidPackageName(cp) origmatches=self.match(origcp,use_cache=0) if not origmatches: return @@ -5087,7 +5087,7 @@ class vardbapi(dbapi): newslot=mylist[3] if not isvalidatom(pkg): - raise portage_exception.InvalidAtom(pkg) + raise portage.exception.InvalidAtom(pkg) origmatches=self.match(pkg,use_cache=0) @@ -5186,7 +5186,7 @@ class vardbapi(dbapi): del self.matchcache[mycat] mymatch = match_from_list(mydep, self.cp_list(mykey, use_cache=use_cache)) - myslot = portage_dep.dep_getslot(mydep) + myslot = portage.dep.dep_getslot(mydep) if myslot is not None: mymatch = [cpv for cpv in mymatch \ if self.aux_get(cpv, ["SLOT"])[0] == myslot] @@ -5202,7 +5202,7 @@ class vardbapi(dbapi): self.matchcache[mycat]={} if not self.matchcache[mycat].has_key(mydep): mymatch=match_from_list(mydep,self.cp_list(mykey,use_cache=use_cache)) - myslot = portage_dep.dep_getslot(mydep) + myslot = portage.dep.dep_getslot(mydep) if myslot is not None: mymatch = [cpv for cpv in mymatch \ if self.aux_get(cpv, ["SLOT"])[0] == myslot] @@ -5232,7 +5232,7 @@ class vardbapi(dbapi): f = atomic_ofstream(self._aux_cache_filename) cPickle.dump(self._aux_cache, f, -1) f.close() - portage_util.apply_secpass_permissions( + portage.util.apply_secpass_permissions( self._aux_cache_filename, gid=portage_gid, mode=0644) except (IOError, OSError), e: pass @@ -5440,7 +5440,7 @@ class vartree(object): mylines, myuse = self.dbapi.aux_get(mycpv, ["PROVIDE","USE"]) if mylines: myuse = myuse.split() - mylines = flatten(portage_dep.use_reduce(portage_dep.paren_reduce(mylines), uselist=myuse)) + mylines = flatten(portage.dep.use_reduce(portage.dep.paren_reduce(mylines), uselist=myuse)) for myprovide in mylines: mys = catpkgsplit(myprovide) if not mys: @@ -5606,15 +5606,15 @@ class portdbapi(dbapi): self.manifestMissingCache = [] if "gpg" in self.mysettings.features: - self.manifestVerifyLevel = portage_gpg.EXISTS + self.manifestVerifyLevel = portage.gpg.EXISTS if "strict" in self.mysettings.features: - self.manifestVerifyLevel = portage_gpg.MARGINAL - self.manifestVerifier = portage_gpg.FileChecker(self.mysettings["PORTAGE_GPG_DIR"], "gentoo.gpg", minimumTrust=self.manifestVerifyLevel) + self.manifestVerifyLevel = portage.gpg.MARGINAL + self.manifestVerifier = portage.gpg.FileChecker(self.mysettings["PORTAGE_GPG_DIR"], "gentoo.gpg", minimumTrust=self.manifestVerifyLevel) elif "severe" in self.mysettings.features: - self.manifestVerifyLevel = portage_gpg.TRUSTED - self.manifestVerifier = portage_gpg.FileChecker(self.mysettings["PORTAGE_GPG_DIR"], "gentoo.gpg", requireSignedRing=True, minimumTrust=self.manifestVerifyLevel) + self.manifestVerifyLevel = portage.gpg.TRUSTED + self.manifestVerifier = portage.gpg.FileChecker(self.mysettings["PORTAGE_GPG_DIR"], "gentoo.gpg", requireSignedRing=True, minimumTrust=self.manifestVerifyLevel) else: - self.manifestVerifier = portage_gpg.FileChecker(self.mysettings["PORTAGE_GPG_DIR"], "gentoo.gpg", minimumTrust=self.manifestVerifyLevel) + self.manifestVerifier = portage.gpg.FileChecker(self.mysettings["PORTAGE_GPG_DIR"], "gentoo.gpg", minimumTrust=self.manifestVerifyLevel) #self.root=settings["PORTDIR"] self.porttree_root = os.path.realpath(porttree_root) @@ -5683,7 +5683,7 @@ class portdbapi(dbapi): try: for mydir in (self.depcachedir,): - if portage_util.ensure_dirs(mydir, gid=portage_gid, mode=dirmode, mask=modemask): + if portage.util.ensure_dirs(mydir, gid=portage_gid, mode=dirmode, mask=modemask): writemsg("Adjusting permissions recursively: '%s'\n" % mydir, noiselevel=-1) def onerror(e): @@ -5691,9 +5691,9 @@ class portdbapi(dbapi): if not apply_recursive_permissions(mydir, gid=portage_gid, dirmode=dirmode, dirmask=modemask, filemode=filemode, filemask=modemask, onerror=onerror): - raise portage_exception.OperationNotPermitted( + raise portage.exception.OperationNotPermitted( "Failed to apply recursive permissions for the portage group.") - except portage_exception.PortageException, e: + except portage.exception.PortageException, e: pass def close_caches(self): @@ -5787,35 +5787,35 @@ class portdbapi(dbapi): myManifestPath = "/".join(myebuild.split("/")[:-1])+"/Manifest" if "gpg" in self.mysettings.features: try: - mys = portage_gpg.fileStats(myManifestPath) + mys = portage.gpg.fileStats(myManifestPath) if (myManifestPath in self.manifestCache) and \ (self.manifestCache[myManifestPath] == mys): pass elif self.manifestVerifier: if not self.manifestVerifier.verify(myManifestPath): # Verification failed the desired level. - raise portage_exception.UntrustedSignature, "Untrusted Manifest: %(manifest)s" % {"manifest":myManifestPath} + raise portage.exception.UntrustedSignature, "Untrusted Manifest: %(manifest)s" % {"manifest":myManifestPath} if ("severe" in self.mysettings.features) and \ - (mys != portage_gpg.fileStats(myManifestPath)): - raise portage_exception.SecurityViolation, "Manifest changed: %(manifest)s" % {"manifest":myManifestPath} + (mys != portage.gpg.fileStats(myManifestPath)): + raise portage.exception.SecurityViolation, "Manifest changed: %(manifest)s" % {"manifest":myManifestPath} - except portage_exception.InvalidSignature, e: + except portage.exception.InvalidSignature, e: if ("strict" in self.mysettings.features) or \ ("severe" in self.mysettings.features): raise writemsg("!!! INVALID MANIFEST SIGNATURE DETECTED: %(manifest)s\n" % {"manifest":myManifestPath}) - except portage_exception.MissingSignature, e: + except portage.exception.MissingSignature, e: if ("severe" in self.mysettings.features): raise if ("strict" in self.mysettings.features): if myManifestPath not in self.manifestMissingCache: writemsg("!!! WARNING: Missing signature in: %(manifest)s\n" % {"manifest":myManifestPath}) self.manifestMissingCache.insert(0,myManifestPath) - except (OSError,portage_exception.FileNotFound), e: + except (OSError,portage.exception.FileNotFound), e: if ("strict" in self.mysettings.features) or \ ("severe" in self.mysettings.features): - raise portage_exception.SecurityViolation, "Error in verification of signatures: %(errormsg)s" % {"errormsg":str(e)} + raise portage.exception.SecurityViolation, "Error in verification of signatures: %(errormsg)s" % {"errormsg":str(e)} writemsg("!!! Manifest is missing or inaccessable: %(manifest)s\n" % {"manifest":myManifestPath}, noiselevel=-1) @@ -5911,8 +5911,8 @@ class portdbapi(dbapi): if useflags is None: useflags = mysettings["USE"].split() - myurilist = portage_dep.paren_reduce(myuris) - myurilist = portage_dep.use_reduce(myurilist,uselist=useflags,matchall=all) + myurilist = portage.dep.paren_reduce(myuris) + myurilist = portage.dep.use_reduce(myurilist,uselist=useflags,matchall=all) newuris = flatten(myurilist) myfiles = [] @@ -5979,9 +5979,9 @@ class portdbapi(dbapi): reason = "digest missing" else: try: - ok, reason = portage_checksum.verify_all( + ok, reason = portage.checksum.verify_all( os.path.join(self.mysettings["DISTDIR"], x), mysums[x]) - except portage_exception.FileNotFound, e: + except portage.exception.FileNotFound, e: ok = False reason = "File Not Found: '%s'" % str(e) if not ok: @@ -6103,7 +6103,7 @@ class portdbapi(dbapi): else: print "ERROR: xmatch doesn't handle",level,"query!" raise KeyError - myslot = portage_dep.dep_getslot(mydep) + myslot = portage.dep.dep_getslot(mydep) if myslot is not None: slotmatches = [] for cpv in myval: @@ -6193,7 +6193,7 @@ class portdbapi(dbapi): keys, eapi = self.aux_get(mycpv, ["KEYWORDS", "EAPI"]) except KeyError: continue - except portage_exception.PortageException, e: + except portage.exception.PortageException, e: writemsg("!!! Error: aux_get('%s', ['KEYWORDS', 'EAPI'])\n" % \ mycpv, noiselevel=-1) writemsg("!!! %s\n" % str(e), noiselevel=-1) @@ -6276,7 +6276,7 @@ class binarytree(object): # sanity check for cp in [origcp,newcp]: if not (isvalidatom(cp) and isjustname(cp)): - raise portage_exception.InvalidPackageName(cp) + raise portage.exception.InvalidPackageName(cp) origcat = origcp.split("/")[0] mynewcat=newcp.split("/")[0] origmatches=self.dbapi.cp_list(origcp) @@ -6381,7 +6381,7 @@ class binarytree(object): newslot=mylist[3] if not isvalidatom(pkg): - raise portage_exception.InvalidAtom(pkg) + raise portage.exception.InvalidAtom(pkg) origmatches=self.dbapi.match(pkg) if not origmatches: @@ -6722,7 +6722,7 @@ class dblink: raise ValueError self.myroot=myroot - protect_obj = portage_util.ConfigProtect(myroot, + protect_obj = portage.util.ConfigProtect(myroot, mysettings.get("CONFIG_PROTECT","").split(), mysettings.get("CONFIG_PROTECT_MASK","").split()) self.updateprotect = protect_obj.updateprotect @@ -6735,12 +6735,12 @@ class dblink: if self._lock_vdb: raise AssertionError("Lock already held.") # At least the parent needs to exist for the lock file. - portage_util.ensure_dirs(self.dbroot) - self._lock_vdb = portage_locks.lockdir(self.dbroot) + portage.util.ensure_dirs(self.dbroot) + self._lock_vdb = portage.locks.lockdir(self.dbroot) def unlockdb(self): if self._lock_vdb: - portage_locks.unlockdir(self._lock_vdb) + portage.locks.unlockdir(self._lock_vdb) self._lock_vdb = None def getpath(self): @@ -6898,27 +6898,27 @@ class dblink: try: doebuild_environment(myebuildpath, "prerm", self.myroot, self.settings, 0, 0, self.vartree.dbapi) - except portage_exception.UnsupportedAPIException, e: + except portage.exception.UnsupportedAPIException, e: # Sometimes this happens due to corruption of the EAPI file. writemsg("!!! FAILED prerm: %s\n" % \ os.path.join(self.dbdir, "EAPI"), noiselevel=-1) writemsg("%s\n" % str(e), noiselevel=-1) return 1 catdir = os.path.dirname(self.settings["PORTAGE_BUILDDIR"]) - portage_util.ensure_dirs(os.path.dirname(catdir), + portage.util.ensure_dirs(os.path.dirname(catdir), uid=portage_uid, gid=portage_gid, mode=070, mask=0) builddir_lock = None catdir_lock = None try: if myebuildpath: - catdir_lock = portage_locks.lockdir(catdir) - portage_util.ensure_dirs(catdir, + catdir_lock = portage.locks.lockdir(catdir) + portage.util.ensure_dirs(catdir, uid=portage_uid, gid=portage_gid, mode=070, mask=0) - builddir_lock = portage_locks.lockdir( + builddir_lock = portage.locks.lockdir( self.settings["PORTAGE_BUILDDIR"]) try: - portage_locks.unlockdir(catdir_lock) + portage.locks.unlockdir(catdir_lock) finally: catdir_lock = None # Eventually, we'd like to pass in the saved ebuild env here... @@ -6951,11 +6951,11 @@ class dblink: finally: if builddir_lock: - portage_locks.unlockdir(builddir_lock) + portage.locks.unlockdir(builddir_lock) try: if myebuildpath and not catdir_lock: # Lock catdir for removal if empty. - catdir_lock = portage_locks.lockdir(catdir) + catdir_lock = portage.locks.lockdir(catdir) finally: if catdir_lock: try: @@ -6964,7 +6964,7 @@ class dblink: if e.errno != errno.ENOTEMPTY: raise del e - portage_locks.unlockdir(catdir_lock) + portage.locks.unlockdir(catdir_lock) env_update(target_root=self.myroot, prev_mtimes=ldpath_mtimes, contents=contents) return os.EX_OK @@ -7050,8 +7050,8 @@ class dblink: continue mymd5 = None try: - mymd5 = portage_checksum.perform_md5(obj, calc_prelink=1) - except portage_exception.FileNotFound, e: + mymd5 = portage.checksum.perform_md5(obj, calc_prelink=1) + except portage.exception.FileNotFound, e: # the file has disappeared between now and our stat call writemsg_stdout("--- !obj %s %s\n" % ("obj", obj)) continue @@ -7575,14 +7575,14 @@ class dblink: elif self.isprotected(mydest): # Use md5 of the target in ${D} if it exists... try: - newmd5 = portage_checksum.perform_md5( + newmd5 = portage.checksum.perform_md5( join(srcroot, myabsto)) - except portage_exception.FileNotFound: + except portage.exception.FileNotFound: # Maybe the target is merged already. try: - newmd5 = portage_checksum.perform_md5( + newmd5 = portage.checksum.perform_md5( myrealto) - except portage_exception.FileNotFound: + except portage.exception.FileNotFound: newmd5 = None mydest = new_protect_filename(mydest,newmd5=newmd5) @@ -7661,7 +7661,7 @@ class dblink: return 1 elif stat.S_ISREG(mymode): # we are merging a regular file - mymd5=portage_checksum.perform_md5(mysrc,calc_prelink=1) + mymd5=portage.checksum.perform_md5(mysrc,calc_prelink=1) # calculate config file protection stuff mydestdir=os.path.dirname(mydest) moveme=1 @@ -7680,7 +7680,7 @@ class dblink: # we only need to tweak mydest if cfg file management is in play. if self.isprotected(mydest): # we have a protection path; enable config file management. - destmd5=portage_checksum.perform_md5(mydest,calc_prelink=1) + destmd5=portage.checksum.perform_md5(mydest,calc_prelink=1) if mymd5==destmd5: #file already in place; simply update mtimes of destination os.utime(mydest,(thismtime,thismtime)) @@ -7758,7 +7758,7 @@ class dblink: # and now we're at the end. yay. myf.close() - mymd5 = portage_checksum.perform_md5(mydest, calc_prelink=1) + mymd5 = portage.checksum.perform_md5(mydest, calc_prelink=1) os.utime(mydest,(thismtime,thismtime)) if mymtime!=None: @@ -7836,7 +7836,7 @@ class dblink: class FetchlistDict(UserDict.DictMixin): """This provide a mapping interface to retrieve fetch lists. It's used - to allow portage_manifest.Manifest to access fetch lists via a standard + to allow portage.manifest.Manifest to access fetch lists via a standard mapping interface rather than use the dbapi directly.""" def __init__(self, pkgdir, settings, mydbapi): """pkgdir is a directory containing ebuilds and settings is passed into @@ -7876,7 +7876,7 @@ def pkgmerge(mytbz2, myroot, mysettings, mydbapi=None, vartree=None, prev_mtimes try: """ Don't lock the tbz2 file because the filesytem could be readonly or shared by a cluster.""" - #tbz2_lock = portage_locks.lockfile(mytbz2, wantnewlockfile=1) + #tbz2_lock = portage.locks.lockfile(mytbz2, wantnewlockfile=1) mypkg = os.path.basename(mytbz2)[:-5] xptbz2 = xpak.tbz2(mytbz2) @@ -7895,14 +7895,14 @@ def pkgmerge(mytbz2, myroot, mysettings, mydbapi=None, vartree=None, prev_mtimes infloc = os.path.join(builddir, "build-info") myebuild = os.path.join( infloc, os.path.basename(mytbz2)[:-4] + "ebuild") - portage_util.ensure_dirs(os.path.dirname(catdir), + portage.util.ensure_dirs(os.path.dirname(catdir), uid=portage_uid, gid=portage_gid, mode=070, mask=0) - catdir_lock = portage_locks.lockdir(catdir) - portage_util.ensure_dirs(catdir, + catdir_lock = portage.locks.lockdir(catdir) + portage.util.ensure_dirs(catdir, uid=portage_uid, gid=portage_gid, mode=070, mask=0) - builddir_lock = portage_locks.lockdir(builddir) + builddir_lock = portage.locks.lockdir(builddir) try: - portage_locks.unlockdir(catdir_lock) + portage.locks.unlockdir(catdir_lock) finally: catdir_lock = None try: @@ -7912,14 +7912,14 @@ def pkgmerge(mytbz2, myroot, mysettings, mydbapi=None, vartree=None, prev_mtimes raise del e for mydir in (builddir, pkgloc, infloc): - portage_util.ensure_dirs(mydir, uid=portage_uid, + portage.util.ensure_dirs(mydir, uid=portage_uid, gid=portage_gid, mode=0755) writemsg_stdout(">>> Extracting info\n") xptbz2.unpackinfo(infloc) mysettings.load_infodir(infloc) # Store the md5sum in the vdb. fp = open(os.path.join(infloc, "BINPKGMD5"), "w") - fp.write(str(portage_checksum.perform_md5(mytbz2))+"\n") + fp.write(str(portage.checksum.perform_md5(mytbz2))+"\n") fp.close() debug = mysettings.get("PORTAGE_DEBUG", "") == "1" @@ -7932,13 +7932,13 @@ def pkgmerge(mytbz2, myroot, mysettings, mydbapi=None, vartree=None, prev_mtimes return retval writemsg_stdout(">>> Extracting %s\n" % mypkg) - retval = portage_exec.spawn_bash( + retval = portage.process.spawn_bash( "bzip2 -dqc -- '%s' | tar -xp -C '%s' -f -" % (mytbz2, pkgloc), env=mysettings.environ()) if retval != os.EX_OK: writemsg("!!! Error Extracting '%s'\n" % mytbz2, noiselevel=-1) return retval - #portage_locks.unlockfile(tbz2_lock) + #portage.locks.unlockfile(tbz2_lock) #tbz2_lock = None mylink = dblink(mycat, mypkg, myroot, mysettings, vartree=vartree, @@ -7948,7 +7948,7 @@ def pkgmerge(mytbz2, myroot, mysettings, mydbapi=None, vartree=None, prev_mtimes return retval finally: if tbz2_lock: - portage_locks.unlockfile(tbz2_lock) + portage.locks.unlockfile(tbz2_lock) if builddir_lock: try: shutil.rmtree(builddir) @@ -7956,11 +7956,11 @@ def pkgmerge(mytbz2, myroot, mysettings, mydbapi=None, vartree=None, prev_mtimes if e.errno != errno.ENOENT: raise del e - portage_locks.unlockdir(builddir_lock) + portage.locks.unlockdir(builddir_lock) try: if not catdir_lock: # Lock catdir for removal if empty. - catdir_lock = portage_locks.lockdir(catdir) + catdir_lock = portage.locks.lockdir(catdir) finally: if catdir_lock: try: @@ -7969,7 +7969,7 @@ def pkgmerge(mytbz2, myroot, mysettings, mydbapi=None, vartree=None, prev_mtimes if e.errno != errno.ENOTEMPTY: raise del e - portage_locks.unlockdir(catdir_lock) + portage.locks.unlockdir(catdir_lock) def deprecated_profile_check(): if not os.access(DEPRECATED_PROFILE_FILE, os.R_OK): @@ -8013,7 +8013,7 @@ def commit_mtimedb(mydict=None, filename=None): f = atomic_ofstream(filename) cPickle.dump(d, f, -1) f.close() - portage_util.apply_secpass_permissions(filename, uid=uid, gid=portage_gid, mode=0664) + portage.util.apply_secpass_permissions(filename, uid=uid, gid=portage_gid, mode=0664) except (IOError, OSError), e: pass @@ -8051,7 +8051,7 @@ def global_updates(mysettings, trees, prev_mtimes): update_data = grab_updates(updpath) else: update_data = grab_updates(updpath, prev_mtimes) - except portage_exception.DirectoryNotFound: + except portage.exception.DirectoryNotFound: writemsg("--- 'profiles/updates' is empty or not available. Empty portage tree?\n") return myupd = None @@ -8183,20 +8183,20 @@ def create_trees(config_root=None, target_root=None, trees=None): del trees[myroot]["porttree"], myroot, portdb settings = config(config_root=config_root, target_root=target_root, - config_incrementals=portage_const.INCREMENTALS) + config_incrementals=portage.const.INCREMENTALS) settings.lock() settings.validate() myroots = [(settings["ROOT"], settings)] if settings["ROOT"] != "/": settings = config(config_root=None, target_root=None, - config_incrementals=portage_const.INCREMENTALS) + config_incrementals=portage.const.INCREMENTALS) settings.lock() settings.validate() myroots.append((settings["ROOT"], settings)) for myroot, mysettings in myroots: - trees[myroot] = portage_util.LazyItemsDict(trees.get(myroot, None)) + trees[myroot] = portage.util.LazyItemsDict(trees.get(myroot, None)) trees[myroot].addLazySingleton("virtuals", mysettings.getvirtuals, myroot) trees[myroot].addLazySingleton( "vartree", vartree, myroot, categories=mysettings.categories, diff --git a/pym/portage/checksum.py b/pym/portage/checksum.py index 7f1a89c8e..51f8e37bc 100644 --- a/pym/portage/checksum.py +++ b/pym/portage/checksum.py @@ -1,18 +1,18 @@ -# portage_checksum.py -- core Portage functionality +# portage.checksum.py -- core Portage functionality # Copyright 1998-2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id$ -from portage_const import PRIVATE_PATH,PRELINK_BINARY,HASHING_BLOCKSIZE +from portage.const import PRIVATE_PATH,PRELINK_BINARY,HASHING_BLOCKSIZE import os import errno import shutil import stat -import portage_exception -import portage_exec -import portage_util -import portage_locks +import portage.exception +import portage.process +import portage.util +import portage.locks import commands import sha @@ -111,7 +111,7 @@ def verify_all(filename, mydict, calc_prelink=0, strict=0): return False,("Filesize does not match recorded size", mysize, mydict["size"]) except OSError, e: if e.errno == errno.ENOENT: - raise portage_exception.FileNotFound(filename) + raise portage.exception.FileNotFound(filename) return False, (str(e), None, None) for x in mydict.keys(): if x == "size": @@ -120,7 +120,7 @@ def verify_all(filename, mydict, calc_prelink=0, strict=0): myhash = perform_checksum(filename, x, calc_prelink=calc_prelink)[0] if mydict[x] != myhash: if strict: - raise portage_exception.DigestException, "Failed to verify '$(file)s' on checksum type '%(type)s'" % {"file":filename, "type":x} + raise portage.exception.DigestException, "Failed to verify '$(file)s' on checksum type '%(type)s'" % {"file":filename, "type":x} else: file_is_ok = False reason = (("Failed on %s verification" % x), myhash,mydict[x]) @@ -168,21 +168,21 @@ def perform_checksum(filename, hashname="MD5", calc_prelink=0): mylock = None try: if calc_prelink and prelink_capable: - mylock = portage_locks.lockfile(prelink_tmpfile, wantnewlockfile=1) + mylock = portage.locks.lockfile(prelink_tmpfile, wantnewlockfile=1) # Create non-prelinked temporary file to checksum. # Files rejected by prelink are summed in place. - retval = portage_exec.spawn([PRELINK_BINARY, "--undo", "-o", + retval = portage.process.spawn([PRELINK_BINARY, "--undo", "-o", prelink_tmpfile, filename], fd_pipes={}) if retval == os.EX_OK: myfilename = prelink_tmpfile try: if hashname not in hashfunc_map: - raise portage_exception.DigestException(hashname + \ + raise portage.exception.DigestException(hashname + \ " hash function not available (needs dev-python/pycrypto)") myhash, mysize = hashfunc_map[hashname](myfilename) except (OSError, IOError), e: if e.errno == errno.ENOENT: - raise portage_exception.FileNotFound(myfilename) + raise portage.exception.FileNotFound(myfilename) raise if calc_prelink and prelink_capable: try: @@ -194,7 +194,7 @@ def perform_checksum(filename, hashname="MD5", calc_prelink=0): return myhash, mysize finally: if mylock: - portage_locks.unlockfile(mylock) + portage.locks.unlockfile(mylock) def perform_multiple_checksums(filename, hashes=["MD5"], calc_prelink=0): """ @@ -214,6 +214,6 @@ def perform_multiple_checksums(filename, hashes=["MD5"], calc_prelink=0): rVal = {} for x in hashes: if x not in hashfunc_map: - raise portage_exception.DigestException, x+" hash function not available (needs dev-python/pycrypto)" + raise portage.exception.DigestException, x+" hash function not available (needs dev-python/pycrypto)" rVal[x] = perform_checksum(filename, x, calc_prelink)[0] return rVal diff --git a/pym/portage/data.py b/pym/portage/data.py index 707c76b2d..1ed53419c 100644 --- a/pym/portage/data.py +++ b/pym/portage/data.py @@ -1,4 +1,4 @@ -# portage_data.py -- Calculated/Discovered Data Values +# portage.data.py -- Calculated/Discovered Data Values # Copyright 1998-2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id$ @@ -7,7 +7,7 @@ if not hasattr(__builtins__, "set"): from sets import Set as set import os,pwd,grp -from portage_util import writemsg +from portage.util import writemsg from output import green,red from output import create_color_func bad = create_color_func("BAD") diff --git a/pym/portage/debug.py b/pym/portage/debug.py index 2ee8bcf28..b9e56ed00 100644 --- a/pym/portage/debug.py +++ b/pym/portage/debug.py @@ -4,8 +4,8 @@ import os, sys, threading -import portage_const -from portage_util import writemsg +import portage.const +from portage.util import writemsg def set_trace(on=True): if on: @@ -28,7 +28,7 @@ class trace_handler(object): for x in python_system_paths: self.ignore_prefixes.append(x + os.sep) - self.trim_filename = prefix_trimmer(os.path.join(portage_const.PORTAGE_BASE_PATH, "pym") + os.sep).trim + self.trim_filename = prefix_trimmer(os.path.join(portage.const.PORTAGE_BASE_PATH, "pym") + os.sep).trim self.show_local_lines = False self.max_repr_length = 200 diff --git a/pym/portage/dep.py b/pym/portage/dep.py index bf40452ac..230080b60 100644 --- a/pym/portage/dep.py +++ b/pym/portage/dep.py @@ -19,16 +19,16 @@ # import re, sys, types -import portage_exception -from portage_exception import InvalidData -from portage_versions import catpkgsplit, catsplit, pkgcmp, pkgsplit, ververify +import portage.exception +from portage.exception import InvalidData +from portage.versions import catpkgsplit, catsplit, pkgcmp, pkgsplit, ververify def cpvequal(cpv1, cpv2): split1 = catpkgsplit(cpv1) split2 = catpkgsplit(cpv2) if not split1 or not split2: - raise portage_exception.PortageException("Invalid data '%s, %s', parameter was not a CPV" % (cpv1, cpv2)) + raise portage.exception.PortageException("Invalid data '%s, %s', parameter was not a CPV" % (cpv1, cpv2)) if split1[0] != split2[0]: return False @@ -141,9 +141,9 @@ def use_reduce(deparray, uselist=[], masklist=[], matchall=0, excludeall=[]): for x in range(len(deparray)): if deparray[x] in ["||","&&"]: if len(deparray) - 1 == x or not isinstance(deparray[x+1], list): - raise portage_exception.InvalidDependString(deparray[x]+" missing atom list in \""+paren_enclose(deparray)+"\"") + raise portage.exception.InvalidDependString(deparray[x]+" missing atom list in \""+paren_enclose(deparray)+"\"") if deparray and deparray[-1] and deparray[-1][-1] == "?": - raise portage_exception.InvalidDependString("Conditional without target in \""+paren_enclose(deparray)+"\"") + raise portage.exception.InvalidDependString("Conditional without target in \""+paren_enclose(deparray)+"\"") global _dep_check_strict @@ -158,7 +158,7 @@ def use_reduce(deparray, uselist=[], masklist=[], matchall=0, excludeall=[]): rlist.append(additions) elif rlist and rlist[-1] == "||": #XXX: Currently some DEPEND strings have || lists without default atoms. - # raise portage_exception.InvalidDependString("No default atom(s) in \""+paren_enclose(deparray)+"\"") + # raise portage.exception.InvalidDependString("No default atom(s) in \""+paren_enclose(deparray)+"\"") rlist.append([]) else: @@ -210,7 +210,7 @@ def use_reduce(deparray, uselist=[], masklist=[], matchall=0, excludeall=[]): # The old deprecated behavior. rlist.append(target) else: - raise portage_exception.InvalidDependString( + raise portage.exception.InvalidDependString( "Conditional without parenthesis: '%s?'" % head) else: @@ -255,7 +255,7 @@ def get_operator(mydep): Return the operator used in a depstring. Example usage: - >>> from portage_dep import * + >>> from portage.dep import * >>> get_operator(">=test-1.0") '>=' @@ -536,7 +536,7 @@ def match_from_list(mydep, candidate_list): if mylist is not None: return mylist[:] - from portage_util import writemsg + from portage.util import writemsg if mydep[0] == "!": mydep = mydep[1:] diff --git a/pym/portage/eclass_cache.py b/pym/portage/eclass_cache.py index 91b98fec5..40d4e360f 100644 --- a/pym/portage/eclass_cache.py +++ b/pym/portage/eclass_cache.py @@ -3,9 +3,9 @@ # License: GPL2 # $Id$ -from portage_util import normalize_path, writemsg +from portage.util import normalize_path, writemsg import os, sys -from portage_data import portage_gid +from portage.data import portage_gid class cache: """ diff --git a/pym/portage/exec.py b/pym/portage/exec.py deleted file mode 100644 index 252fed2a0..000000000 --- a/pym/portage/exec.py +++ /dev/null @@ -1,336 +0,0 @@ -# portage.py -- core Portage functionality -# Copyright 1998-2004 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Id$ - - -import os, atexit, signal, sys -import portage_data - -from portage_util import dump_traceback -from portage_const import BASH_BINARY, SANDBOX_BINARY - - -try: - import resource - max_fd_limit = resource.getrlimit(resource.RLIMIT_NOFILE)[0] -except ImportError: - max_fd_limit = 256 - -if os.path.isdir("/proc/%i/fd" % os.getpid()): - def get_open_fds(): - return map(int, [fd for fd in os.listdir("/proc/%i/fd" % os.getpid()) if fd.isdigit()]) -else: - def get_open_fds(): - return xrange(max_fd_limit) - -sandbox_capable = (os.path.isfile(SANDBOX_BINARY) and - os.access(SANDBOX_BINARY, os.X_OK)) - -def spawn_bash(mycommand, debug=False, opt_name=None, **keywords): - """ - Spawns a bash shell running a specific commands - - @param mycommand: The command for bash to run - @type mycommand: String - @param debug: Turn bash debugging on (set -x) - @type debug: Boolean - @param opt_name: Name of the spawned process (detaults to binary name) - @type opt_name: String - @param keywords: Extra Dictionary arguments to pass to spawn - @type keywords: Dictionary - """ - - args = [BASH_BINARY] - if not opt_name: - opt_name = os.path.basename(mycommand.split()[0]) - if debug: - # Print commands and their arguments as they are executed. - args.append("-x") - args.append("-c") - args.append(mycommand) - return spawn(args, 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) - args=[SANDBOX_BINARY] - if not opt_name: - opt_name = os.path.basename(mycommand.split()[0]) - args.append(mycommand) - return spawn(args, opt_name=opt_name, **keywords) - -_exithandlers = [] -def atexit_register(func, *args, **kargs): - """Wrapper around atexit.register that is needed in order to track - what is registered. For example, when portage restarts itself via - os.execv, the atexit module does not work so we have to do it - manually by calling the run_exitfuncs() function in this module.""" - _exithandlers.append((func, args, kargs)) - -def run_exitfuncs(): - """This should behave identically to the routine performed by - the atexit module at exit time. It's only necessary to call this - function when atexit will not work (because of os.execv, for - example).""" - - # This function is a copy of the private atexit._run_exitfuncs() - # from the python 2.4.2 sources. The only difference from the - # original function is in the output to stderr. - exc_info = None - while _exithandlers: - func, targs, kargs = _exithandlers.pop() - try: - func(*targs, **kargs) - except SystemExit: - exc_info = sys.exc_info() - except: # No idea what they called, so we need this broad except here. - dump_traceback("Error in portage_exec.run_exitfuncs", noiselevel=0) - exc_info = sys.exc_info() - - if exc_info is not None: - raise exc_info[0], exc_info[1], exc_info[2] - -atexit.register(run_exitfuncs) - -# We need to make sure that any processes spawned are killed off when -# we exit. spawn() takes care of adding and removing pids to this list -# as it creates and cleans up processes. -spawned_pids = [] -def cleanup(): - while spawned_pids: - pid = spawned_pids.pop() - try: - if os.waitpid(pid, os.WNOHANG) == (0, 0): - os.kill(pid, signal.SIGTERM) - os.waitpid(pid, 0) - except OSError: - # This pid has been cleaned up outside - # of spawn(). - pass - -atexit_register(cleanup) - -def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False, - uid=None, gid=None, groups=None, umask=None, logfile=None, - path_lookup=True): - """ - Spawns a given command. - - @param mycommand: the command to execute - @type mycommand: String or List (Popen style list) - @param env: A dict of Key=Value pairs for env variables - @type env: Dictionary - @param opt_name: an optional name for the spawn'd process (defaults to the binary name) - @type opt_name: String - @param fd_pipes: A dict of mapping for pipes, { '0': stdin, '1': stdout } for example - @type fd_pipes: Dictionary - @param returnpid: Return the Process IDs for a successful spawn. - NOTE: This requires the caller clean up all the PIDs, otherwise spawn will clean them. - @type returnpid: Boolean - @param uid: User ID to spawn as; useful for dropping privilages - @type uid: Integer - @param gid: Group ID to spawn as; useful for dropping privilages - @type gid: Integer - @param groups: Group ID's to spawn in: useful for having the process run in multiple group contexts. - @type groups: List - @param umask: An integer representing the umask for the process (see man chmod for umask details) - @type umask: Integer - @param logfile: name of a file to use for logging purposes - @type logfile: String - @param path_lookup: If the binary is not fully specified then look for it in PATH - @type path_lookup: Boolean - - logfile requires stdout and stderr to be assigned to this process (ie not pointed - somewhere else.) - - """ - - # mycommand is either a str or a list - if isinstance(mycommand, str): - mycommand = mycommand.split() - - # If an absolute path to an executable file isn't given - # search for it unless we've been told not to. - binary = mycommand[0] - if (not os.path.isabs(binary) or not os.path.isfile(binary) - or not os.access(binary, os.X_OK)): - binary = path_lookup and find_binary(binary) or None - if not binary: - return -1 - - # If we haven't been told what file descriptors to use - # default to propogating our stdin, stdout and stderr. - if fd_pipes is None: - fd_pipes = {0:0, 1:1, 2:2} - - # mypids will hold the pids of all processes created. - mypids = [] - - if logfile: - # Using a log file requires that stdout and stderr - # are assigned to the process we're running. - if 1 not in fd_pipes or 2 not in fd_pipes: - raise ValueError(fd_pipes) - - # Create a pipe - (pr, pw) = os.pipe() - - # Create a tee process, giving it our stdout and stderr - # as well as the read end of the pipe. - mypids.extend(spawn(('tee', '-i', '-a', logfile), - returnpid=True, fd_pipes={0:pr, - 1:fd_pipes[1], 2:fd_pipes[2]})) - - # We don't need the read end of the pipe, so close it. - os.close(pr) - - # Assign the write end of the pipe to our stdout and stderr. - fd_pipes[1] = pw - fd_pipes[2] = pw - - pid = os.fork() - - if not pid: - try: - _exec(binary, mycommand, opt_name, fd_pipes, - env, gid, groups, uid, umask) - except Exception, e: - # We need to catch _any_ exception so that it doesn't - # propogate out of this function and cause exiting - # with anything other than os._exit() - sys.stderr.write("%s:\n %s\n" % (e, " ".join(mycommand))) - sys.stderr.flush() - os._exit(1) - - # Add the pid to our local and the global pid lists. - mypids.append(pid) - spawned_pids.append(pid) - - # If we started a tee process the write side of the pipe is no - # longer needed, so close it. - if logfile: - os.close(pw) - - # If the caller wants to handle cleaning up the processes, we tell - # it about all processes that were created. - if returnpid: - return mypids - - # Otherwise we clean them up. - while mypids: - - # Pull the last reader in the pipe chain. If all processes - # in the pipe are well behaved, it will die when the process - # it is reading from dies. - pid = mypids.pop(0) - - # and wait for it. - retval = os.waitpid(pid, 0)[1] - - # When it's done, we can remove it from the - # global pid list as well. - spawned_pids.remove(pid) - - if retval: - # If it failed, kill off anything else that - # isn't dead yet. - for pid in mypids: - if os.waitpid(pid, os.WNOHANG) == (0,0): - os.kill(pid, signal.SIGTERM) - os.waitpid(pid, 0) - spawned_pids.remove(pid) - - # If it got a signal, return the signal that was sent. - if (retval & 0xff): - return ((retval & 0xff) << 8) - - # Otherwise, return its exit code. - return (retval >> 8) - - # Everything succeeded - return 0 - -def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask): - - """ - Execute a given binary with options - - @param binary: Name of program to execute - @type binary: String - @param mycommand: Options for program - @type mycommand: String - @param opt_name: Name of process (defaults to binary) - @type opt_name: String - @param fd_pipes: Mapping pipes to destination; { 0:0, 1:1, 2:2 } - @type fd_pipes: Dictionary - @param env: Key,Value mapping for Environmental Variables - @type env: Dictionary - @param gid: Group ID to run the process under - @type gid: Integer - @param groups: Groups the Process should be in. - @type groups: Integer - @param uid: User ID to run the process under - @type uid: Integer - @param umask: an int representing a unix umask (see man chmod for umask details) - @type umask: Integer - @rtype: None - @returns: Never returns (calls os.execve) - """ - - # If the process we're creating hasn't been given a name - # assign it the name of the executable. - if not opt_name: - opt_name = os.path.basename(binary) - - # Set up the command's argument list. - myargs = [opt_name] - myargs.extend(mycommand[1:]) - - # Set up the command's pipes. - my_fds = {} - # To protect from cases where direct assignment could - # clobber needed fds ({1:2, 2:1}) we first dupe the fds - # into unused fds. - for fd in fd_pipes: - my_fds[fd] = os.dup(fd_pipes[fd]) - # Then assign them to what they should be. - for fd in my_fds: - os.dup2(my_fds[fd], fd) - # Then close _all_ fds that haven't been explictly - # requested to be kept open. - for fd in get_open_fds(): - if fd not in my_fds: - try: - os.close(fd) - except OSError: - pass - - # Set requested process permissions. - if gid: - os.setgid(gid) - if groups: - os.setgroups(groups) - if uid: - os.setuid(uid) - if umask: - os.umask(umask) - - # And switch to the new process. - os.execve(binary, myargs, env) - -def find_binary(binary): - """ - Given a binary name, find the binary in PATH - - @param binary: Name of the binary to find - @type string - @rtype: None or string - @returns: full path to binary or None if the binary could not be located. - """ - - for path in os.getenv("PATH", "").split(":"): - filename = "%s/%s" % (path, binary) - if os.access(filename, os.X_OK) and os.path.isfile(filename): - return filename - return None diff --git a/pym/portage/gpg.py b/pym/portage/gpg.py index 04ed60046..7dd758506 100644 --- a/pym/portage/gpg.py +++ b/pym/portage/gpg.py @@ -1,4 +1,4 @@ -# portage_gpg.py -- core Portage functionality +# portage.gpg.py -- core Portage functionality # Copyright 2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id$ @@ -8,8 +8,8 @@ import os import copy import types import commands -import portage_exception -import portage_checksum +import portage.exception +import portage.checksum GPG_BINARY = "/usr/bin/gpg" GPG_OPTIONS = " --lock-never --no-random-seed-file --no-greeting --no-sig-cache " @@ -26,7 +26,7 @@ def fileStats(filepath): mya = [] for x in os.stat(filepath): mya.append(x) - mya.append(portage_checksum.perform_checksum(filepath)) + mya.append(portage.checksum.perform_checksum(filepath)) return mya @@ -42,34 +42,34 @@ class FileChecker: if (keydir != None): # Verify that the keydir is valid. if type(keydir) != types.StringType: - raise portage_exception.InvalidDataType, "keydir argument: %s" % keydir + raise portage.exception.InvalidDataType, "keydir argument: %s" % keydir if not os.path.isdir(keydir): - raise portage_exception.DirectoryNotFound, "keydir: %s" % keydir + raise portage.exception.DirectoryNotFound, "keydir: %s" % keydir self.keydir = copy.deepcopy(keydir) if (keyring != None): # Verify that the keyring is a valid filename and exists. if type(keyring) != types.StringType: - raise portage_exception.InvalidDataType, "keyring argument: %s" % keyring + raise portage.exception.InvalidDataType, "keyring argument: %s" % keyring if keyring.find("/") != -1: - raise portage_exception.InvalidData, "keyring: %s" % keyring + raise portage.exception.InvalidData, "keyring: %s" % keyring pathname = "" if keydir: pathname = keydir + "/" + keyring if not os.path.isfile(pathname): - raise portage_exception.FileNotFound, "keyring missing: %s (dev.gentoo.org/~carpaski/gpg/)" % pathname + raise portage.exception.FileNotFound, "keyring missing: %s (dev.gentoo.org/~carpaski/gpg/)" % pathname keyringPath = keydir+"/"+keyring if not keyring or not keyringPath and requireSignedRing: - raise portage_exception.MissingParameter + raise portage.exception.MissingParameter self.keyringStats = fileStats(keyringPath) self.minimumTrust = TRUSTED if not self.verify(keyringPath, keyringPath+".asc"): self.keyringIsTrusted = False if requireSignedRing: - raise portage_exception.InvalidSignature, "Required keyring verification: "+keyringPath + raise portage.exception.InvalidSignature, "Required keyring verification: "+keyringPath else: self.keyringIsTrusted = True @@ -81,27 +81,27 @@ class FileChecker: if self.keyringStats and self.keyringPath: new_stats = fileStats(self.keyringPath) if new_stats != self.keyringStats: - raise portage_exception.SecurityViolation, "GPG keyring changed!" + raise portage.exception.SecurityViolation, "GPG keyring changed!" def verify(self, filename, sigfile=None): """Uses minimumTrust to determine if it is Valid/True or Invalid/False""" self._verifyKeyring() if not os.path.isfile(filename): - raise portage_exception.FileNotFound, filename + raise portage.exception.FileNotFound, filename if sigfile and not os.path.isfile(sigfile): - raise portage_exception.FileNotFound, sigfile + raise portage.exception.FileNotFound, sigfile if self.keydir and not os.path.isdir(self.keydir): - raise portage_exception.DirectoryNotFound, filename + raise portage.exception.DirectoryNotFound, filename if self.keyringPath: if not os.path.isfile(self.keyringPath): - raise portage_exception.FileNotFound, self.keyringPath + raise portage.exception.FileNotFound, self.keyringPath if not os.path.isfile(filename): - raise portage_exception.CommandNotFound, filename + raise portage.exception.CommandNotFound, filename command = GPG_BINARY + GPG_VERIFY_FLAGS + GPG_OPTIONS if self.keydir: @@ -127,22 +127,22 @@ class FileChecker: #if output.find("WARNING") != -1: # trustLevel = MARGINAL if output.find("BAD") != -1: - raise portage_exception.InvalidSignature, filename + raise portage.exception.InvalidSignature, filename elif result == 1: trustLevel = EXISTS if output.find("BAD") != -1: - raise portage_exception.InvalidSignature, filename + raise portage.exception.InvalidSignature, filename elif result == 2: trustLevel = UNTRUSTED if output.find("could not be verified") != -1: - raise portage_exception.MissingSignature, filename + raise portage.exception.MissingSignature, filename if output.find("public key not found") != -1: if self.keyringIsTrusted: # We trust the ring, but not the key specifically. trustLevel = MARGINAL else: - raise portage_exception.InvalidSignature, filename+" (Unknown Signature)" + raise portage.exception.InvalidSignature, filename+" (Unknown Signature)" else: - raise portage_exception.UnknownCondition, "GPG returned unknown result: %d" % (result) + raise portage.exception.UnknownCondition, "GPG returned unknown result: %d" % (result) if trustLevel >= self.minimumTrust: return True diff --git a/pym/portage/localization.py b/pym/portage/localization.py index 59ccea711..2e9f620c8 100644 --- a/pym/portage/localization.py +++ b/pym/portage/localization.py @@ -1,4 +1,4 @@ -# portage_localization.py -- Code to manage/help portage localization. +# portage.localization.py -- Code to manage/help portage localization. # Copyright 2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id$ diff --git a/pym/portage/locks.py b/pym/portage/locks.py index 28042e2fb..3def88a38 100644 --- a/pym/portage/locks.py +++ b/pym/portage/locks.py @@ -5,10 +5,10 @@ import errno, os, stat, time, types -from portage_exception import InvalidData, DirectoryNotFound, FileNotFound -from portage_data import portage_gid -from portage_util import writemsg -from portage_localization import _ +from portage.exception import InvalidData, DirectoryNotFound, FileNotFound +from portage.data import portage_gid +from portage.util import writemsg +from portage.localization import _ HARDLINK_FD = -2 diff --git a/pym/portage/mail.py b/pym/portage/mail.py index 99ed77fda..7c326b039 100644 --- a/pym/portage/mail.py +++ b/pym/portage/mail.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id: portage.py 3483 2006-06-10 21:40:40Z genone $ -import portage_exception, socket, smtplib, os, sys, time +import portage.exception, socket, smtplib, os, sys, time from email.MIMEText import MIMEText as TextMessage from email.MIMEMultipart import MIMEMultipart as MultipartMessage from email.MIMEBase import MIMEBase as BaseMessage @@ -20,7 +20,7 @@ def create_message(sender, recipient, subject, body, attachments=None): elif isinstance(x, str): mymessage.attach(TextMessage(x)) else: - raise portage_exception.PortageException("Can't handle type of attachment: %s" % type(x)) + raise portage.exception.PortageException("Can't handle type of attachment: %s" % type(x)) mymessage.set_unixfrom(sender) mymessage["To"] = recipient @@ -82,8 +82,8 @@ def send_mail(mysettings, message): myconn.sendmail(myfrom, myrecipient, message.as_string()) myconn.quit() except smtplib.SMTPException, e: - raise portage_exception.PortageException("!!! An error occured while trying to send logmail:\n"+str(e)) + raise portage.exception.PortageException("!!! An error occured while trying to send logmail:\n"+str(e)) except socket.error, e: - raise portage_exception.PortageException("!!! A network error occured while trying to send logmail:\n"+str(e)+"\nSure you configured PORTAGE_ELOG_MAILURI correctly?") + raise portage.exception.PortageException("!!! A network error occured while trying to send logmail:\n"+str(e)+"\nSure you configured PORTAGE_ELOG_MAILURI correctly?") return diff --git a/pym/portage/manifest.py b/pym/portage/manifest.py index e621606c1..92b5b8e85 100644 --- a/pym/portage/manifest.py +++ b/pym/portage/manifest.py @@ -6,10 +6,10 @@ import errno, os, sets if not hasattr(__builtins__, "set"): from sets import Set as set -import portage_exception, portage_versions, portage_const -from portage_checksum import * -from portage_exception import * -from portage_util import write_atomic +import portage.exception, portage.versions, portage.const +from portage.checksum import * +from portage.exception import * +from portage.util import write_atomic class FileNotInManifestException(PortageException): pass @@ -43,7 +43,7 @@ def guessManifestFileType(filename): def parseManifest2(mysplit): myentry = None - if len(mysplit) > 4 and mysplit[0] in portage_const.MANIFEST2_IDENTIFIERS: + if len(mysplit) > 4 and mysplit[0] in portage.const.MANIFEST2_IDENTIFIERS: mytype = mysplit[0] myname = mysplit[1] mysize = int(mysplit[2]) @@ -54,7 +54,7 @@ def parseManifest2(mysplit): def parseManifest1(mysplit): myentry = None - if len(mysplit) == 4 and mysplit[0] in ["size"] + portage_const.MANIFEST1_HASH_FUNCTIONS: + if len(mysplit) == 4 and mysplit[0] in ["size"] + portage.const.MANIFEST1_HASH_FUNCTIONS: myname = mysplit[2] mytype = None mytype = guessManifestFileType(myname) @@ -110,12 +110,12 @@ class Manifest(object): a Manifest (not needed for parsing and checking sums).""" self.pkgdir = pkgdir.rstrip(os.sep) + os.sep self.fhashdict = {} - self.hashes = portage_const.MANIFEST2_HASH_FUNCTIONS[:] + self.hashes = portage.const.MANIFEST2_HASH_FUNCTIONS[:] self.hashes.append("size") if manifest1_compat: - self.hashes.extend(portage_const.MANIFEST1_HASH_FUNCTIONS) + self.hashes.extend(portage.const.MANIFEST1_HASH_FUNCTIONS) self.hashes = sets.Set(self.hashes) - for t in portage_const.MANIFEST2_IDENTIFIERS: + for t in portage.const.MANIFEST2_IDENTIFIERS: self.fhashdict[t] = {} if not from_scratch: self._read() @@ -134,7 +134,7 @@ class Manifest(object): def getDigests(self): """ Compability function for old digest/manifest code, returns dict of filename:{hashfunction:hashvalue} """ rval = {} - for t in portage_const.MANIFEST2_IDENTIFIERS: + for t in portage.const.MANIFEST2_IDENTIFIERS: rval.update(self.fhashdict[t]) return rval @@ -245,7 +245,7 @@ class Manifest(object): for hashname in \ new_data["DIST"][myfile].keys(): if hashname != "size" and hashname not in \ - portage_const.MANIFEST1_HASH_FUNCTIONS: + portage.const.MANIFEST1_HASH_FUNCTIONS: del new_data["DIST"][myfile][hashname] if new_data["DIST"] == old_data["DIST"]: update_digest = False @@ -285,7 +285,7 @@ class Manifest(object): myhashkeys = myhashdict["DIST"][f].keys() myhashkeys.sort() for h in myhashkeys: - if h not in portage_const.MANIFEST1_HASH_FUNCTIONS: + if h not in portage.const.MANIFEST1_HASH_FUNCTIONS: continue myline = " ".join([h, str(myhashdict["DIST"][f][h]), f, str(myhashdict["DIST"][f]["size"])]) mylines.append(myline) @@ -295,7 +295,7 @@ class Manifest(object): """ Add entries for old style digest files to Manifest file """ mylines = [] for dname in digests: - myhashes = perform_multiple_checksums(dname, portage_const.MANIFEST1_HASH_FUNCTIONS+["size"]) + myhashes = perform_multiple_checksums(dname, portage.const.MANIFEST1_HASH_FUNCTIONS+["size"]) for h in myhashes: mylines.append((" ".join([h, str(myhashes[h]), os.path.join("files", os.path.basename(dname)), str(myhashes["size"])]))) fd.write("\n".join(mylines)) @@ -312,14 +312,14 @@ class Manifest(object): type=t, name=f, hashes=self.fhashdict[t][f].copy()) myhashkeys = myentry.hashes.keys() for h in myhashkeys: - if h not in ["size"] + portage_const.MANIFEST2_HASH_FUNCTIONS: + if h not in ["size"] + portage.const.MANIFEST2_HASH_FUNCTIONS: del myentry.hashes[h] yield myentry if self.compat and t != "DIST": mysize = self.fhashdict[t][f]["size"] myhashes = self.fhashdict[t][f] for h in myhashkeys: - if h not in portage_const.MANIFEST1_HASH_FUNCTIONS: + if h not in portage.const.MANIFEST1_HASH_FUNCTIONS: continue yield Manifest1Entry( type=t, name=f, hashes={"size":mysize, h:myhashes[h]}) @@ -331,11 +331,11 @@ class Manifest(object): digest_path = os.path.join("files", "digest-%s" % self._catsplit(cpv)[1]) dname = os.path.join(self.pkgdir, digest_path) try: - myhashes = perform_multiple_checksums(dname, portage_const.MANIFEST1_HASH_FUNCTIONS+["size"]) + myhashes = perform_multiple_checksums(dname, portage.const.MANIFEST1_HASH_FUNCTIONS+["size"]) myhashkeys = myhashes.keys() myhashkeys.sort() for h in myhashkeys: - if h in portage_const.MANIFEST1_HASH_FUNCTIONS: + if h in portage.const.MANIFEST1_HASH_FUNCTIONS: yield Manifest1Entry(type="AUX", name=digest_path, hashes={"size":myhashes["size"], h:myhashes[h]}) except FileNotFound: @@ -390,14 +390,14 @@ class Manifest(object): fname = os.path.join("files", fname) if not os.path.exists(self.pkgdir+fname) and not ignoreMissing: raise FileNotFound(fname) - if not ftype in portage_const.MANIFEST2_IDENTIFIERS: + if not ftype in portage.const.MANIFEST2_IDENTIFIERS: raise InvalidDataType(ftype) if ftype == "AUX" and fname.startswith("files"): fname = fname[6:] self.fhashdict[ftype][fname] = {} if hashdict != None: self.fhashdict[ftype][fname].update(hashdict) - if not portage_const.MANIFEST2_REQUIRED_HASH in self.fhashdict[ftype][fname]: + if not portage.const.MANIFEST2_REQUIRED_HASH in self.fhashdict[ftype][fname]: self.updateFileHashes(ftype, fname, checkExisting=False, ignoreMissing=ignoreMissing) def removeFile(self, ftype, fname): @@ -410,7 +410,7 @@ class Manifest(object): def findFile(self, fname): """ Return entrytype of the given file if present in Manifest or None if not present """ - for t in portage_const.MANIFEST2_IDENTIFIERS: + for t in portage.const.MANIFEST2_IDENTIFIERS: if fname in self.fhashdict[t]: return t return None @@ -500,7 +500,7 @@ class Manifest(object): return absname def checkAllHashes(self, ignoreMissingFiles=False): - for t in portage_const.MANIFEST2_IDENTIFIERS: + for t in portage.const.MANIFEST2_IDENTIFIERS: self.checkTypeHashes(t, ignoreMissingFiles=ignoreMissingFiles) def checkTypeHashes(self, idtype, ignoreMissingFiles=False): @@ -564,7 +564,7 @@ class Manifest(object): def updateAllHashes(self, checkExisting=False, ignoreMissingFiles=True): """ Regenerate all hashes for all files in this Manifest. """ - for ftype in portage_const.MANIFEST2_IDENTIFIERS: + for ftype in portage.const.MANIFEST2_IDENTIFIERS: self.updateTypeHashes(idtype, fname, checkExisting) def updateCpvHashes(self, cpv, ignoreMissingFiles=True): @@ -606,9 +606,9 @@ class Manifest(object): myfile.close() for l in lines: mysplit = l.split() - if len(mysplit) == 4 and mysplit[0] in portage_const.MANIFEST1_HASH_FUNCTIONS and not 1 in rVal: + if len(mysplit) == 4 and mysplit[0] in portage.const.MANIFEST1_HASH_FUNCTIONS and not 1 in rVal: rVal.append(1) - elif len(mysplit) > 4 and mysplit[0] in portage_const.MANIFEST2_IDENTIFIERS and ((len(mysplit) - 3) % 2) == 0 and not 2 in rVal: + elif len(mysplit) > 4 and mysplit[0] in portage.const.MANIFEST2_IDENTIFIERS and ((len(mysplit) - 3) % 2) == 0 and not 2 in rVal: rVal.append(2) return rVal diff --git a/pym/portage/news.py b/pym/portage/news.py index b54261d92..0f8c16da6 100644 --- a/pym/portage/news.py +++ b/pym/portage/news.py @@ -3,12 +3,12 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from portage_const import INCREMENTALS, PROFILE_PATH, NEWS_LIB_PATH +from portage.const import INCREMENTALS, PROFILE_PATH, NEWS_LIB_PATH from portage import config, vartree, vardbapi, portdbapi -from portage_util import ensure_dirs, apply_permissions -from portage_data import portage_gid -from portage_locks import lockfile, unlockfile, lockdir, unlockdir -from portage_exception import FileNotFound +from portage.util import ensure_dirs, apply_permissions +from portage.data import portage_gid +from portage.locks import lockfile, unlockfile, lockdir, unlockdir +from portage.exception import FileNotFound import os, re class NewsManager(object): diff --git a/pym/portage/output.py b/pym/portage/output.py index 62ec975fe..600b8183b 100644 --- a/pym/portage/output.py +++ b/pym/portage/output.py @@ -5,9 +5,9 @@ __docformat__ = "epytext" import commands,errno,os,re,shlex,sys -from portage_const import COLOR_MAP_FILE -from portage_util import writemsg -from portage_exception import PortageException, ParseError, PermissionDenied, FileNotFound +from portage.const import COLOR_MAP_FILE +from portage.util import writemsg +from portage.exception import PortageException, ParseError, PermissionDenied, FileNotFound havecolor=1 dotitles=1 diff --git a/pym/portage/process.py b/pym/portage/process.py new file mode 100644 index 000000000..20b1d705c --- /dev/null +++ b/pym/portage/process.py @@ -0,0 +1,336 @@ +# portage.py -- core Portage functionality +# Copyright 1998-2004 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + + +import os, atexit, signal, sys +import portage.data + +from portage.util import dump_traceback +from portage.const import BASH_BINARY, SANDBOX_BINARY + + +try: + import resource + max_fd_limit = resource.getrlimit(resource.RLIMIT_NOFILE)[0] +except ImportError: + max_fd_limit = 256 + +if os.path.isdir("/proc/%i/fd" % os.getpid()): + def get_open_fds(): + return map(int, [fd for fd in os.listdir("/proc/%i/fd" % os.getpid()) if fd.isdigit()]) +else: + def get_open_fds(): + return xrange(max_fd_limit) + +sandbox_capable = (os.path.isfile(SANDBOX_BINARY) and + os.access(SANDBOX_BINARY, os.X_OK)) + +def spawn_bash(mycommand, debug=False, opt_name=None, **keywords): + """ + Spawns a bash shell running a specific commands + + @param mycommand: The command for bash to run + @type mycommand: String + @param debug: Turn bash debugging on (set -x) + @type debug: Boolean + @param opt_name: Name of the spawned process (detaults to binary name) + @type opt_name: String + @param keywords: Extra Dictionary arguments to pass to spawn + @type keywords: Dictionary + """ + + args = [BASH_BINARY] + if not opt_name: + opt_name = os.path.basename(mycommand.split()[0]) + if debug: + # Print commands and their arguments as they are executed. + args.append("-x") + args.append("-c") + args.append(mycommand) + return spawn(args, 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) + args=[SANDBOX_BINARY] + if not opt_name: + opt_name = os.path.basename(mycommand.split()[0]) + args.append(mycommand) + return spawn(args, opt_name=opt_name, **keywords) + +_exithandlers = [] +def atexit_register(func, *args, **kargs): + """Wrapper around atexit.register that is needed in order to track + what is registered. For example, when portage restarts itself via + os.execv, the atexit module does not work so we have to do it + manually by calling the run_exitfuncs() function in this module.""" + _exithandlers.append((func, args, kargs)) + +def run_exitfuncs(): + """This should behave identically to the routine performed by + the atexit module at exit time. It's only necessary to call this + function when atexit will not work (because of os.execv, for + example).""" + + # This function is a copy of the private atexit._run_exitfuncs() + # from the python 2.4.2 sources. The only difference from the + # original function is in the output to stderr. + exc_info = None + while _exithandlers: + func, targs, kargs = _exithandlers.pop() + try: + func(*targs, **kargs) + except SystemExit: + exc_info = sys.exc_info() + except: # No idea what they called, so we need this broad except here. + dump_traceback("Error in portage.process.run_exitfuncs", noiselevel=0) + exc_info = sys.exc_info() + + if exc_info is not None: + raise exc_info[0], exc_info[1], exc_info[2] + +atexit.register(run_exitfuncs) + +# We need to make sure that any processes spawned are killed off when +# we exit. spawn() takes care of adding and removing pids to this list +# as it creates and cleans up processes. +spawned_pids = [] +def cleanup(): + while spawned_pids: + pid = spawned_pids.pop() + try: + if os.waitpid(pid, os.WNOHANG) == (0, 0): + os.kill(pid, signal.SIGTERM) + os.waitpid(pid, 0) + except OSError: + # This pid has been cleaned up outside + # of spawn(). + pass + +atexit_register(cleanup) + +def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False, + uid=None, gid=None, groups=None, umask=None, logfile=None, + path_lookup=True): + """ + Spawns a given command. + + @param mycommand: the command to execute + @type mycommand: String or List (Popen style list) + @param env: A dict of Key=Value pairs for env variables + @type env: Dictionary + @param opt_name: an optional name for the spawn'd process (defaults to the binary name) + @type opt_name: String + @param fd_pipes: A dict of mapping for pipes, { '0': stdin, '1': stdout } for example + @type fd_pipes: Dictionary + @param returnpid: Return the Process IDs for a successful spawn. + NOTE: This requires the caller clean up all the PIDs, otherwise spawn will clean them. + @type returnpid: Boolean + @param uid: User ID to spawn as; useful for dropping privilages + @type uid: Integer + @param gid: Group ID to spawn as; useful for dropping privilages + @type gid: Integer + @param groups: Group ID's to spawn in: useful for having the process run in multiple group contexts. + @type groups: List + @param umask: An integer representing the umask for the process (see man chmod for umask details) + @type umask: Integer + @param logfile: name of a file to use for logging purposes + @type logfile: String + @param path_lookup: If the binary is not fully specified then look for it in PATH + @type path_lookup: Boolean + + logfile requires stdout and stderr to be assigned to this process (ie not pointed + somewhere else.) + + """ + + # mycommand is either a str or a list + if isinstance(mycommand, str): + mycommand = mycommand.split() + + # If an absolute path to an executable file isn't given + # search for it unless we've been told not to. + binary = mycommand[0] + if (not os.path.isabs(binary) or not os.path.isfile(binary) + or not os.access(binary, os.X_OK)): + binary = path_lookup and find_binary(binary) or None + if not binary: + return -1 + + # If we haven't been told what file descriptors to use + # default to propogating our stdin, stdout and stderr. + if fd_pipes is None: + fd_pipes = {0:0, 1:1, 2:2} + + # mypids will hold the pids of all processes created. + mypids = [] + + if logfile: + # Using a log file requires that stdout and stderr + # are assigned to the process we're running. + if 1 not in fd_pipes or 2 not in fd_pipes: + raise ValueError(fd_pipes) + + # Create a pipe + (pr, pw) = os.pipe() + + # Create a tee process, giving it our stdout and stderr + # as well as the read end of the pipe. + mypids.extend(spawn(('tee', '-i', '-a', logfile), + returnpid=True, fd_pipes={0:pr, + 1:fd_pipes[1], 2:fd_pipes[2]})) + + # We don't need the read end of the pipe, so close it. + os.close(pr) + + # Assign the write end of the pipe to our stdout and stderr. + fd_pipes[1] = pw + fd_pipes[2] = pw + + pid = os.fork() + + if not pid: + try: + _exec(binary, mycommand, opt_name, fd_pipes, + env, gid, groups, uid, umask) + except Exception, e: + # We need to catch _any_ exception so that it doesn't + # propogate out of this function and cause exiting + # with anything other than os._exit() + sys.stderr.write("%s:\n %s\n" % (e, " ".join(mycommand))) + sys.stderr.flush() + os._exit(1) + + # Add the pid to our local and the global pid lists. + mypids.append(pid) + spawned_pids.append(pid) + + # If we started a tee process the write side of the pipe is no + # longer needed, so close it. + if logfile: + os.close(pw) + + # If the caller wants to handle cleaning up the processes, we tell + # it about all processes that were created. + if returnpid: + return mypids + + # Otherwise we clean them up. + while mypids: + + # Pull the last reader in the pipe chain. If all processes + # in the pipe are well behaved, it will die when the process + # it is reading from dies. + pid = mypids.pop(0) + + # and wait for it. + retval = os.waitpid(pid, 0)[1] + + # When it's done, we can remove it from the + # global pid list as well. + spawned_pids.remove(pid) + + if retval: + # If it failed, kill off anything else that + # isn't dead yet. + for pid in mypids: + if os.waitpid(pid, os.WNOHANG) == (0,0): + os.kill(pid, signal.SIGTERM) + os.waitpid(pid, 0) + spawned_pids.remove(pid) + + # If it got a signal, return the signal that was sent. + if (retval & 0xff): + return ((retval & 0xff) << 8) + + # Otherwise, return its exit code. + return (retval >> 8) + + # Everything succeeded + return 0 + +def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask): + + """ + Execute a given binary with options + + @param binary: Name of program to execute + @type binary: String + @param mycommand: Options for program + @type mycommand: String + @param opt_name: Name of process (defaults to binary) + @type opt_name: String + @param fd_pipes: Mapping pipes to destination; { 0:0, 1:1, 2:2 } + @type fd_pipes: Dictionary + @param env: Key,Value mapping for Environmental Variables + @type env: Dictionary + @param gid: Group ID to run the process under + @type gid: Integer + @param groups: Groups the Process should be in. + @type groups: Integer + @param uid: User ID to run the process under + @type uid: Integer + @param umask: an int representing a unix umask (see man chmod for umask details) + @type umask: Integer + @rtype: None + @returns: Never returns (calls os.execve) + """ + + # If the process we're creating hasn't been given a name + # assign it the name of the executable. + if not opt_name: + opt_name = os.path.basename(binary) + + # Set up the command's argument list. + myargs = [opt_name] + myargs.extend(mycommand[1:]) + + # Set up the command's pipes. + my_fds = {} + # To protect from cases where direct assignment could + # clobber needed fds ({1:2, 2:1}) we first dupe the fds + # into unused fds. + for fd in fd_pipes: + my_fds[fd] = os.dup(fd_pipes[fd]) + # Then assign them to what they should be. + for fd in my_fds: + os.dup2(my_fds[fd], fd) + # Then close _all_ fds that haven't been explictly + # requested to be kept open. + for fd in get_open_fds(): + if fd not in my_fds: + try: + os.close(fd) + except OSError: + pass + + # Set requested process permissions. + if gid: + os.setgid(gid) + if groups: + os.setgroups(groups) + if uid: + os.setuid(uid) + if umask: + os.umask(umask) + + # And switch to the new process. + os.execve(binary, myargs, env) + +def find_binary(binary): + """ + Given a binary name, find the binary in PATH + + @param binary: Name of the binary to find + @type string + @rtype: None or string + @returns: full path to binary or None if the binary could not be located. + """ + + for path in os.getenv("PATH", "").split(":"): + filename = "%s/%s" % (path, binary) + if os.access(filename, os.X_OK) and os.path.isfile(filename): + return filename + return None diff --git a/pym/portage/update.py b/pym/portage/update.py index 1a2a1d884..472eebe96 100644 --- a/pym/portage/update.py +++ b/pym/portage/update.py @@ -4,12 +4,12 @@ import errno, os, re, sys -from portage_util import ConfigProtect, grabfile, new_protect_filename, \ +from portage.util import ConfigProtect, grabfile, new_protect_filename, \ normalize_path, write_atomic, writemsg -from portage_exception import DirectoryNotFound, PortageException -from portage_versions import ververify -from portage_dep import dep_getkey, get_operator, isvalidatom, isjustname -from portage_const import USER_CONFIG_PATH, WORLD_FILE +from portage.exception import DirectoryNotFound, PortageException +from portage.versions import ververify +from portage.dep import dep_getkey, get_operator, isvalidatom, isjustname +from portage.const import USER_CONFIG_PATH, WORLD_FILE ignored_dbentries = ("CONTENTS", "environment.bz2") diff --git a/pym/portage/util.py b/pym/portage/util.py index cc5a566b8..aad939529 100644 --- a/pym/portage/util.py +++ b/pym/portage/util.py @@ -2,10 +2,10 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from portage_exception import PortageException, FileNotFound, \ +from portage.exception import PortageException, FileNotFound, \ OperationNotPermitted, PermissionDenied, ReadOnlyFileSystem -import portage_exception -from portage_dep import isvalidatom +import portage.exception +from portage.dep import isvalidatom import os, errno, shlex, stat, string, sys try: @@ -88,7 +88,7 @@ def stack_dictlist(original_dicts, incremental=0, incrementals=[], ignore_none=0 Returns a single dict. Higher index in lists is preferenced. Example usage: - >>> from portage_util import stack_dictlist + >>> from portage.util import stack_dictlist >>> print stack_dictlist( [{'a':'b'},{'x':'y'}]) >>> {'a':'b','x':'y'} >>> print stack_dictlist( [{'a':'b'},{'a':'c'}], incremental = True ) @@ -336,7 +336,7 @@ def getconfig(mycfg, tolerant=0, allow_sourcing=False, expand=True): if not tolerant: writemsg("!!! Unexpected end of config file: variable "+str(key)+"\n", noiselevel=-1) - raise portage_exception.CorruptionError("ParseError: Unexpected EOF: "+str(mycfg)+": line "+str(lex.lineno)) + raise portage.exception.CorruptionError("ParseError: Unexpected EOF: "+str(mycfg)+": line "+str(lex.lineno)) else: return mykeys if expand: @@ -346,7 +346,7 @@ def getconfig(mycfg, tolerant=0, allow_sourcing=False, expand=True): except SystemExit, e: raise except Exception, e: - raise portage_exception.ParseError(str(e)+" in "+mycfg) + raise portage.exception.ParseError(str(e)+" in "+mycfg) return mykeys #cache expansions of constant strings @@ -579,8 +579,8 @@ def apply_permissions(filename, uid=-1, gid=-1, mode=-1, mask=-1, if follow_links: os.chown(filename, uid, gid) else: - import portage_data - portage_data.lchown(filename, uid, gid) + import portage.data + portage.data.lchown(filename, uid, gid) modified = True except OSError, oe: func_call = "chown('%s', %i, %i)" % (filename, uid, gid) @@ -725,8 +725,8 @@ def apply_secpass_permissions(filename, uid=-1, gid=-1, mode=-1, mask=-1, all_applied = True - import portage_data # not imported globally because of circular dep - if portage_data.secpass < 2: + import portage.data # not imported globally because of circular dep + if portage.data.secpass < 2: if uid != -1 and \ uid != stat_cached.st_uid: @@ -1030,8 +1030,8 @@ def new_protect_filename(mydest, newmd5=None): "._cfg" + str(prot_num).zfill(4) + "_" + real_filename)) old_pfile = normalize_path(os.path.join(real_dirname, last_pfile)) if last_pfile and newmd5: - import portage_checksum - if portage_checksum.perform_md5( + import portage.checksum + if portage.checksum.perform_md5( os.path.join(real_dirname, last_pfile)) == newmd5: return old_pfile return new_pfile diff --git a/pym/portage/versions.py b/pym/portage/versions.py index 63d69bac4..90bfea936 100644 --- a/pym/portage/versions.py +++ b/pym/portage/versions.py @@ -1,4 +1,4 @@ -# portage_versions.py -- core Portage functionality +# portage.versions.py -- core Portage functionality # Copyright 1998-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id$ @@ -10,7 +10,7 @@ suffix_regexp = re.compile("^(alpha|beta|rc|pre|p)(\\d*)$") suffix_value = {"pre": -2, "p": 0, "alpha": -4, "beta": -3, "rc": -1} endversion_keys = ["pre", "p", "alpha", "beta", "rc"] -from portage_exception import InvalidData +from portage.exception import InvalidData def ververify(myver, silent=1): if ver_regexp.match(myver): @@ -25,7 +25,7 @@ def vercmp(ver1, ver2, silent=1): """ Compare two versions Example usage: - >>> from portage_versions import vercmp + >>> from portage.versions import vercmp >>> vercmp('1.0-r1','1.2-r3') negative number >>> vercmp('1.3','1.2-r3') @@ -33,16 +33,16 @@ def vercmp(ver1, ver2, silent=1): >>> vercmp('1.0_p3','1.0_p3') 0 - @param pkg1: version to compare with (see ver_regexp in portage_versions.py) + @param pkg1: version to compare with (see ver_regexp in portage.versions.py) @type pkg1: string (example: "2.1.2-r3") - @param pkg2: version to compare againts (see ver_regexp in portage_versions.py) + @param pkg2: version to compare againts (see ver_regexp in portage.versions.py) @type pkg2: string (example: "2.1.2_rc5") @rtype: None or float @return: 1. positive if ver1 is greater than ver2 2. negative if ver1 is less than ver2 3. 0 if ver1 equals ver2 - 4. None if ver1 or ver2 are invalid (see ver_regexp in portage_versions.py) + 4. None if ver1 or ver2 are invalid (see ver_regexp in portage.versions.py) """ if ver1 == ver2: @@ -159,7 +159,7 @@ def pkgcmp(pkg1, pkg2): Compare 2 package versions created in pkgsplit format. Example usage: - >>> from portage_versions import * + >>> from portage.versions import * >>> pkgcmp(pkgsplit('test-1.0-r1'),pkgsplit('test-1.2-r3')) -1 >>> pkgcmp(pkgsplit('test-1.3'),pkgsplit('test-1.2-r3')) @@ -270,7 +270,7 @@ def catpkgsplit(mydata,silent=1): # Categories may contain a-zA-z0-9+_- but cannot start with - global _valid_category - import portage_dep + import portage.dep try: if not catcache[mydata]: return None @@ -283,7 +283,7 @@ def catpkgsplit(mydata,silent=1): retval=["null"] p_split=pkgsplit(mydata,silent=silent) elif len(mysplit)==2: - if portage_dep._dep_check_strict and \ + if portage.dep._dep_check_strict and \ not _valid_category.match(mysplit[0]): raise InvalidData("Invalid category in %s" %mydata ) retval=[mysplit[0]] -- cgit v1.2.3-1-g7c22