def testNoNeedDl(self): policy = Policy(foo_iface_uri, config=self.config) policy.freshness = 0 assert policy.need_download() policy = Policy(os.path.abspath('Foo.xml'), config=self.config) assert not policy.need_download() assert policy.ready
def testNoNeedDl(self): policy = Policy(foo_iface_uri, config = self.config) policy.freshness = 0 assert policy.need_download() policy = Policy(os.path.abspath('Foo.xml'), config = self.config) assert not policy.need_download() assert policy.ready
def testDistro(self): with output_suppressed(): native_url = 'http://example.com:8000/Native.xml' # Initially, we don't have the feed at all... master_feed = self.config.iface_cache.get_feed(native_url) assert master_feed is None, master_feed trust.trust_db.trust_key('DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') self.child = server.handle_requests('Native.xml', '6FCF121BE2390E0B.gpg', '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B') policy = Policy(native_url, config = self.config) assert policy.need_download() solve = policy.solve_with_downloads() self.config.handler.wait_for_blocker(solve) tasks.check(solve) master_feed = self.config.iface_cache.get_feed(native_url) assert master_feed is not None assert master_feed.implementations == {} distro_feed_url = master_feed.get_distro_feed() assert distro_feed_url is not None distro_feed = self.config.iface_cache.get_feed(distro_feed_url) assert distro_feed is not None assert len(distro_feed.implementations) == 2, distro_feed.implementations
def testDistro(self): with output_suppressed(): native_url = 'http://example.com:8000/Native.xml' # Initially, we don't have the feed at all... master_feed = self.config.iface_cache.get_feed(native_url) assert master_feed is None, master_feed trust.trust_db.trust_key( 'DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') self.child = server.handle_requests( 'Native.xml', '6FCF121BE2390E0B.gpg', '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B') policy = Policy(native_url, config=self.config) assert policy.need_download() solve = policy.solve_with_downloads() self.config.handler.wait_for_blocker(solve) tasks.check(solve) master_feed = self.config.iface_cache.get_feed(native_url) assert master_feed is not None assert master_feed.implementations == {} distro_feed_url = master_feed.get_distro_feed() assert distro_feed_url is not None distro_feed = self.config.iface_cache.get_feed(distro_feed_url) assert distro_feed is not None assert len( distro_feed.implementations) == 2, distro_feed.implementations
def testAcceptKey(self): with output_suppressed(): self.child = server.handle_requests('Hello', '6FCF121BE2390E0B.gpg', '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B', 'HelloWorld.tgz') policy = Policy('http://localhost:8000/Hello', config = self.config) assert policy.need_download() sys.stdin = Reply("Y\n") try: download_and_execute(policy, ['Hello'], main = 'Missing') assert 0 except model.SafeException as ex: if "HelloWorld/Missing" not in str(ex): raise
def _check_for_updates(old_policy, verbose): from zeroinstall.injector.policy import Policy from zeroinstall.injector.config import load_config iface_cache = old_policy.config.iface_cache root_iface = iface_cache.get_interface(old_policy.root).get_name() background_config = load_config( BackgroundHandler(root_iface, old_policy.root)) policy = Policy(config=background_config, requirements=old_policy.requirements) info(_("Checking for updates to '%s' in a background process"), root_iface) if verbose: policy.handler.notify("Zero Install", _("Checking for updates to '%s'...") % root_iface, timeout=1) network_state = policy.handler.get_network_state() if network_state != _NetworkState.NM_STATE_CONNECTED: info( _("Not yet connected to network (status = %d). Sleeping for a bit..." ), network_state) import time time.sleep(120) if network_state in (_NetworkState.NM_STATE_DISCONNECTED, _NetworkState.NM_STATE_ASLEEP): info(_("Still not connected to network. Giving up.")) sys.exit(1) else: info(_("NetworkManager says we're on-line. Good!")) policy.freshness = 0 # Don't bother trying to refresh when getting the interface refresh = policy.refresh_all() # (causes confusing log messages) tasks.wait_for_blocker(refresh) # We could even download the archives here, but for now just # update the interfaces. if not policy.need_download(): if verbose: policy.handler.notify("Zero Install", _("No updates to download."), timeout=1) sys.exit(0) policy.handler.notify("Zero Install", _("Updates ready to download for '%s'.") % root_iface, timeout=1) _exec_gui(policy.root, '--refresh', '--systray') sys.exit(1)
def testDLfeed(self): self.cache_iface(foo_iface_uri, """<?xml version="1.0" ?> <interface last-modified="1110752708" uri="%s" xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> <feed src='http://example.com'/> </interface>""" % foo_iface_uri) policy = Policy(foo_iface_uri, config = self.config) policy.network_use = model.network_full policy.freshness = 0 assert policy.need_download() feed = self.config.iface_cache.get_feed(foo_iface_uri) feed.feeds = [model.Feed('/BadFeed', None, False)] logger.setLevel(logging.ERROR) assert policy.need_download() # Triggers warning logger.setLevel(logging.WARN)
def testDLfeed(self): self.cache_iface( foo_iface_uri, """<?xml version="1.0" ?> <interface last-modified="1110752708" uri="%s" xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> <feed src='http://example.com'/> </interface>""" % foo_iface_uri) policy = Policy(foo_iface_uri, config=self.config) policy.network_use = model.network_full policy.freshness = 0 assert policy.need_download() feed = self.config.iface_cache.get_feed(foo_iface_uri) feed.feeds = [model.Feed('/BadFeed', None, False)] logger.setLevel(logging.ERROR) assert policy.need_download() # Triggers warning logger.setLevel(logging.WARN)
def testAcceptKey(self): with output_suppressed(): self.child = server.handle_requests( 'Hello', '6FCF121BE2390E0B.gpg', '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B', 'HelloWorld.tgz') policy = Policy('http://localhost:8000/Hello', config=self.config) assert policy.need_download() sys.stdin = Reply("Y\n") try: download_and_execute(policy, ['Hello'], main='Missing') assert 0 except model.SafeException as ex: if "HelloWorld/Missing" not in str(ex): raise
def testRejectKey(self): with output_suppressed(): self.child = server.handle_requests('Hello', '6FCF121BE2390E0B.gpg', '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B') policy = Policy('http://localhost:8000/Hello', config = self.config) assert policy.need_download() sys.stdin = Reply("N\n") try: download_and_execute(policy, ['Hello']) assert 0 except model.SafeException as ex: if "has no usable implementations" not in str(ex): raise ex if "Not signed with a trusted key" not in str(policy.handler.ex): raise ex self.config.handler.ex = None
def testWrongSize(self): with output_suppressed(): self.child = server.handle_requests( "Hello-wrong-size", "6FCF121BE2390E0B.gpg", "/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B", "HelloWorld.tgz", ) policy = Policy("http://localhost:8000/Hello-wrong-size", config=self.config) assert policy.need_download() sys.stdin = Reply("Y\n") try: download_and_execute(policy, ["Hello"], main="Missing") assert 0 except model.SafeException, ex: if "Downloaded archive has incorrect size" not in str(ex): raise ex
def testRejectKeyXML(self): with output_suppressed(): self.child = server.handle_requests( "Hello.xml", "6FCF121BE2390E0B.gpg", "/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B" ) policy = Policy("http://example.com:8000/Hello.xml", config=self.config) assert policy.need_download() sys.stdin = Reply("N\n") try: download_and_execute(policy, ["Hello"]) assert 0 except model.SafeException, ex: if "has no usable implementations" not in str(ex): raise ex if "Not signed with a trusted key" not in str(policy.handler.ex): raise self.config.handler.ex = None
def testRejectKey(self): with output_suppressed(): self.child = server.handle_requests( 'Hello', '6FCF121BE2390E0B.gpg', '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B') policy = Policy('http://localhost:8000/Hello', config=self.config) assert policy.need_download() sys.stdin = Reply("N\n") try: download_and_execute(policy, ['Hello']) assert 0 except model.SafeException as ex: if "has no usable implementations" not in str(ex): raise ex if "Not signed with a trusted key" not in str( policy.handler.ex): raise ex self.config.handler.ex = None
def _check_for_updates(old_policy, verbose): from zeroinstall.injector.policy import Policy from zeroinstall.injector.config import load_config iface_cache = old_policy.config.iface_cache root_iface = iface_cache.get_interface(old_policy.root).get_name() background_config = load_config(BackgroundHandler(root_iface, old_policy.root)) policy = Policy(config = background_config, requirements = old_policy.requirements) info(_("Checking for updates to '%s' in a background process"), root_iface) if verbose: policy.handler.notify("Zero Install", _("Checking for updates to '%s'...") % root_iface, timeout = 1) network_state = policy.handler.get_network_state() if network_state != _NetworkState.NM_STATE_CONNECTED: info(_("Not yet connected to network (status = %d). Sleeping for a bit..."), network_state) import time time.sleep(120) if network_state in (_NetworkState.NM_STATE_DISCONNECTED, _NetworkState.NM_STATE_ASLEEP): info(_("Still not connected to network. Giving up.")) sys.exit(1) else: info(_("NetworkManager says we're on-line. Good!")) policy.freshness = 0 # Don't bother trying to refresh when getting the interface refresh = policy.refresh_all() # (causes confusing log messages) tasks.wait_for_blocker(refresh) # We could even download the archives here, but for now just # update the interfaces. if not policy.need_download(): if verbose: policy.handler.notify("Zero Install", _("No updates to download."), timeout = 1) sys.exit(0) policy.handler.notify("Zero Install", _("Updates ready to download for '%s'.") % root_iface, timeout = 1) _exec_gui(policy.root, '--refresh', '--systray') sys.exit(1)
def testNeedDL(self): self.cache_iface( foo_iface_uri, """<?xml version="1.0" ?> <interface last-modified="0" uri="%s" main='ThisBetterNotExist' xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> <implementation version='1.0' id='sha1=123'> <archive href='http://foo/foo.tgz' size='100'/> </implementation> </interface>""" % foo_iface_uri) policy = Policy(foo_iface_uri, config=self.config) policy.freshness = 0 policy.network_use = model.network_full recalculate(policy) assert policy.need_download() assert policy.ready
def testNeedDL(self): self.cache_iface(foo_iface_uri, """<?xml version="1.0" ?> <interface last-modified="0" uri="%s" main='ThisBetterNotExist' xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> <implementation version='1.0' id='sha1=123'> <archive href='http://foo/foo.tgz' size='100'/> </implementation> </interface>""" % foo_iface_uri) policy = Policy(foo_iface_uri, config = self.config) policy.freshness = 0 policy.network_use = model.network_full recalculate(policy) assert policy.need_download() assert policy.ready
def testUnknownAlg(self): self.cache_iface(foo_iface_uri, """<?xml version="1.0" ?> <interface uri="%s" xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> <implementation main='.' id='unknown=123' version='1.0'> <archive href='http://foo/foo.tgz' size='100'/> </implementation> </interface>""" % foo_iface_uri) self.config.fetcher = fetch.Fetcher(self.config) policy = Policy(foo_iface_uri, config = self.config) policy.freshness = 0 try: assert policy.need_download() download_and_execute(policy, []) except model.SafeException as ex: assert 'Unknown digest algorithm' in str(ex)
def testUnknownAlg(self): self.cache_iface( foo_iface_uri, """<?xml version="1.0" ?> <interface uri="%s" xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> <implementation main='.' id='unknown=123' version='1.0'> <archive href='http://foo/foo.tgz' size='100'/> </implementation> </interface>""" % foo_iface_uri) self.config.fetcher = fetch.Fetcher(self.config) policy = Policy(foo_iface_uri, config=self.config) policy.freshness = 0 try: assert policy.need_download() download_and_execute(policy, []) except model.SafeException as ex: assert 'Unknown digest algorithm' in str(ex)
def _check_for_updates(old_policy, verbose): from zeroinstall.injector.policy import load_config, Policy iface_cache = old_policy.config.iface_cache root_iface = iface_cache.get_interface(old_policy.root).get_name() background_config = load_config(BackgroundHandler(root_iface, old_policy.root)) policy = Policy(config = background_config, requirements = old_policy.requirements) info(_("Checking for updates to '%s' in a background process"), root_iface) if verbose: policy.handler.notify("Zero Install", _("Checking for updates to '%s'...") % root_iface, timeout = 1) network_state = policy.handler.get_network_state() if network_state != _NetworkState.NM_STATE_CONNECTED: info(_("Not yet connected to network (status = %d). Sleeping for a bit..."), network_state) import time time.sleep(120) if network_state in (_NetworkState.NM_STATE_DISCONNECTED, _NetworkState.NM_STATE_ASLEEP): info(_("Still not connected to network. Giving up.")) sys.exit(1) else: info(_("NetworkManager says we're on-line. Good!")) policy.freshness = 0 # Don't bother trying to refresh when getting the interface refresh = policy.refresh_all() # (causes confusing log messages) policy.handler.wait_for_blocker(refresh) # We could even download the archives here, but for now just # update the interfaces. if not policy.need_download(): if verbose: policy.handler.notify("Zero Install", _("No updates to download."), timeout = 1) sys.exit(0) if not policy.handler.have_actions_support(): # Can't ask the user to choose, so just notify them # In particular, Ubuntu/Jaunty doesn't support actions policy.handler.notify("Zero Install", _("Updates ready to download for '%s'.") % root_iface, timeout = 1) _exec_gui(policy.root, '--refresh', '--systray') sys.exit(1) notification_closed = tasks.Blocker("wait for notification response") def _NotificationClosed(nid, *unused): if nid != our_question: return notification_closed.trigger() def _ActionInvoked(nid, action): if nid != our_question: return if action == 'download': _exec_gui(policy.root) notification_closed.trigger() policy.handler.notification_service.connect_to_signal('NotificationClosed', _NotificationClosed) policy.handler.notification_service.connect_to_signal('ActionInvoked', _ActionInvoked) our_question = policy.handler.notify("Zero Install", _("Updates ready to download for '%s'.") % root_iface, actions = ['download', 'Download']) policy.handler.wait_for_blocker(notification_closed)
class _SolveLink(_Link): name = 'Solve' def __init__(self, feed, seed=None): _Link.__init__(self) self.force = False iface_uri = model.canonical_iface_uri(feed) self.policy = Policy(iface_uri) self.policy.solver.record_details = True if seed is not None: self.policy.network_use = seed.policy.network_use self.policy.handler = seed.policy.handler self.force = seed.force def attach(self): if self.force or not self.policy.ready: msg = _('Download feed for service %s:') % \ self.get_name() self.emit('verbose', msg) else: msg = _('Download requirements for service %s:') % \ self.get_name() self.emit('verbose', msg) return self.policy.solve_with_downloads(force=self.force) def detach(self, blocker): if self.policy.solver.ready: for iface, __ in self.policy.implementation.items(): msg = _('* %s done;') % _name(iface.uri) self.emit('verbose', msg) if self.policy.need_download(): return [_DownloadLink(self)] else: return [] zcompile = _SolveLink(www.IFACE_COMPILE, self) # at the end, we should restart current link next_links = [_SolveLink(self.policy.root, self)] failed = False need_build = False for iface, impl in self.policy.implementation.items(): if impl is not None: msg = _('* %s done;') % _name(iface.uri) self.emit('verbose', msg) continue if self._has_source(iface): msg = _('* %s needs to be built from sources;') % \ _name(iface.uri) self.emit('verbose', msg) next_links.append(_BuildLink(iface.uri, zcompile)) next_links.append(_SolveSourceLink(iface.uri, self)) need_build = True else: reason = self.policy.solver.details.get(iface) or _('Unknown') msg = _('* %s failed to resolve due to "%s";') % \ (_name(iface.uri), reason) self.emit('verbose', msg) failed = True if failed and not need_build: return None # check for 0compile at first next_links.append(zcompile) msg = _('* add %s;') % zcompile.get_name() self.emit('verbose', msg) return next_links def _has_source(self, iface): for feed in iface.feeds: if feed.machine == 'src': return True for impl in iface.implementations.values(): if impl.machine == 'src': return True return False
def get_selections(config, options, iface_uri, select_only, download_only, test_callback): """Get selections for iface_uri, according to the options passed. Will switch to GUI mode if necessary. @param options: options from OptionParser @param iface_uri: canonical URI of the interface @param select_only: return immediately even if the selected versions aren't cached @param download_only: wait for stale feeds, and display GUI button as Download, not Run @return: the selected versions, or None if the user cancels @rtype: L{selections.Selections} | None """ if options.offline: config.network_use = model.network_offline iface_cache = config.iface_cache # Try to load it as a feed. If it is a feed, it'll get cached. If not, it's a # selections document and we return immediately. maybe_selections = iface_cache.get_feed(iface_uri, selections_ok = True) if isinstance(maybe_selections, selections.Selections): if not select_only: blocker = maybe_selections.download_missing(config) if blocker: logging.info(_("Waiting for selected implementations to be downloaded...")) tasks.wait_for_blocker(blocker) return maybe_selections r = requirements.Requirements(iface_uri) r.parse_options(options) policy = Policy(config = config, requirements = r) # Note that need_download() triggers a solve if options.refresh or options.gui: # We could run immediately, but the user asked us not to can_run_immediately = False else: if select_only: # --select-only: we only care that we've made a selection, not that we've cached the implementations policy.need_download() can_run_immediately = policy.ready else: can_run_immediately = not policy.need_download() stale_feeds = [feed for feed in policy.solver.feeds_used if not os.path.isabs(feed) and # Ignore local feeds (note: file might be missing too) not feed.startswith('distribution:') and # Ignore (memory-only) PackageKit feeds iface_cache.is_stale(iface_cache.get_feed(feed), config.freshness)] if download_only and stale_feeds: can_run_immediately = False if can_run_immediately: if stale_feeds: if policy.network_use == model.network_offline: logging.debug(_("No doing background update because we are in off-line mode.")) else: # There are feeds we should update, but we can run without them. # Do the update in the background while the program is running. from zeroinstall.injector import background background.spawn_background_update(policy, options.verbose > 0) return policy.solver.selections # If the user didn't say whether to use the GUI, choose for them. if options.gui is None and os.environ.get('DISPLAY', None): options.gui = True # If we need to download anything, we might as well # refresh all the feeds first. options.refresh = True logging.info(_("Switching to GUI mode... (use --console to disable)")) if options.gui: gui_args = policy.requirements.get_as_options() if download_only: # Just changes the button's label gui_args.append('--download-only') if options.refresh: gui_args.append('--refresh') if options.verbose: gui_args.insert(0, '--verbose') if options.verbose > 1: gui_args.insert(0, '--verbose') if options.with_store: for x in options.with_store: gui_args += ['--with-store', x] if select_only: gui_args.append('--select-only') from zeroinstall import helpers sels = helpers.get_selections_gui(iface_uri, gui_args, test_callback) if not sels: return None # Aborted else: # Note: --download-only also makes us stop and download stale feeds first. downloaded = policy.solve_and_download_impls(refresh = options.refresh or download_only or False, select_only = select_only) if downloaded: tasks.wait_for_blocker(downloaded) sels = selections.Selections(policy) return sels
def get_selections(config, options, iface_uri, select_only, download_only, test_callback): """Get selections for iface_uri, according to the options passed. Will switch to GUI mode if necessary. @param options: options from OptionParser @param iface_uri: canonical URI of the interface @param select_only: return immediately even if the selected versions aren't cached @param download_only: wait for stale feeds, and display GUI button as Download, not Run @return: the selected versions, or None if the user cancels @rtype: L{selections.Selections} | None """ if options.offline: config.network_use = model.network_offline # Try to load it as a feed. If it is a feed, it'll get cached. If not, it's a # selections document and we return immediately. maybe_selections = config.iface_cache.get_feed(iface_uri, selections_ok = True) if isinstance(maybe_selections, selections.Selections): if not select_only: blocker = maybe_selections.download_missing(config) if blocker: logging.info(_("Waiting for selected implementations to be downloaded...")) config.handler.wait_for_blocker(blocker) return maybe_selections r = requirements.Requirements(iface_uri) r.parse_options(options) policy = Policy(config = config, requirements = r) # Note that need_download() triggers a solve if options.refresh or options.gui: # We could run immediately, but the user asked us not to can_run_immediately = False else: if select_only: # --select-only: we only care that we've made a selection, not that we've cached the implementations policy.need_download() can_run_immediately = policy.ready else: can_run_immediately = not policy.need_download() stale_feeds = [feed for feed in policy.solver.feeds_used if not feed.startswith('distribution:') and # Ignore (memory-only) PackageKit feeds policy.is_stale(config.iface_cache.get_feed(feed))] if download_only and stale_feeds: can_run_immediately = False if can_run_immediately: if stale_feeds: if policy.network_use == model.network_offline: logging.debug(_("No doing background update because we are in off-line mode.")) else: # There are feeds we should update, but we can run without them. # Do the update in the background while the program is running. from zeroinstall.injector import background background.spawn_background_update(policy, options.verbose > 0) return policy.solver.selections # If the user didn't say whether to use the GUI, choose for them. if options.gui is None and os.environ.get('DISPLAY', None): options.gui = True # If we need to download anything, we might as well # refresh all the feeds first. options.refresh = True logging.info(_("Switching to GUI mode... (use --console to disable)")) if options.gui: gui_args = policy.requirements.get_as_options() if download_only: # Just changes the button's label gui_args.append('--download-only') if options.refresh: gui_args.append('--refresh') if options.verbose: gui_args.insert(0, '--verbose') if options.verbose > 1: gui_args.insert(0, '--verbose') if options.with_store: for x in options.with_store: gui_args += ['--with-store', x] if select_only: gui_args.append('--select-only') from zeroinstall import helpers sels = helpers.get_selections_gui(iface_uri, gui_args, test_callback) if not sels: return None # Aborted else: # Note: --download-only also makes us stop and download stale feeds first. downloaded = policy.solve_and_download_impls(refresh = options.refresh or download_only or False, select_only = select_only) if downloaded: config.handler.wait_for_blocker(downloaded) sels = selections.Selections(policy) return sels