def emerge_main(args=None, build_dict=None):
"""
@param args: command arguments (default: sys.argv[1:])
@type args: list
@param build_dict: info of the build_job
@type build_dict: dict
"""
if args is None:
args = sys.argv[1:]
if build_dict is None:
build_dict = {}
# Disable color until we're sure that it should be enabled (after
# EMERGE_DEFAULT_OPTS has been parsed).
portage.output.havecolor = 0
# This first pass is just for options that need to be known as early as
# possible, such as --config-root. They will be parsed again later,
# together with EMERGE_DEFAULT_OPTS (which may vary depending on the
# the value of --config-root).
myaction, myopts, myfiles = parse_opts(args, silent=True)
if "--debug" in myopts:
os.environ["PORTAGE_DEBUG"] = "1"
if "--config-root" in myopts:
os.environ["PORTAGE_CONFIGROOT"] = myopts["--config-root"]
if "--root" in myopts:
os.environ["ROOT"] = myopts["--root"]
if "--accept-properties" in myopts:
os.environ["ACCEPT_PROPERTIES"] = myopts["--accept-properties"]
# optimize --help (no need to load config / EMERGE_DEFAULT_OPTS)
if myaction == "help":
emerge_help()
return os.EX_OK
elif myaction == "moo":
print(COWSAY_MOO % platform.system())
return os.EX_OK
# Portage needs to ensure a sane umask for the files it creates.
os.umask(0o22)
if myaction == "sync":
portage._sync_disabled_warnings = True
settings, trees, mtimedb = load_emerge_config()
rval = profile_check(trees, myaction)
if rval != os.EX_OK:
return rval
tmpcmdline = []
if "--ignore-default-opts" not in myopts:
tmpcmdline.extend(settings["EMERGE_DEFAULT_OPTS"].split())
tmpcmdline.extend(args)
myaction, myopts, myfiles = parse_opts(tmpcmdline)
return run_action(settings, trees, mtimedb, myaction, myopts, myfiles, build_dict,
gc_locals=locals().clear)
开发者ID:zorry,项目名称:zobsc,代码行数:56,代码来源:main.py
示例3: __init__
def __init__(self, settings, logger):
self.settings = settings
self.logger = logger
# Similar to emerge, sync needs a default umask so that created
# files have sane permissions.
os.umask(0o22)
self.module_controller = portage.sync.module_controller
self.module_names = self.module_controller.module_names
self.hooks = {}
for _dir in ["repo.postsync.d", "postsync.d"]:
postsync_dir = os.path.join(self.settings["PORTAGE_CONFIGROOT"],
portage.USER_CONFIG_PATH, _dir)
hooks = OrderedDict()
for filepath in util._recursive_file_list(postsync_dir):
name = filepath.split(postsync_dir)[1].lstrip(os.sep)
if os.access(filepath, os.X_OK):
hooks[filepath] = name
else:
writemsg_level(" %s %s hook: '%s' is not executable\n"
% (warn("*"), _dir, _unicode_decode(name),),
level=logging.WARN, noiselevel=2)
self.hooks[_dir] = hooks
def emaint_main(myargv):
# Similar to emerge, emaint needs a default umask so that created
# files (such as the world file) have sane permissions.
os.umask(0o22)
module_path = os.path.join(
(os.path.dirname(
os.path.realpath(__file__))), "modules"
)
module_controller = Modules(
path=module_path,
namepath="portage.emaint.modules")
module_names = module_controller.module_names[:]
module_names.insert(0, "all")
parser = ArgumentParser(usage=usage(module_controller))
# add default options
parser_options = []
for opt in DEFAULT_OPTIONS:
parser_options.append(OptionItem(DEFAULT_OPTIONS[opt]))
for mod in module_names[1:]:
desc = module_controller.get_func_descriptions(mod)
if desc:
for opt in desc:
parser_options.append(OptionItem(desc[opt]))
desc = module_controller.get_opt_descriptions(mod)
if desc:
for opt in desc:
parser_options.append(OptionItem(desc[opt]))
for opt in parser_options:
parser.add_argument(*opt.pargs, **opt.kwargs)
options, args = parser.parse_known_args(args=myargv)
if options.version:
print(portage.VERSION)
return os.EX_OK
if len(args) != 1:
parser.error("Incorrect number of arguments")
if args[0] not in module_names:
parser.error("%s target is not a known target" % args[0])
check_opt = None
func = status = long_action = None
for opt in parser_options:
if opt.long == '--check':
# Default action
check_opt = opt
if opt.status and getattr(options, opt.target, False):
if long_action is not None:
parser.error("--%s and %s are exclusive options" %
(long_action, opt.long))
status = opt.status
func = opt.func
long_action = opt.long.lstrip('-')
if long_action is None:
#print("DEBUG: long_action is None: setting to 'check'")
long_action = 'check'
func = check_opt.func
status = check_opt.status
if args[0] == "all":
tasks = []
for m in module_names[1:]:
#print("DEBUG: module: %s, functions: " % (m, str(module_controller.get_functions(m))))
if long_action in module_controller.get_functions(m):
tasks.append(module_controller.get_class(m))
elif long_action in module_controller.get_functions(args[0]):
tasks = [module_controller.get_class(args[0] )]
else:
portage.util.writemsg(
"\nERROR: module '%s' does not have option '--%s'\n\n" %
(args[0], long_action), noiselevel=-1)
portage.util.writemsg(module_opts(module_controller, args[0]),
noiselevel=-1)
sys.exit(1)
# need to pass the parser options dict to the modules
# so they are available if needed.
task_opts = options.__dict__
task_opts['return-messages'] = True
taskmaster = TaskHandler(callback=print_results, module_output=sys.stdout)
taskmaster.run_tasks(tasks, func, status, options=task_opts)
开发者ID:Whissi,项目名称:portage,代码行数:87,代码来源:main.py
示例5: _exec
def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask,
pre_exec):
"""
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
@param pre_exec: A function to be called with no arguments just prior to the exec call.
@type pre_exec: callable
@rtype: None
@return: 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:
if binary is portage._python_interpreter:
# NOTE: PyPy 1.7 will die due to "libary path not found" if argv[0]
# does not contain the full path of the binary.
opt_name = binary
else:
opt_name = os.path.basename(binary)
# Set up the command's argument list.
myargs = [opt_name]
myargs.extend(mycommand[1:])
# Use default signal handlers in order to avoid problems
# killing subprocesses as reported in bug #353239.
signal.signal(signal.SIGINT, signal.SIG_DFL)
signal.signal(signal.SIGTERM, signal.SIG_DFL)
# Quiet killing of subprocesses by SIGPIPE (see bug #309001).
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
# Avoid issues triggered by inheritance of SIGQUIT handler from
# the parent process (see bug #289486).
signal.signal(signal.SIGQUIT, signal.SIG_DFL)
_setup_pipes(fd_pipes)
# Set requested process permissions.
if gid:
os.setgid(gid)
if groups:
os.setgroups(groups)
if uid:
os.setuid(uid)
if umask:
os.umask(umask)
if pre_exec:
pre_exec()
# And switch to the new process.
os.execve(binary, myargs, env)
def pre_sync(self, repo):
msg = ">>> Syncing repository '%s' into '%s'..." % (repo.name, repo.location)
self.logger(self.xterm_titles, msg)
writemsg_level(msg + "\n")
try:
st = os.stat(repo.location)
except OSError:
st = None
self.usersync_uid = None
spawn_kwargs = {}
# Redirect command stderr to stdout, in order to prevent
# spurious cron job emails (bug 566132).
spawn_kwargs["fd_pipes"] = {0: sys.__stdin__.fileno(), 1: sys.__stdout__.fileno(), 2: sys.__stdout__.fileno()}
spawn_kwargs["env"] = self.settings.environ()
if repo.sync_user is not None:
def get_sync_user_data(sync_user):
user = None
group = None
home = None
logname = None
spl = sync_user.split(":", 1)
if spl[0]:
username = spl[0]
try:
try:
pw = pwd.getpwnam(username)
except KeyError:
pw = pwd.getpwuid(int(username))
except (ValueError, KeyError):
writemsg("!!! User '%s' invalid or does not exist\n" % username, noiselevel=-1)
return (logname, user, group, home)
user = pw.pw_uid
group = pw.pw_gid
home = pw.pw_dir
logname = pw.pw_name
if len(spl) > 1:
groupname = spl[1]
try:
try:
gp = grp.getgrnam(groupname)
except KeyError:
pw = grp.getgrgid(int(groupname))
except (ValueError, KeyError):
writemsg("!!! Group '%s' invalid or does not exist\n" % groupname, noiselevel=-1)
return (logname, user, group, home)
group = gp.gr_gid
return (logname, user, group, home)
# user or user:group
(logname, uid, gid, home) = get_sync_user_data(repo.sync_user)
if uid is not None:
spawn_kwargs["uid"] = uid
self.usersync_uid = uid
if gid is not None:
spawn_kwargs["gid"] = gid
spawn_kwargs["groups"] = [gid]
if home is not None:
spawn_kwargs["env"]["HOME"] = home
if logname is not None:
spawn_kwargs["env"]["LOGNAME"] = logname
if st is None:
perms = {"mode": 0o755}
# respect sync-user if set
if "umask" in spawn_kwargs:
perms["mode"] &= ~spawn_kwargs["umask"]
if "uid" in spawn_kwargs:
perms["uid"] = spawn_kwargs["uid"]
if "gid" in spawn_kwargs:
perms["gid"] = spawn_kwargs["gid"]
portage.util.ensure_dirs(repo.location, **perms)
st = os.stat(repo.location)
if (
repo.sync_user is None
and "usersync" in self.settings.features
and portage.data.secpass >= 2
and (st.st_uid != os.getuid() and st.st_mode & 0o700 or st.st_gid != os.getgid() and st.st_mode & 0o070)
):
try:
pw = pwd.getpwuid(st.st_uid)
except KeyError:
pass
else:
# Drop privileges when syncing, in order to match
# existing uid/gid settings.
self.usersync_uid = st.st_uid
spawn_kwargs["uid"] = st.st_uid
spawn_kwargs["gid"] = st.st_gid
spawn_kwargs["groups"] = [st.st_gid]
spawn_kwargs["env"]["HOME"] = pw.pw_dir
spawn_kwargs["env"]["LOGNAME"] = pw.pw_name
#.........这里部分代码省略.........
def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask,
pre_exec):
"""
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
@param pre_exec: A function to be called with no arguments just prior to the exec call.
@type pre_exec: callable
@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)
if pre_exec:
pre_exec()
# And switch to the new process.
os.execve(binary, myargs, env)
def lockfile(mypath, wantnewlockfile=0, unlinkfile=0,
waiting_msg=None, flags=0):
"""
If wantnewlockfile is True then this creates a lockfile in the parent
directory as the file: '.' + basename + '.portage_lockfile'.
"""
if not mypath:
raise InvalidData(_("Empty path given"))
# Since Python 3.4, chown requires int type (no proxies).
portage_gid = int(portage.data.portage_gid)
# Support for file object or integer file descriptor parameters is
# deprecated due to ambiguity in whether or not it's safe to close
# the file descriptor, making it prone to "Bad file descriptor" errors
# or file descriptor leaks.
if isinstance(mypath, basestring) and mypath[-1] == '/':
mypath = mypath[:-1]
lockfilename_path = mypath
if hasattr(mypath, 'fileno'):
warnings.warn("portage.locks.lockfile() support for "
"file object parameters is deprecated. Use a file path instead.",
DeprecationWarning, stacklevel=2)
lockfilename_path = getattr(mypath, 'name', None)
mypath = mypath.fileno()
if isinstance(mypath, int):
warnings.warn("portage.locks.lockfile() support for integer file "
"descriptor parameters is deprecated. Use a file path instead.",
DeprecationWarning, stacklevel=2)
lockfilename = mypath
wantnewlockfile = 0
unlinkfile = 0
elif wantnewlockfile:
base, tail = os.path.split(mypath)
lockfilename = os.path.join(base, "." + tail + ".portage_lockfile")
lockfilename_path = lockfilename
unlinkfile = 1
else:
lockfilename = mypath
if isinstance(mypath, basestring):
if not os.path.exists(os.path.dirname(mypath)):
raise DirectoryNotFound(os.path.dirname(mypath))
preexisting = os.path.exists(lockfilename)
old_mask = os.umask(000)
try:
try:
myfd = os.open(lockfilename, os.O_CREAT|os.O_RDWR, 0o660)
except OSError as e:
func_call = "open('%s')" % lockfilename
if e.errno == OperationNotPermitted.errno:
raise OperationNotPermitted(func_call)
elif e.errno == PermissionDenied.errno:
raise PermissionDenied(func_call)
elif e.errno == ReadOnlyFileSystem.errno:
raise ReadOnlyFileSystem(func_call)
else:
raise
if not preexisting:
try:
if os.stat(lockfilename).st_gid != portage_gid:
os.chown(lockfilename, -1, portage_gid)
except OSError as e:
if e.errno in (errno.ENOENT, errno.ESTALE):
return lockfile(mypath,
wantnewlockfile=wantnewlockfile,
unlinkfile=unlinkfile, waiting_msg=waiting_msg,
flags=flags)
else:
writemsg("%s: chown('%s', -1, %d)\n" % \
(e, lockfilename, portage_gid), noiselevel=-1)
writemsg(_("Cannot chown a lockfile: '%s'\n") % \
lockfilename, noiselevel=-1)
writemsg(_("Group IDs of current user: %s\n") % \
" ".join(str(n) for n in os.getgroups()),
noiselevel=-1)
finally:
os.umask(old_mask)
elif isinstance(mypath, int):
myfd = mypath
else:
raise ValueError(_("Unknown type passed in '%s': '%s'") % \
(type(mypath), mypath))
# try for a non-blocking lock, if it's held, throw a message
# we're waiting on lockfile and use a blocking attempt.
locking_method = portage._eintr_func_wrapper(_default_lock_fn)
try:
if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ:
raise IOError(errno.ENOSYS, "Function not implemented")
locking_method(myfd, fcntl.LOCK_EX|fcntl.LOCK_NB)
except IOError as e:
if not hasattr(e, "errno"):
raise
if e.errno in (errno.EACCES, errno.EAGAIN, errno.ENOLCK):
#.........这里部分代码省略.........
from repoman.argparser import parse_args
from repoman.qa_data import QAData
from repoman.qa_data import format_qa_output, format_qa_output_column
from repoman.repos import RepoSettings
from repoman.scanner import Scanner
from repoman import utilities
from repoman.modules.vcs.settings import VCSSettings
from repoman import VERSION
if sys.hexversion >= 0x3000000:
basestring = str
bad = create_color_func("BAD")
# A sane umask is needed for files that portage creates.
os.umask(0o22)
LOGLEVEL = logging.WARNING
portage.util.initialize_logger(LOGLEVEL)
VALID_VERSIONS = [1,]
def repoman_main(argv):
config_root = os.environ.get("PORTAGE_CONFIGROOT")
repoman_settings = portage.config(config_root=config_root, local_config=False)
repoman_settings.valid_versions = VALID_VERSIONS
if repoman_settings.get("NOCOLOR", "").lower() in ("yes", "true") or \
repoman_settings.get('TERM') == 'dumb' or \
not sys.stdout.isatty():
nocolor()
def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask,
pre_exec, close_fds, unshare_net, unshare_ipc, cgroup):
"""
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
@param pre_exec: A function to be called with no arguments just prior to the exec call.
@type pre_exec: callable
@param unshare_net: If True, networking will be unshared from the spawned process
@type unshare_net: Boolean
@param unshare_ipc: If True, IPC will be unshared from the spawned process
@type unshare_ipc: Boolean
@param cgroup: CGroup path to bind the process to
@type cgroup: String
@rtype: None
@return: 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:
if binary is portage._python_interpreter:
# NOTE: PyPy 1.7 will die due to "libary path not found" if argv[0]
# does not contain the full path of the binary.
opt_name = binary
else:
opt_name = os.path.basename(binary)
# Set up the command's argument list.
myargs = [opt_name]
myargs.extend(mycommand[1:])
# Avoid a potential UnicodeEncodeError from os.execve().
myargs = [_unicode_encode(x, encoding=_encodings['fs'],
errors='strict') for x in myargs]
# Use default signal handlers in order to avoid problems
# killing subprocesses as reported in bug #353239.
signal.signal(signal.SIGINT, signal.SIG_DFL)
signal.signal(signal.SIGTERM, signal.SIG_DFL)
# Quiet killing of subprocesses by SIGPIPE (see bug #309001).
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
# Avoid issues triggered by inheritance of SIGQUIT handler from
# the parent process (see bug #289486).
signal.signal(signal.SIGQUIT, signal.SIG_DFL)
_setup_pipes(fd_pipes, close_fds=close_fds, inheritable=True)
# Add to cgroup
# it's better to do it from the child since we can guarantee
# it is done before we start forking children
if cgroup:
with open(os.path.join(cgroup, 'cgroup.procs'), 'a') as f:
f.write('%d\n' % os.getpid())
# Unshare (while still uid==0)
if unshare_net or unshare_ipc:
filename = find_library("c")
if filename is not None:
libc = LoadLibrary(filename)
if libc is not None:
CLONE_NEWIPC = 0x08000000
CLONE_NEWNET = 0x40000000
flags = 0
if unshare_net:
flags |= CLONE_NEWNET
if unshare_ipc:
flags |= CLONE_NEWIPC
try:
if libc.unshare(flags) != 0:
writemsg("Unable to unshare: %s\n" % (
errno.errorcode.get(ctypes.get_errno(), '?')),
noiselevel=-1)
else:
if unshare_net:
# 'up' the loopback
IFF_UP = 0x1
ifreq = struct.pack('16sh', b'lo', IFF_UP)
#.........这里部分代码省略.........
def _exec(binary, mycommand, opt_name, fd_pipes,
env, gid, groups, uid, umask, cwd,
pre_exec, close_fds, unshare_net, unshare_ipc, unshare_mount, unshare_pid,
unshare_flags, cgroup):
"""
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: List
@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
@param cwd: Current working directory
@type cwd: String
@param pre_exec: A function to be called with no arguments just prior to the exec call.
@type pre_exec: callable
@param unshare_net: If True, networking will be unshared from the spawned process
@type unshare_net: Boolean
@param unshare_ipc: If True, IPC will be unshared from the spawned process
@type unshare_ipc: Boolean
@param unshare_mount: If True, mount namespace will be unshared and mounts will
be private to the namespace
@type unshare_mount: Boolean
@param unshare_pid: If True, PID ns will be unshared from the spawned process
@type unshare_pid: Boolean
@param unshare_flags: Flags for the unshare(2) function
@type unshare_flags: Integer
@param cgroup: CGroup path to bind the process to
@type cgroup: String
@rtype: None
@return: 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:
if binary is portage._python_interpreter:
# NOTE: PyPy 1.7 will die due to "libary path not found" if argv[0]
# does not contain the full path of the binary.
opt_name = binary
else:
opt_name = os.path.basename(binary)
# Set up the command's argument list.
myargs = [opt_name]
myargs.extend(mycommand[1:])
# Avoid a potential UnicodeEncodeError from os.execve().
myargs = [_unicode_encode(x, encoding=_encodings['fs'],
errors='strict') for x in myargs]
# Use default signal handlers in order to avoid problems
# killing subprocesses as reported in bug #353239.
signal.signal(signal.SIGINT, signal.SIG_DFL)
signal.signal(signal.SIGTERM, signal.SIG_DFL)
# Unregister SIGCHLD handler and wakeup_fd for the parent
# process's event loop (bug 655656).
signal.signal(signal.SIGCHLD, signal.SIG_DFL)
try:
wakeup_fd = signal.set_wakeup_fd(-1)
if wakeup_fd > 0:
os.close(wakeup_fd)
except (ValueError, OSError):
pass
# Quiet killing of subprocesses by SIGPIPE (see bug #309001).
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
# Avoid issues triggered by inheritance of SIGQUIT handler from
# the parent process (see bug #289486).
signal.signal(signal.SIGQUIT, signal.SIG_DFL)
_setup_pipes(fd_pipes, close_fds=close_fds, inheritable=True)
# Add to cgroup
# it's better to do it from the child since we can guarantee
# it is done before we start forking children
if cgroup:
with open(os.path.join(cgroup, 'cgroup.procs'), 'a') as f:
f.write('%d\n' % os.getpid())
# Unshare (while still uid==0)
if unshare_net or unshare_ipc or unshare_mount or unshare_pid:
filename = find_library("c")
if filename is not None:
#.........这里部分代码省略.........
def pre_sync(self, repo):
self.settings, self.trees, self.mtimedb = self.emerge_config
self.xterm_titles = "notitles" not in self.settings.features
msg = ">>> Synchronization of repository '%s' located in '%s'..." \
% (repo.name, repo.location)
self.logger(self.xterm_titles, msg)
writemsg_level(msg + "\n")
try:
st = os.stat(repo.location)
except OSError:
st = None
self.usersync_uid = None
spawn_kwargs = {}
spawn_kwargs["env"] = self.settings.environ()
if repo.sync_user is not None:
def get_sync_user_data(sync_user):
user = None
group = None
home = None
spl = sync_user.split(':', 1)
if spl[0]:
username = spl[0]
try:
try:
pw = pwd.getpwnam(username)
except KeyError:
pw = pwd.getpwuid(int(username))
except (ValueError, KeyError):
writemsg("!!! User '%s' invalid or does not exist\n"
% username, noiselevel=-1)
return (user, group, home)
user = pw.pw_uid
group = pw.pw_gid
home = pw.pw_dir
if len(spl) > 1:
groupname = spl[1]
try:
try:
gp = grp.getgrnam(groupname)
except KeyError:
pw = grp.getgrgid(int(groupname))
except (ValueError, KeyError):
writemsg("!!! Group '%s' invalid or does not exist\n"
% groupname, noiselevel=-1)
return (user, group, home)
group = gp.gr_gid
return (user, group, home)
# user or user:group
(uid, gid, home) = get_sync_user_data(repo.sync_user)
if uid is not None:
spawn_kwargs["uid"] = uid
self.usersync_uid = uid
if gid is not None:
spawn_kwargs["gid"] = gid
spawn_kwargs["groups"] = [gid]
if home is not None:
spawn_kwargs["env"]["HOME"] = home
if st is None:
perms = {'mode': 0o755}
# respect sync-user if set
if 'umask' in spawn_kwargs:
perms['mode'] &= ~spawn_kwargs['umask']
if 'uid' in spawn_kwargs:
perms['uid'] = spawn_kwargs['uid']
if 'gid' in spawn_kwargs:
perms['gid'] = spawn_kwargs['gid']
writemsg_level(">>> '%s' not found, creating it."
% _unicode_decode(repo.location))
portage.util.ensure_dirs(repo.location, **perms)
st = os.stat(repo.location)
if (repo.sync_user is None and
'usersync' in self.settings.features and
portage.data.secpass >= 2 and
(st.st_uid != os.getuid() and st.st_mode & 0o700 or
st.st_gid != os.getgid() and st.st_mode & 0o070)):
try:
homedir = pwd.getpwuid(st.st_uid).pw_dir
except KeyError:
pass
else:
# Drop privileges when syncing, in order to match
# existing uid/gid settings.
self.usersync_uid = st.st_uid
spawn_kwargs["uid"] = st.st_uid
spawn_kwargs["gid"] = st.st_gid
spawn_kwargs["groups"] = [st.st_gid]
spawn_kwargs["env"]["HOME"] = homedir
umask = 0o002
if not st.st_mode & 0o020:
umask = umask | 0o020
spawn_kwargs["umask"] = umask
#.........这里部分代码省略.........
def _get_legacy_global(name):
constructed = portage._legacy_globals_constructed
if name in constructed:
return getattr(portage, name)
if name == 'portdb':
portage.portdb = portage.db[portage.root]["porttree"].dbapi
constructed.add(name)
return getattr(portage, name)
elif name in ('mtimedb', 'mtimedbfile'):
portage.mtimedbfile = os.path.join(portage.settings['EROOT'],
CACHE_PATH, "mtimedb")
constructed.add('mtimedbfile')
portage.mtimedb = portage.MtimeDB(portage.mtimedbfile)
constructed.add('mtimedb')
return getattr(portage, name)
# Portage needs to ensure a sane umask for the files it creates.
os.umask(0o22)
kwargs = {}
for k, envvar in (("config_root", "PORTAGE_CONFIGROOT"),
("target_root", "ROOT"), ("eprefix", "EPREFIX")):
kwargs[k] = os.environ.get(envvar)
portage._initializing_globals = True
portage.db = portage.create_trees(**kwargs)
constructed.add('db')
del portage._initializing_globals
settings = portage.db[portage.db._target_eroot]["vartree"].settings
portage.settings = settings
constructed.add('settings')
# Since portage.db now uses EROOT for keys instead of ROOT, we make
# portage.root refer to EROOT such that it continues to work as a key.
portage.root = portage.db._target_eroot
constructed.add('root')
# COMPATIBILITY
# These attributes should not be used within
# Portage under any circumstances.
portage.archlist = settings.archlist()
constructed.add('archlist')
portage.features = settings.features
constructed.add('features')
portage.groups = settings.get("ACCEPT_KEYWORDS", "").split()
constructed.add('groups')
portage.pkglines = settings.packages
constructed.add('pkglines')
portage.selinux_enabled = settings.selinux_enabled()
constructed.add('selinux_enabled')
portage.thirdpartymirrors = settings.thirdpartymirrors()
constructed.add('thirdpartymirrors')
profiledir = os.path.join(settings["PORTAGE_CONFIGROOT"], PROFILE_PATH)
if not os.path.isdir(profiledir):
profiledir = None
portage.profiledir = profiledir
constructed.add('profiledir')
return getattr(portage, name)
def emerge_main(args=None):
"""
@param args: command arguments (default: sys.argv[1:])
@type args: list
"""
if args is None:
args = sys.argv[1:]
args = portage._decode_argv(args)
# Use system locale.
locale.setlocale(locale.LC_ALL, '')
# Disable color until we're sure that it should be enabled (after
# EMERGE_DEFAULT_OPTS has been parsed).
portage.output.havecolor = 0
# This first pass is just for options that need to be known as early as
# possible, such as --config-root. They will be parsed again later,
# together with EMERGE_DEFAULT_OPTS (which may vary depending on the
# the value of --config-root).
myaction, myopts, myfiles = parse_opts(args, silent=True)
if "--debug" in myopts:
os.environ["PORTAGE_DEBUG"] = "1"
if "--config-root" in myopts:
os.environ["PORTAGE_CONFIGROOT"] = myopts["--config-root"]
if "--root" in myopts:
os.environ["ROOT"] = myopts["--root"]
if "--prefix" in myopts:
os.environ["EPREFIX"] = myopts["--prefix"]
if "--accept-properties" in myopts:
os.environ["ACCEPT_PROPERTIES"] = myopts["--accept-properties"]
if "--accept-restrict" in myopts:
os.environ["ACCEPT_RESTRICT"] = myopts["--accept-restrict"]
# optimize --help (no need to load config / EMERGE_DEFAULT_OPTS)
if myaction == "help":
emerge_help()
return os.EX_OK
elif myaction == "moo":
print(COWSAY_MOO % platform.system())
return os.EX_OK
# Portage needs to ensure a sane umask for the files it creates.
os.umask(0o22)
if myaction == "sync":
portage._sync_mode = True
emerge_config = load_emerge_config(
action=myaction, args=myfiles, opts=myopts)
rval = profile_check(emerge_config.trees, emerge_config.action)
if rval != os.EX_OK:
return rval
tmpcmdline = []
if "--ignore-default-opts" not in myopts:
tmpcmdline.extend(portage.util.shlex_split(
emerge_config.target_config.settings.get(
"EMERGE_DEFAULT_OPTS", "")))
tmpcmdline.extend(args)
emerge_config.action, emerge_config.opts, emerge_config.args = \
parse_opts(tmpcmdline)
try:
return run_action(emerge_config)
finally:
# Call destructors for our portdbapi instances.
for x in emerge_config.trees.values():
if "porttree" in x.lazy_items:
continue
x["porttree"].dbapi.close_caches()
开发者ID:Spencerx,项目名称:portage,代码行数:70,代码来源:main.py
示例15: emerge_main
def emerge_main():
global portage # NFC why this is necessary now - genone
portage._disable_legacy_globals()
# Disable color until we're sure that it should be enabled (after
# EMERGE_DEFAULT_OPTS has been parsed).
portage.output.havecolor = 0
# This first pass is just for options that need to be known as early as
# possible, such as --config-root. They will be parsed again later,
# together with EMERGE_DEFAULT_OPTS (which may vary depending on the
# the value of --config-root).
myaction, myopts, myfiles = parse_opts(sys.argv[1:], silent=True)
if "--debug" in myopts:
os.environ["PORTAGE_DEBUG"] = "1"
if "--config-root" in myopts:
os.environ["PORTAGE_CONFIGROOT"] = myopts["--config-root"]
if "--root" in myopts:
os.environ["ROOT"] = myopts["--root"]
if "--accept-properties" in myopts:
os.environ["ACCEPT_PROPERTIES"] = myopts["--accept-properties"]
# Portage needs to ensure a sane umask for the files it creates.
os.umask(0o22)
settings, trees, mtimedb = load_emerge_config()
portdb = trees[settings["ROOT"]]["porttree"].dbapi
rval = profile_check(trees, myaction)
if rval != os.EX_OK:
return rval
if myaction not in ('help', 'info', 'version') and \
_global_updates(trees, mtimedb["updates"]):
mtimedb.commit()
# Reload the whole config from scratch.
settings, trees, mtimedb = load_emerge_config(trees=trees)
portdb = trees[settings["ROOT"]]["porttree"].dbapi
xterm_titles = "notitles" not in settings.features
if xterm_titles:
xtermTitle("emerge")
tmpcmdline = []
if "--ignore-default-opts" not in myopts:
tmpcmdline.extend(settings["EMERGE_DEFAULT_OPTS"].split())
tmpcmdline.extend(sys.argv[1:])
myaction, myopts, myfiles = parse_opts(tmpcmdline)
if "--digest" in myopts:
os.environ["FEATURES"] = os.environ.get("FEATURES","") + " digest"
# Reload the whole config from scratch so that the portdbapi internal
# config is updated with new FEATURES.
settings, trees, mtimedb = load_emerge_config(trees=trees)
portdb = trees[settings["ROOT"]]["porttree"].dbapi
adjust_configs(myopts, trees)
apply_priorities(settings)
if myaction == 'version':
writemsg_stdout(getportageversion(
settings["PORTDIR"], settings["ROOT"],
settings.profile_path, settings["CHOST"],
trees[settings["ROOT"]]["vartree"].dbapi) + '\n', noiselevel=-1)
return 0
elif myaction == 'help':
_emerge.help.help(myopts, portage.output.havecolor)
return 0
spinner = stdout_spinner()
if "candy" in settings.features:
spinner.update = spinner.update_scroll
if "--quiet" not in myopts:
portage.deprecated_profile_check(settings=settings)
repo_name_check(trees)
repo_name_duplicate_check(trees)
config_protect_check(trees)
check_procfs()
if "getbinpkg" in settings.features:
myopts["--getbinpkg"] = True
if "--getbinpkgonly" in myopts:
myopts["--getbinpkg"] = True
if "--getbinpkgonly" in myopts:
myopts["--usepkgonly"] = True
if "--getbinpkg" in myopts:
myopts["--usepkg"] = True
if "--usepkgonly" in myopts:
myopts["--usepkg"] = True
if "buildpkg" in settings.features or "--buildpkgonly" in myopts:
myopts["--buildpkg"] = True
if "--buildpkgonly" in myopts:
# --buildpkgonly will not merge anything, so
# it cancels all binary package options.
for opt in ("--getbinpkg", "--getbinpkgonly",
"--usepkg", "--usepkgonly"):
myopts.pop(opt, None)
#.........这里部分代码省略.........
def lockfile(mypath, wantnewlockfile=0, unlinkfile=0,
waiting_msg=None, flags=0):
"""
If wantnewlockfile is True then this creates a lockfile in the parent
directory as the file: '.' + basename + '.portage_lockfile'.
"""
import fcntl
if not mypath:
raise InvalidData(_("Empty path given"))
if isinstance(mypath, basestring) and mypath[-1] == '/':
mypath = mypath[:-1]
if hasattr(mypath, 'fileno'):
mypath = mypath.fileno()
if isinstance(mypath, int):
lockfilename = mypath
wantnewlockfile = 0
unlinkfile = 0
elif wantnewlockfile:
base, tail = os.path.split(mypath)
lockfilename = os.path.join(base, "." + tail + ".portage_lockfile")
del base, tail
unlinkfile = 1
else:
lockfilename = mypath
if isinstance(mypath, basestring):
if not os.path.exists(os.path.dirname(mypath)):
raise DirectoryNotFound(os.path.dirname(mypath))
preexisting = os.path.exists(lockfilename)
old_mask = os.umask(000)
try:
try:
myfd = os.open(lockfilename, os.O_CREAT|os.O_RDWR, 0o660)
except OSError as e:
func_call = "open('%s')" % lockfilename
if e.errno == OperationNotPermitted.errno:
raise OperationNotPermitted(func_call)
elif e.errno == PermissionDenied.errno:
raise PermissionDenied(func_call)
else:
raise
if not preexisting:
try:
if os.stat(lockfilename).st_gid != portage_gid:
os.chown(lockfilename, -1, portage_gid)
except OSError as e:
if e.errno in (errno.ENOENT, errno.ESTALE):
return lockfile(mypath,
wantnewlockfile=wantnewlockfile,
unlinkfile=unlinkfile, waiting_msg=waiting_msg,
flags=flags)
else:
writemsg(_("Cannot chown a lockfile: '%s'\n") % \
lockfilename, noiselevel=-1)
finally:
os.umask(old_mask)
elif isinstance(mypath, int):
myfd = mypath
else:
raise ValueError(_("Unknown type passed in '%s': '%s'") % \
(type(mypath), mypath))
# try for a non-blocking lock, if it's held, throw a message
# we're waiting on lockfile and use a blocking attempt.
locking_method = fcntl.lockf
try:
fcntl.lockf(myfd,fcntl.LOCK_EX|fcntl.LOCK_NB)
except IOError as e:
if "errno" not in dir(e):
raise
if e.errno in (errno.EACCES, errno.EAGAIN):
# resource temp unavailable; eg, someone beat us to the lock.
if flags & os.O_NONBLOCK:
raise TryAgain(mypath)
global _quiet
out = EOutput()
out.quiet = _quiet
if waiting_msg is None:
if isinstance(mypath, int):
waiting_msg = _("waiting for lock on fd %i") % myfd
else:
waiting_msg = _("waiting for lock on %s\n") % lockfilename
out.ebegin(waiting_msg)
# try for the exclusive lock now.
try:
fcntl.lockf(myfd, fcntl.LOCK_EX)
except EnvironmentError as e:
out.eend(1, str(e))
raise
out.eend(os.EX_OK)
elif e.errno == errno.ENOLCK:
# We're not allowed to lock on this FS.
#.........这里部分代码省略.........
请发表评论