def test_coroutine(loop=None): proc = (yield create_subprocess_exec(echo_binary, *args_tuple, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, loop=loop)) out, err = (yield proc.communicate()) self.assertEqual(tuple(out.split()), args_tuple) self.assertEqual(proc.returncode, os.EX_OK) proc = (yield create_subprocess_exec( 'bash', '-c', 'echo foo; echo bar 1>&2;', stdout=subprocess.PIPE, stderr=subprocess.PIPE, loop=loop)) out, err = (yield proc.communicate()) self.assertEqual(out, b'foo\n') self.assertEqual(err, b'bar\n') self.assertEqual(proc.returncode, os.EX_OK) proc = (yield create_subprocess_exec( 'bash', '-c', 'echo foo; echo bar 1>&2;', stdout=subprocess.PIPE, stderr=subprocess.STDOUT, loop=loop)) out, err = (yield proc.communicate()) self.assertEqual(out, b'foo\nbar\n') self.assertEqual(err, None) self.assertEqual(proc.returncode, os.EX_OK) coroutine_return('success')
def init_update(self): update_location = os.path.join(self._storage_location, 'update') yield self._check_call(['rm', '-rf', update_location]) # This assumes normal umask permissions if it doesn't exist yet. portage.util.ensure_dirs(self._storage_location) if self._latest_canonical is not None: portage.util.ensure_dirs(update_location) portage.util.apply_stat_permissions(update_location, os.stat(self._user_location)) # Use rsync --link-dest to hardlink a files into update_location, # since cp -l is not portable. yield self._check_call([ 'rsync', '-a', '--link-dest', self._latest_canonical, self._latest_canonical + '/', update_location + '/' ]) elif not os.path.islink(self._user_location): yield self._migrate(update_location) update_location = (yield self.init_update()) self._update_location = update_location coroutine_return(self._update_location)
def test_coroutine(loop=None): proc = (yield create_subprocess_exec(echo_binary, *args_tuple, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, loop=loop)) out, err = (yield proc.communicate()) self.assertEqual(tuple(out.split()), args_tuple) self.assertEqual(proc.returncode, os.EX_OK) proc = (yield create_subprocess_exec( 'bash', '-c', 'echo foo; echo bar 1>&2;', stdout=subprocess.PIPE, stderr=subprocess.PIPE, loop=loop)) out, err = (yield proc.communicate()) self.assertEqual(out, b'foo\n') self.assertEqual(err, b'bar\n') self.assertEqual(proc.returncode, os.EX_OK) proc = (yield create_subprocess_exec( 'bash', '-c', 'echo foo; echo bar 1>&2;', stdout=subprocess.PIPE, stderr=subprocess.STDOUT, loop=loop)) out, err = (yield proc.communicate()) self.assertEqual(out, b'foo\nbar\n') self.assertEqual(err, None) self.assertEqual(proc.returncode, os.EX_OK) coroutine_return('success')
def _testPipeLoggerToPipe(self, test_string, loop=None): """ Test PipeLogger writing to a pipe connected to a PipeReader. This verifies that PipeLogger does not deadlock when writing to a pipe that's drained by a PipeReader running in the same process (requires non-blocking write). """ input_fd, writer_pipe = os.pipe() _set_nonblocking(writer_pipe) writer_pipe = os.fdopen(writer_pipe, 'wb', 0) writer = asyncio.ensure_future(_writer(writer_pipe, test_string.encode('ascii'), loop=loop), loop=loop) writer.add_done_callback(lambda writer: writer_pipe.close()) pr, pw = os.pipe() consumer = PipeLogger(background=True, input_fd=input_fd, log_file_path=os.fdopen(pw, 'wb', 0), scheduler=loop) consumer.start() # Before starting the reader, wait here for a moment, in order # to exercise PipeLogger's handling of EAGAIN during write. yield asyncio.wait([writer], timeout=0.01) reader = _reader(pr, loop=loop) yield writer content = yield reader yield consumer.async_wait() self.assertEqual(consumer.returncode, os.EX_OK) coroutine_return(content.decode('ascii', 'replace'))
def _testPipeLoggerToPipe(self, test_string, loop=None): """ Test PipeLogger writing to a pipe connected to a PipeReader. This verifies that PipeLogger does not deadlock when writing to a pipe that's drained by a PipeReader running in the same process (requires non-blocking write). """ producer = PopenProcess(proc=subprocess.Popen( ["bash", "-c", self._echo_cmd % test_string], stdout=subprocess.PIPE, stderr=subprocess.STDOUT), scheduler=loop) pr, pw = os.pipe() consumer = producer.pipe_reader = PipeLogger( background=True, input_fd=producer.proc.stdout, log_file_path=os.fdopen(pw, 'wb', 0)) reader = _reader(pr, loop=loop) yield producer.async_start() content = yield reader yield producer.async_wait() yield consumer.async_wait() self.assertEqual(producer.returncode, os.EX_OK) self.assertEqual(consumer.returncode, os.EX_OK) coroutine_return(content.decode('ascii', 'replace'))
def read(self): while self._value is self._empty: yield self._wait() value = self._value self._value = self._empty self._notify() coroutine_return(value)
def reader_coroutine(cubby, sentinel): results = [] while True: result = yield cubby.read() if result == sentinel: break results.append(result) coroutine_return(results)
def reader_coroutine(cubby, sentinel, loop=None): results = [] while True: result = yield cubby.read(loop=loop) if result == sentinel: break results.append(result) coroutine_return(results)
def read(self, loop=None): while self._value is self._empty: yield self._wait() value = self._value self._value = self._empty self._notify() coroutine_return(value)
def async_fetch(pkg, ebuild_path): fetcher = EbuildFetcher(config_pool=config_pool, ebuild_path=ebuild_path, fetchonly=False, fetchall=True, pkg=pkg, scheduler=loop) yield fetcher.async_start() result = yield fetcher.async_wait() coroutine_return(result)
def catching_coroutine(loop=None): loop = asyncio._wrap_loop(loop) future = loop.create_future() loop.call_soon(future.set_exception, TestException('exception')) try: yield future except TestException: self.assertTrue(True) else: self.assertTrue(False) coroutine_return('success')
def catching_coroutine(loop=None): loop = asyncio._wrap_loop(loop) future = loop.create_future() loop.call_soon(future.set_exception, TestException('exception')) try: yield future except TestException: self.assertTrue(True) else: self.assertTrue(False) coroutine_return('success')
def commit_update(self): update_location = self.current_update self._update_location = None try: snapshots = [int(name) for name in os.listdir(self._snapshots_dir)] except OSError: snapshots = [] portage.util.ensure_dirs(self._snapshots_dir) portage.util.apply_stat_permissions( self._snapshots_dir, os.stat(self._storage_location)) if snapshots: new_id = max(snapshots) + 1 else: new_id = 1 os.rename(update_location, os.path.join(self._snapshots_dir, str(new_id))) new_symlink = self._latest_symlink + '.new' try: os.unlink(new_symlink) except OSError: pass os.symlink('snapshots/{}'.format(new_id), new_symlink) # If SyncManager.pre_sync creates an empty directory where # self._latest_symlink is suppose to be (which is normal if # sync-rcu-store-dir has been removed), then we need to remove # the directory or else rename will raise IsADirectoryError # when we try to replace the directory with a symlink. try: os.rmdir(self._latest_symlink) except OSError: pass os.rename(new_symlink, self._latest_symlink) try: user_location_correct = os.path.samefile(self._user_location, self._latest_symlink) except OSError: user_location_correct = False if not user_location_correct: new_symlink = self._user_location + '.new' try: os.unlink(new_symlink) except OSError: pass os.symlink(self._latest_symlink, new_symlink) os.rename(new_symlink, self._user_location) coroutine_return() yield None
def communicate(self, input=None): """ Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate. @param input: stdin content to write @type input: bytes @return: tuple (stdout_data, stderr_data) @rtype: asyncio.Future (or compatible) """ futures = [] for input_file in (self._proc.stdout, self._proc.stderr): if input_file is None: future = self._loop.create_future() future.set_result(None) else: future = _reader(input_file, loop=self._loop) futures.append(future) writer = None if input is not None: if self._proc.stdin is None: raise TypeError( 'communicate: expected file or int, got {}'.format( type(self._proc.stdin))) stdin = self._proc.stdin stdin = os.fdopen(stdin, 'wb', 0) if isinstance(stdin, int) else stdin _set_nonblocking(stdin.fileno()) writer = asyncio.ensure_future(_writer(stdin, input, loop=self._loop), loop=self._loop) writer.add_done_callback(lambda writer: stdin.close()) try: yield asyncio.wait(futures + [self.wait()], loop=self._loop) finally: if writer is not None: if writer.done(): # Consume expected exceptions. try: writer.result() except EnvironmentError: # This is normal if the other end of the pipe was closed. pass else: writer.cancel() coroutine_return(tuple(future.result() for future in futures))
def init_update(self): update_location = os.path.join(self._user_location, '.tmp-unverified-download-quarantine') yield self._check_call(['rm', '-rf', update_location]) # Use rsync --link-dest to hardlink a files into self._update_location, # since cp -l is not portable. yield self._check_call(['rsync', '-a', '--link-dest', self._user_location, '--exclude=/distfiles', '--exclude=/local', '--exclude=/lost+found', '--exclude=/packages', '--exclude', '/{}'.format(os.path.basename(update_location)), self._user_location + '/', update_location + '/']) self._update_location = update_location coroutine_return(self._update_location)
def _test_mod_async(self, ebuilds, ebuild_inherited, eclass_defined_phases, eclass_depend, portdb, loop=None): for cpv, metadata in ebuilds.items(): defined_phases, depend, eapi, inherited = yield portdb.async_aux_get( cpv, ['DEFINED_PHASES', 'DEPEND', 'EAPI', 'INHERITED'], loop=loop) self.assertEqual(defined_phases, eclass_defined_phases) self.assertEqual(depend, eclass_depend) self.assertEqual(eapi, metadata['EAPI']) self.assertEqual(frozenset(inherited.split()), ebuild_inherited) coroutine_return(True)
def init_update(self): update_location = os.path.join(self._user_location, '.tmp-unverified-download-quarantine') yield self._check_call(['rm', '-rf', update_location]) # Use rsync --link-dest to hardlink a files into self._update_location, # since cp -l is not portable. yield self._check_call([ 'rsync', '-a', '--link-dest', self._user_location, '--exclude=/distfiles', '--exclude=/local', '--exclude=/lost+found', '--exclude=/packages', '--exclude', '/{}'.format(os.path.basename(update_location)), self._user_location + '/', update_location + '/' ]) self._update_location = update_location coroutine_return(self._update_location)
def commit_update(self): update_location = self.current_update self._update_location = None try: snapshots = [int(name) for name in os.listdir(self._snapshots_dir)] except OSError: snapshots = [] portage.util.ensure_dirs(self._snapshots_dir) portage.util.apply_stat_permissions( self._snapshots_dir, os.stat(self._storage_location)) if snapshots: new_id = max(snapshots) + 1 else: new_id = 1 os.rename(update_location, os.path.join(self._snapshots_dir, str(new_id))) new_symlink = self._latest_symlink + '.new' try: os.unlink(new_symlink) except OSError: pass os.symlink('snapshots/{}'.format(new_id), new_symlink) os.rename(new_symlink, self._latest_symlink) try: user_location_correct = os.path.samefile(self._user_location, self._latest_symlink) except OSError: user_location_correct = False if not user_location_correct: new_symlink = self._user_location + '.new' try: os.unlink(new_symlink) except OSError: pass os.symlink(self._latest_symlink, new_symlink) os.rename(new_symlink, self._user_location) coroutine_return() yield None
def fetch_wait_result(scheduler, first, loop=None): if first: yield scheduler.async_start() # If the current coroutine awakens just after a call to # done_callback but before scheduler has been notified of # corresponding done future(s), then wait here until scheduler # is notified (which will cause future_map to populate). while not future_map and scheduler.poll() is None: yield asyncio.sleep(0, loop=loop) if not future_map: if scheduler.poll() is not None: coroutine_return((set(), set())) else: raise AssertionError('expected non-empty future_map') wait_result = yield asyncio.wait(list(future_map.values()), return_when=asyncio.FIRST_COMPLETED, loop=loop) coroutine_return(wait_result)
def commit_update(self): update_location = self.current_update self._update_location = None try: snapshots = [int(name) for name in os.listdir(self._snapshots_dir)] except OSError: snapshots = [] portage.util.ensure_dirs(self._snapshots_dir) portage.util.apply_stat_permissions(self._snapshots_dir, os.stat(self._storage_location)) if snapshots: new_id = max(snapshots) + 1 else: new_id = 1 os.rename(update_location, os.path.join(self._snapshots_dir, str(new_id))) new_symlink = self._latest_symlink + '.new' try: os.unlink(new_symlink) except OSError: pass os.symlink('snapshots/{}'.format(new_id), new_symlink) os.rename(new_symlink, self._latest_symlink) try: user_location_correct = os.path.samefile(self._user_location, self._latest_symlink) except OSError: user_location_correct = False if not user_location_correct: new_symlink = self._user_location + '.new' try: os.unlink(new_symlink) except OSError: pass os.symlink(self._latest_symlink, new_symlink) os.rename(new_symlink, self._user_location) coroutine_return() yield None
def init_update(self): update_location = os.path.join(self._storage_location, 'update') yield self._check_call(['rm', '-rf', update_location]) # This assumes normal umask permissions if it doesn't exist yet. portage.util.ensure_dirs(self._storage_location) if self._latest_canonical is not None: portage.util.ensure_dirs(update_location) portage.util.apply_stat_permissions(update_location, os.stat(self._user_location)) # Use rsync --link-dest to hardlink a files into update_location, # since cp -l is not portable. yield self._check_call(['rsync', '-a', '--link-dest', self._latest_canonical, self._latest_canonical + '/', update_location + '/']) elif not os.path.islink(self._user_location): yield self._migrate(update_location) update_location = (yield self.init_update()) self._update_location = update_location coroutine_return(self._update_location)
def commit_update(self): self.current_update self._update_location = None coroutine_return() yield None
def async_xmatch(self, level, origdep, loop=None): """ Asynchronous form of xmatch. @param level: xmatch level (bestmatch-visible, match-all-cpv-only match-allmatch-visible, minimum-all, minimum-all-ignore-profile, or minimum-visible) @type level: str @param origdep: dependency to match (may omit category) @type origdep: portage.dep.Atom or str @param loop: event loop (defaults to global event loop) @type loop: EventLoop @return: match result(s) @rtype: asyncio.Future (or compatible), which results in a _pkg_str or list of _pkg_str (depends on level) """ mydep = dep_expand(origdep, mydb=self, settings=self.settings) mykey = mydep.cp #if no updates are being made to the tree, we can consult our xcache... cache_key = None if self.frozen: cache_key = (mydep, mydep.unevaluated_atom) try: coroutine_return(self.xcache[level][cache_key][:]) except KeyError: pass loop = asyncio._wrap_loop(loop) myval = None mytree = None if mydep.repo is not None: mytree = self.treemap.get(mydep.repo) if mytree is None: if level.startswith("match-"): myval = [] else: myval = "" if myval is not None: # Unknown repo, empty result. pass elif level == "match-all-cpv-only": # match *all* packages, only against the cpv, in order # to bypass unnecessary cache access for things like IUSE # and SLOT. if mydep == mykey: # Share cache with match-all/cp_list when the result is the # same. Note that this requires that mydep.repo is None and # thus mytree is also None. level = "match-all" myval = self.cp_list(mykey, mytree=mytree) else: myval = match_from_list(mydep, self.cp_list(mykey, mytree=mytree)) elif level in ("bestmatch-visible", "match-all", "match-visible", "minimum-all", "minimum-all-ignore-profile", "minimum-visible"): # Find the minimum matching visible version. This is optimized to # minimize the number of metadata accesses (improves performance # especially in cases where metadata needs to be generated). if mydep == mykey: mylist = self.cp_list(mykey, mytree=mytree) else: mylist = match_from_list(mydep, self.cp_list(mykey, mytree=mytree)) ignore_profile = level in ("minimum-all-ignore-profile",) visibility_filter = level not in ("match-all", "minimum-all", "minimum-all-ignore-profile") single_match = level not in ("match-all", "match-visible") myval = [] aux_keys = list(self._aux_cache_keys) if level == "bestmatch-visible": iterfunc = reversed else: iterfunc = iter for cpv in iterfunc(mylist): try: metadata = dict(zip(aux_keys, (yield self.async_aux_get(cpv, aux_keys, myrepo=cpv.repo, loop=loop)))) except KeyError: # ebuild not in this repo, or masked by corruption continue try: pkg_str = _pkg_str(cpv, metadata=metadata, settings=self.settings, db=self) except InvalidData: continue if visibility_filter and not self._visible(pkg_str, metadata): continue if mydep.slot is not None and \ not _match_slot(mydep, pkg_str): continue if mydep.unevaluated_atom.use is not None and \ not self._match_use(mydep, pkg_str, metadata, ignore_profile=ignore_profile): continue myval.append(pkg_str) if single_match: break if single_match: if myval: myval = myval[0] else: myval = "" else: raise AssertionError( "Invalid level argument: '%s'" % level) if self.frozen: xcache_this_level = self.xcache.get(level) if xcache_this_level is not None: xcache_this_level[cache_key] = myval if not isinstance(myval, _pkg_str): myval = myval[:] coroutine_return(myval)
def init_update(self): self._update_location = self._user_location coroutine_return(self._update_location) yield None
def task_coroutine(task): task.future = loop.create_future() task.scheduler = loop yield task.async_start() result = yield task.future coroutine_return(result)
def _async_start(self): need_builddir = self.phase not in EbuildProcess._phases_without_builddir if need_builddir: phase_completed_file = os.path.join( self.settings['PORTAGE_BUILDDIR'], ".%sed" % self.phase.rstrip('e')) if not os.path.exists(phase_completed_file): # If the phase is really going to run then we want # to eliminate any stale elog messages that may # exist from a previous run. try: os.unlink( os.path.join(self.settings['T'], 'logging', self.phase)) except OSError: pass if self.phase in ('nofetch', 'pretend', 'setup'): use = self.settings.get('PORTAGE_BUILT_USE') if use is None: use = self.settings['PORTAGE_USE'] maint_str = "" upstr_str = "" metadata_xml_path = os.path.join( os.path.dirname(self.settings['EBUILD']), "metadata.xml") if MetaDataXML is not None and os.path.isfile(metadata_xml_path): herds_path = os.path.join(self.settings['PORTDIR'], 'metadata/herds.xml') try: metadata_xml = MetaDataXML(metadata_xml_path, herds_path) maint_str = metadata_xml.format_maintainer_string() upstr_str = metadata_xml.format_upstream_string() except SyntaxError: maint_str = "<invalid metadata.xml>" msg = [] msg.append("Package: %s" % self.settings.mycpv) if self.settings.get('PORTAGE_REPO_NAME'): msg.append("Repository: %s" % self.settings['PORTAGE_REPO_NAME']) if maint_str: msg.append("Maintainer: %s" % maint_str) if upstr_str: msg.append("Upstream: %s" % upstr_str) msg.append("USE: %s" % use) relevant_features = [] enabled_features = self.settings.features for x in self._features_display: if x in enabled_features: relevant_features.append(x) if relevant_features: msg.append("FEATURES: %s" % " ".join(relevant_features)) # Force background=True for this header since it's intended # for the log and it doesn't necessarily need to be visible # elsewhere. yield self._elog('einfo', msg, background=True) if self.phase == 'package': if 'PORTAGE_BINPKG_TMPFILE' not in self.settings: self.settings['PORTAGE_BINPKG_TMPFILE'] = \ os.path.join(self.settings['PKGDIR'], self.settings['CATEGORY'], self.settings['PF']) + '.tbz2' if self.phase in ("pretend", "prerm"): env_extractor = BinpkgEnvExtractor(background=self.background, scheduler=self.scheduler, settings=self.settings) if env_extractor.saved_env_exists(): self._current_task = env_extractor yield env_extractor.async_start() yield env_extractor.async_wait() if self._default_exit(env_extractor) != os.EX_OK: self._async_wait() coroutine_return() # If the environment.bz2 doesn't exist, then ebuild.sh will # source the ebuild as a fallback. self._start_lock()
def abort_update(self): self._update_location = None coroutine_return() yield None
def garbage_collection(self): coroutine_return() yield None
def init_update(self): self._update_location = self._user_location coroutine_return(self._update_location) yield None
def commit_update(self): self.current_update self._update_location = None coroutine_return() yield None
def returning_coroutine(): yield asyncio.sleep(0) coroutine_return('success')
def _async_start(self): need_builddir = self.phase not in self._phases_without_builddir # This can happen if the pre-clean phase triggers # die_hooks for some reason, and PORTAGE_BUILDDIR # doesn't exist yet. if need_builddir and \ not os.path.isdir(self.settings['PORTAGE_BUILDDIR']): msg = _("The ebuild phase '%s' has been aborted " "since PORTAGE_BUILDDIR does not exist: '%s'") % \ (self.phase, self.settings['PORTAGE_BUILDDIR']) self._eerror(textwrap.wrap(msg, 72)) self.returncode = 1 self._async_wait() coroutine_return() # Check if the cgroup hierarchy is in place. If it's not, mount it. if (os.geteuid() == 0 and platform.system() == 'Linux' and 'cgroup' in self.settings.features and self.phase not in _global_pid_phases): cgroup_root = '/sys/fs/cgroup' cgroup_portage = os.path.join(cgroup_root, 'portage') try: # cgroup tmpfs if not os.path.ismount(cgroup_root): # we expect /sys/fs to be there already if not os.path.isdir(cgroup_root): os.mkdir(cgroup_root, 0o755) subprocess.check_call([ 'mount', '-t', 'tmpfs', '-o', 'rw,nosuid,nodev,noexec,mode=0755', 'tmpfs', cgroup_root ]) # portage subsystem if not os.path.ismount(cgroup_portage): if not os.path.isdir(cgroup_portage): os.mkdir(cgroup_portage, 0o755) subprocess.check_call([ 'mount', '-t', 'cgroup', '-o', 'rw,nosuid,nodev,noexec,none,name=portage', 'tmpfs', cgroup_portage ]) with open(os.path.join(cgroup_portage, 'release_agent'), 'w') as f: f.write( os.path.join(self.settings['PORTAGE_BIN_PATH'], 'cgroup-release-agent')) with open( os.path.join(cgroup_portage, 'notify_on_release'), 'w') as f: f.write('1') else: # Update release_agent if it no longer exists, because # it refers to a temporary path when portage is updating # itself. release_agent = os.path.join(cgroup_portage, 'release_agent') try: with open(release_agent) as f: release_agent_path = f.readline().rstrip('\n') except EnvironmentError: release_agent_path = None if (release_agent_path is None or not os.path.exists(release_agent_path)): with open(release_agent, 'w') as f: f.write( os.path.join(self.settings['PORTAGE_BIN_PATH'], 'cgroup-release-agent')) cgroup_path = tempfile.mkdtemp( dir=cgroup_portage, prefix='%s:%s.' % (self.settings["CATEGORY"], self.settings["PF"])) except (subprocess.CalledProcessError, OSError): pass else: self.cgroup = cgroup_path if self.background: # Automatically prevent color codes from showing up in logs, # since we're not displaying to a terminal anyway. self.settings['NOCOLOR'] = 'true' start_ipc_daemon = False if self._enable_ipc_daemon: self.settings.pop('PORTAGE_EBUILD_EXIT_FILE', None) if self.phase not in self._phases_without_builddir: start_ipc_daemon = True if 'PORTAGE_BUILDDIR_LOCKED' not in self.settings: self._build_dir = EbuildBuildDir(scheduler=self.scheduler, settings=self.settings) yield self._build_dir.async_lock() else: self.settings.pop('PORTAGE_IPC_DAEMON', None) else: # Since the IPC daemon is disabled, use a simple tempfile based # approach to detect unexpected exit like in bug #190128. self.settings.pop('PORTAGE_IPC_DAEMON', None) if self.phase not in self._phases_without_builddir: exit_file = os.path.join(self.settings['PORTAGE_BUILDDIR'], '.exit_status') self.settings['PORTAGE_EBUILD_EXIT_FILE'] = exit_file try: os.unlink(exit_file) except OSError: if os.path.exists(exit_file): # make sure it doesn't exist raise else: self.settings.pop('PORTAGE_EBUILD_EXIT_FILE', None) if start_ipc_daemon: self.settings['PORTAGE_IPC_DAEMON'] = "1" self._start_ipc_daemon() if self.fd_pipes is None: self.fd_pipes = {} null_fd = None if 0 not in self.fd_pipes and \ self.phase not in self._phases_interactive_whitelist and \ "interactive" not in self.settings.get("PROPERTIES", "").split(): null_fd = os.open('/dev/null', os.O_RDONLY) self.fd_pipes[0] = null_fd self.log_filter_file = self.settings.get('PORTAGE_LOG_FILTER_FILE_CMD') try: yield SpawnProcess._async_start(self) finally: if null_fd is not None: os.close(null_fd)
def async_xmatch(self, level, origdep, loop=None): """ Asynchronous form of xmatch. @param level: xmatch level (bestmatch-visible, match-all-cpv-only match-allmatch-visible, minimum-all, minimum-all-ignore-profile, or minimum-visible) @type level: str @param origdep: dependency to match (may omit category) @type origdep: portage.dep.Atom or str @param loop: event loop (defaults to global event loop) @type loop: EventLoop @return: match result(s) @rtype: asyncio.Future (or compatible), which results in a _pkg_str or list of _pkg_str (depends on level) """ mydep = dep_expand(origdep, mydb=self, settings=self.settings) mykey = mydep.cp #if no updates are being made to the tree, we can consult our xcache... cache_key = None if self.frozen: cache_key = (mydep, mydep.unevaluated_atom) try: coroutine_return(self.xcache[level][cache_key][:]) except KeyError: pass loop = asyncio._wrap_loop(loop) myval = None mytree = None if mydep.repo is not None: mytree = self.treemap.get(mydep.repo) if mytree is None: if level.startswith("match-"): myval = [] else: myval = "" if myval is not None: # Unknown repo, empty result. pass elif level == "match-all-cpv-only": # match *all* packages, only against the cpv, in order # to bypass unnecessary cache access for things like IUSE # and SLOT. if mydep == mykey: # Share cache with match-all/cp_list when the result is the # same. Note that this requires that mydep.repo is None and # thus mytree is also None. level = "match-all" myval = self.cp_list(mykey, mytree=mytree) else: myval = match_from_list(mydep, self.cp_list(mykey, mytree=mytree)) elif level in ("bestmatch-visible", "match-all", "match-visible", "minimum-all", "minimum-all-ignore-profile", "minimum-visible"): # Find the minimum matching visible version. This is optimized to # minimize the number of metadata accesses (improves performance # especially in cases where metadata needs to be generated). if mydep == mykey: mylist = self.cp_list(mykey, mytree=mytree) else: mylist = match_from_list(mydep, self.cp_list(mykey, mytree=mytree)) ignore_profile = level in ("minimum-all-ignore-profile",) visibility_filter = level not in ("match-all", "minimum-all", "minimum-all-ignore-profile") single_match = level not in ("match-all", "match-visible") myval = [] aux_keys = list(self._aux_cache_keys) if level == "bestmatch-visible": iterfunc = reversed else: iterfunc = iter for cpv in iterfunc(mylist): try: metadata = dict(zip(aux_keys, (yield self.async_aux_get(cpv, aux_keys, myrepo=cpv.repo, loop=loop)))) except KeyError: # ebuild not in this repo, or masked by corruption continue try: pkg_str = _pkg_str(cpv, metadata=metadata, settings=self.settings, db=self) except InvalidData: continue if visibility_filter and not self._visible(pkg_str, metadata): continue if mydep.slot is not None and \ not _match_slot(mydep, pkg_str): continue if mydep.unevaluated_atom.use is not None and \ not self._match_use(mydep, pkg_str, metadata, ignore_profile=ignore_profile): continue myval.append(pkg_str) if single_match: break if single_match: if myval: myval = myval[0] else: myval = "" else: raise AssertionError( "Invalid level argument: '%s'" % level) if self.frozen: xcache_this_level = self.xcache.get(level) if xcache_this_level is not None: xcache_this_level[cache_key] = myval if not isinstance(myval, _pkg_str): myval = myval[:] coroutine_return(myval)
def _task(self, task, loop=None): yield task.future coroutine_return((task, task.future.result()))
def returning_coroutine(loop=None): yield asyncio.sleep(0, loop=loop) coroutine_return('success')
def abort_update(self): self._update_location = None coroutine_return() yield None
def _async_start(self): self._start() coroutine_return() yield None
def garbage_collection(self): coroutine_return() yield None
def returning_coroutine(): yield asyncio.sleep(0) coroutine_return('success')