def testFeeds(self): self.cache_iface( foo_iface_uri, """<?xml version="1.0" ?> <interface last-modified="0" uri="%s" xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> <feed src='http://bar'/> </interface>""" % foo_iface_uri) self.cache_iface( 'http://bar', """<?xml version="1.0" ?> <interface last-modified="0" uri="http://bar" xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <feed-for interface='%s'/> <name>Bar</name> <summary>Bar</summary> <description>Bar</description> <implementation version='1.0' id='sha1=123' main='dummy'> <archive href='foo' size='10'/> </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.ready foo_iface = self.config.iface_cache.get_interface(foo_iface_uri) self.assertEquals('sha1=123', policy.implementation[foo_iface].id)
def build(): # Get the chosen versions src_policy = Policy(interface.uri, src=True) src_policy.freshness = 0 src_policy.recalculate() if not src_policy.ready: raise Exception( _('Internal error: required source components not found!')) root_iface = iface_cache.iface_cache.get_interface(src_policy.root) impl = src_policy.implementation[root_iface] min_version = impl.metadata.get(XMLNS_0COMPILE + ' min-version', our_min_version) # Check the syntax is valid and the version is high enough if model.parse_version(min_version) < model.parse_version( our_min_version): min_version = our_min_version # Do the whole build-and-register-feed c = Command() c.run(("0launch", '--message', _('Download the 0compile tool, to compile the source code'), '--not-before=' + min_version, "http://0install.net/2006/interfaces/0compile.xml", 'gui', '--no-prompt', interface.uri), add_feed)
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 testFeeds(self): self.cache_iface(foo_iface_uri, """<?xml version="1.0" ?> <interface last-modified="0" uri="%s" xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> <feed src='http://bar'/> </interface>""" % foo_iface_uri) self.cache_iface('http://bar', """<?xml version="1.0" ?> <interface last-modified="0" uri="http://bar" xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <feed-for interface='%s'/> <name>Bar</name> <summary>Bar</summary> <description>Bar</description> <implementation version='1.0' id='sha1=123' main='dummy'> <archive href='foo' size='10'/> </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.ready foo_iface = self.config.iface_cache.get_interface(foo_iface_uri) self.assertEquals('sha1=123', policy.implementation[foo_iface].id)
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 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 testBackground(self, verbose=False): p = Policy('http://example.com:8000/Hello.xml', config=self.config) self.import_feed(p.root, 'Hello.xml') p.freshness = 0 p.network_use = model.network_minimal p.solver.solve(p.root, arch.get_host_architecture()) assert p.ready, p.solver.get_failure_reason() @tasks. async def choose_download(registed_cb, nid, actions): try: assert actions == ['download', 'Download'], actions registed_cb(nid, 'download') except: import traceback traceback.print_exc() yield None global ran_gui ran_gui = False old_out = sys.stdout try: sys.stdout = StringIO() self.child = server.handle_requests('Hello.xml', '6FCF121BE2390E0B.gpg') my_dbus.system_services = { "org.freedesktop.NetworkManager": { "/org/freedesktop/NetworkManager": NetworkManager() } } my_dbus.user_callback = choose_download pid = os.getpid() old_exit = os._exit def my_exit(code): # The background handler runs in the same process # as the tests, so don't let it abort. if os.getpid() == pid: raise SystemExit(code) # But, child download processes are OK old_exit(code) from zeroinstall.injector import config key_info = config.DEFAULT_KEY_LOOKUP_SERVER config.DEFAULT_KEY_LOOKUP_SERVER = None try: try: os._exit = my_exit background.spawn_background_update(p, verbose) assert False except SystemExit as ex: self.assertEquals(1, ex.code) finally: os._exit = old_exit config.DEFAULT_KEY_LOOKUP_SERVER = key_info finally: sys.stdout = old_out assert ran_gui
def _manage_feeds(options, args): from zeroinstall.injector import writer from zeroinstall.injector.handler import Handler from zeroinstall.injector.policy import Policy handler = Handler(dry_run = options.dry_run) if not args: raise UsageError() for x in args: print _("Feed '%s':") % x + '\n' x = model.canonical_iface_uri(x) policy = Policy(x, handler) if options.offline: policy.network_use = model.network_offline feed = iface_cache.get_feed(x) if policy.network_use != model.network_offline and policy.is_stale(feed): blocker = policy.fetcher.download_and_import_feed(x, iface_cache.iface_cache) print _("Downloading feed; please wait...") handler.wait_for_blocker(blocker) print _("Done") interfaces = policy.get_feed_targets(x) for i in range(len(interfaces)): feed = interfaces[i].get_feed(x) if feed: print _("%(index)d) Remove as feed for '%(uri)s'") % {'index': i + 1, 'uri': interfaces[i].uri} else: print _("%(index)d) Add as feed for '%(uri)s'") % {'index': i + 1, 'uri': interfaces[i].uri} print while True: try: i = raw_input(_('Enter a number, or CTRL-C to cancel [1]: ')).strip() except KeyboardInterrupt: print raise SafeException(_("Aborted at user request.")) if i == '': i = 1 else: try: i = int(i) except ValueError: i = 0 if i > 0 and i <= len(interfaces): break print _("Invalid number. Try again. (1 to %d)") % len(interfaces) iface = interfaces[i - 1] feed = iface.get_feed(x) if feed: iface.extra_feeds.remove(feed) else: iface.extra_feeds.append(model.Feed(x, arch = None, user_override = True)) writer.save_interface(iface) print '\n' + _("Feed list for interface '%s' is now:") % iface.get_name() if iface.feeds: for f in iface.feeds: print "- " + f.uri else: print _("(no feeds)")
def testConstraints(self): self.cache_iface('http://bar', """<?xml version="1.0" ?> <interface last-modified="1110752708" uri="http://bar" xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Bar</name> <summary>Bar</summary> <description>Bar</description> <implementation id='sha1=100' version='1.0'> <archive href='foo' size='10'/> </implementation> <implementation id='sha1=150' stability='developer' version='1.5'> <archive href='foo' size='10'/> </implementation> <implementation id='sha1=200' version='2.0'> <archive href='foo' size='10'/> </implementation> </interface>""") 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> <group main='dummy'> <requires interface='http://bar'> <version/> </requires> <implementation id='sha1=123' version='1.0'> <archive href='foo' size='10'/> </implementation> </group> </interface>""" % foo_iface_uri) policy = Policy(foo_iface_uri, config = self.config) policy.network_use = model.network_full policy.freshness = 0 #logger.setLevel(logging.DEBUG) recalculate(policy) #logger.setLevel(logging.WARN) foo_iface = self.config.iface_cache.get_interface(foo_iface_uri) bar_iface = self.config.iface_cache.get_interface('http://bar') assert policy.implementation[bar_iface].id == 'sha1=200' dep = policy.implementation[foo_iface].dependencies['http://bar'] assert len(dep.restrictions) == 1 restriction = dep.restrictions[0] restriction.before = model.parse_version('2.0') recalculate(policy) assert policy.implementation[bar_iface].id == 'sha1=100' restriction.not_before = model.parse_version('1.5') recalculate(policy) assert policy.implementation[bar_iface].id == 'sha1=150'
def testConstraints(self): self.cache_iface( 'http://bar', """<?xml version="1.0" ?> <interface last-modified="1110752708" uri="http://bar" xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Bar</name> <summary>Bar</summary> <description>Bar</description> <implementation id='sha1=100' version='1.0'> <archive href='foo' size='10'/> </implementation> <implementation id='sha1=150' stability='developer' version='1.5'> <archive href='foo' size='10'/> </implementation> <implementation id='sha1=200' version='2.0'> <archive href='foo' size='10'/> </implementation> </interface>""") 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> <group main='dummy'> <requires interface='http://bar'> <version/> </requires> <implementation id='sha1=123' version='1.0'> <archive href='foo' size='10'/> </implementation> </group> </interface>""" % foo_iface_uri) policy = Policy(foo_iface_uri, config=self.config) policy.network_use = model.network_full policy.freshness = 0 #logger.setLevel(logging.DEBUG) recalculate(policy) #logger.setLevel(logging.WARN) foo_iface = self.config.iface_cache.get_interface(foo_iface_uri) bar_iface = self.config.iface_cache.get_interface('http://bar') assert policy.implementation[bar_iface].id == 'sha1=200' dep = policy.implementation[foo_iface].dependencies['http://bar'] assert len(dep.restrictions) == 1 restriction = dep.restrictions[0] restriction.before = model.parse_version('2.0') recalculate(policy) assert policy.implementation[bar_iface].id == 'sha1=100' restriction.not_before = model.parse_version('1.5') recalculate(policy) assert policy.implementation[bar_iface].id == 'sha1=150'
def testBackground(self, verbose=False): p = Policy("http://example.com:8000/Hello.xml", config=self.config) self.import_feed(p.root, "Hello.xml") p.freshness = 0 p.network_use = model.network_minimal p.solver.solve(p.root, arch.get_host_architecture()) assert p.ready, p.solver.get_failure_reason() @tasks.async def choose_download(registed_cb, nid, actions): try: assert actions == ["download", "Download"], actions registed_cb(nid, "download") except: import traceback traceback.print_exc() yield None global ran_gui ran_gui = False old_out = sys.stdout try: sys.stdout = StringIO() self.child = server.handle_requests("Hello.xml", "6FCF121BE2390E0B.gpg") my_dbus.system_services = { "org.freedesktop.NetworkManager": {"/org/freedesktop/NetworkManager": NetworkManager()} } my_dbus.user_callback = choose_download pid = os.getpid() old_exit = os._exit def my_exit(code): # The background handler runs in the same process # as the tests, so don't let it abort. if os.getpid() == pid: raise SystemExit(code) # But, child download processes are OK old_exit(code) key_info = fetch.DEFAULT_KEY_LOOKUP_SERVER fetch.DEFAULT_KEY_LOOKUP_SERVER = None try: try: os._exit = my_exit background.spawn_background_update(p, verbose) assert False except SystemExit, ex: self.assertEquals(1, ex.code) finally: os._exit = old_exit fetch.DEFAULT_KEY_LOOKUP_SERVER = key_info finally: sys.stdout = old_out assert ran_gui
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 __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 testNoArchives(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> <implementation id='sha1=123' version='1.0' main='dummy'/> </interface>""" % foo_iface_uri) policy = Policy(foo_iface_uri, config = self.config) policy.freshness = 0 recalculate(policy) assert not policy.ready
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 testNoArchives(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> <implementation id='sha1=123' version='1.0' main='dummy'/> </interface>""" % foo_iface_uri) policy = Policy(foo_iface_uri, config=self.config) policy.freshness = 0 recalculate(policy) assert not policy.ready
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 testMirrors(self): old_out = sys.stdout try: sys.stdout = StringIO() getLogger().setLevel(ERROR) trust.trust_db.trust_key('DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') self.child = server.handle_requests(server.Give404('/Hello.xml'), 'latest.xml', '/0mirror/keys/6FCF121BE2390E0B.gpg') policy = Policy('http://example.com:8000/Hello.xml', config = self.config) self.config.feed_mirror = 'http://example.com:8000/0mirror' refreshed = policy.solve_with_downloads() policy.handler.wait_for_blocker(refreshed) assert policy.ready finally: sys.stdout = old_out
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 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 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 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 testCycle(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> <group> <requires interface='%s'/> <implementation id='sha1=123' version='1.0'> <archive href='foo' size='10'/> </implementation> </group> </interface>""" % (foo_iface_uri, foo_iface_uri)) policy = Policy(foo_iface_uri, config=self.config) policy.freshness = 0 recalculate(policy)
def testMirrors(self): old_out = sys.stdout try: sys.stdout = StringIO() getLogger().setLevel(ERROR) trust.trust_db.trust_key( 'DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') self.child = server.handle_requests( server.Give404('/Hello.xml'), 'latest.xml', '/0mirror/keys/6FCF121BE2390E0B.gpg') policy = Policy('http://example.com:8000/Hello.xml', config=self.config) self.config.feed_mirror = 'http://example.com:8000/0mirror' refreshed = policy.solve_with_downloads() policy.handler.wait_for_blocker(refreshed) assert policy.ready finally: sys.stdout = old_out
def testCycle(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> <group> <requires interface='%s'/> <implementation id='sha1=123' version='1.0'> <archive href='foo' size='10'/> </implementation> </group> </interface>""" % (foo_iface_uri, foo_iface_uri)) policy = Policy(foo_iface_uri, config = self.config) policy.freshness = 0 recalculate(policy)
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 testBestUnusable(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> <implementation id='sha1=123' version='1.0' arch='odd-weird' main='dummy'/> </interface>""" % foo_iface_uri) policy = Policy(foo_iface_uri, config = self.config) policy.network_use = model.network_offline recalculate(policy) assert not policy.ready, policy.implementation try: download_and_execute(policy, []) assert False except model.SafeException as ex: assert "has no usable implementations" in str(ex), ex
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 testBestUnusable(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> <implementation id='sha1=123' version='1.0' arch='odd-weird' main='dummy'/> </interface>""" % foo_iface_uri) policy = Policy(foo_iface_uri, config=self.config) policy.network_use = model.network_offline recalculate(policy) assert not policy.ready, policy.implementation try: download_and_execute(policy, []) assert False except model.SafeException as ex: assert "has no usable implementations" in str(ex), 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 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 testBadConfig(self): path = basedir.save_config_path(namespaces.config_site, namespaces.config_prog) glob = os.path.join(path, 'global') assert not os.path.exists(glob) stream = file(glob, 'w') stream.write('hello!') stream.close() logger.setLevel(logging.ERROR) Policy(foo_iface_uri, config=self.config) logger.setLevel(logging.WARN)
def setUp(self): www.HTTP_ROOT = '<HTTP_ROOT>' www.REPO_ROOT = '<REPO_ROOT>' for name, path in _ENVS.items(): os.environ[name] = os.path.join(_ROOT, path) if os.path.exists(os.environ['XDG_CACHE_HOME']): support.ro_rmtree(os.environ['XDG_CACHE_HOME']) shutil.rmtree(_ROOT, ignore_errors=True) for name, path in _ENVS.items(): os.makedirs(os.environ[name], mode=0700) reload(basedir) assert basedir.xdg_config_home == os.environ['XDG_CONFIG_HOME'] iface_cache.iface_cache.__init__() download._downloads = {} logger = logging.getLogger() for i in logger.handlers: logger.removeHandler(i) logging.basicConfig(filename=os.path.join(_ROOT, 'debug.log'), level=logging.DEBUG) self.logger = logging.getLogger('test') policy = Policy('') policy.network_use = model.network_full policy.freshness = 60 policy.save_config() self._child = None
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 testRecipeUnpack(self): old_out = sys.stdout try: sys.stdout = StringIO() self.child = server.handle_requests(('doubly_packed.tar')) policy = Policy(os.path.abspath('Unpack.xml'), config=self.config) try: download_and_execute(policy, []) assert False except model.SafeException, ex: if "HelloWorld/Missing" not in str(ex): raise ex finally: sys.stdout = old_out
def testSource(self): iface_cache = self.config.iface_cache foo = iface_cache.get_interface('http://foo/Binary.xml') self.import_feed(foo.uri, 'Binary.xml') foo_src = iface_cache.get_interface('http://foo/Source.xml') self.import_feed(foo_src.uri, 'Source.xml') compiler = iface_cache.get_interface('http://foo/Compiler.xml') self.import_feed(compiler.uri, 'Compiler.xml') self.config.freshness = 0 self.config.network_use = model.network_full p = Policy('http://foo/Binary.xml', config = self.config) tasks.wait_for_blocker(p.solve_with_downloads()) assert p.implementation[foo].id == 'sha1=123' # Now ask for source instead p.requirements.source = True p.requirements.command = 'compile' tasks.wait_for_blocker(p.solve_with_downloads()) assert p.solver.ready, p.solver.get_failure_reason() assert p.implementation[foo].id == 'sha1=234' # The source assert p.implementation[compiler].id == 'sha1=345' # A binary needed to compile it
def testRecipeFailure(self): old_out = sys.stdout try: sys.stdout = StringIO() self.child = server.handle_requests('*') policy = Policy(os.path.abspath('Recipe.xml'), config=self.config) try: download_and_execute(policy, []) assert False except download.DownloadError as ex: if "Connection" not in str(ex): raise finally: sys.stdout = old_out
def testSource(self): iface_cache = self.config.iface_cache foo = iface_cache.get_interface('http://foo/Binary.xml') self.import_feed(foo.uri, 'Binary.xml') foo_src = iface_cache.get_interface('http://foo/Source.xml') self.import_feed(foo_src.uri, 'Source.xml') compiler = iface_cache.get_interface('http://foo/Compiler.xml') self.import_feed(compiler.uri, 'Compiler.xml') self.config.freshness = 0 self.config.network_use = model.network_full p = Policy('http://foo/Binary.xml', config=self.config) tasks.wait_for_blocker(p.solve_with_downloads()) assert p.implementation[foo].id == 'sha1=123' # Now ask for source instead p.requirements.source = True p.requirements.command = 'compile' tasks.wait_for_blocker(p.solve_with_downloads()) assert p.solver.ready, p.solver.get_failure_reason() assert p.implementation[foo].id == 'sha1=234' # The source assert p.implementation[ compiler].id == 'sha1=345' # A binary needed to compile it
def testRecipe(self): old_out = sys.stdout try: sys.stdout = StringIO() self.child = server.handle_requests( ('HelloWorld.tar.bz2', 'dummy_1-1_all.deb')) policy = Policy(os.path.abspath('Recipe.xml'), config=self.config) try: download_and_execute(policy, []) assert False except model.SafeException as ex: if "HelloWorld/Missing" not in str(ex): raise ex finally: sys.stdout = old_out
def testAbsMain(self): tmp = tempfile.NamedTemporaryFile(prefix = 'test-') tmp.write( """<?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> <group main='/bin/sh'> <implementation id='.' version='1'/> </group> </interface>""" % foo_iface_uri) tmp.flush() policy = Policy(tmp.name, config = self.config) try: downloaded = policy.solve_and_download_impls() if downloaded: policy.handler.wait_for_blocker(downloaded) run.execute_selections(policy.solver.selections, [], stores = policy.config.stores) assert False except SafeException, ex: assert 'Command path must be relative' in str(ex), ex
def testAbsMain(self): tmp = tempfile.NamedTemporaryFile(prefix='test-') tmp.write("""<?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> <group main='/bin/sh'> <implementation id='.' version='1'/> </group> </interface>""" % foo_iface_uri) tmp.flush() policy = Policy(tmp.name, config=self.config) try: downloaded = policy.solve_and_download_impls() if downloaded: policy.handler.wait_for_blocker(downloaded) run.execute_selections(policy.solver.selections, [], stores=policy.config.stores) assert False except SafeException as ex: assert 'Command path must be relative' in str(ex), ex
def testAutopackage(self): old_out = sys.stdout try: sys.stdout = StringIO() self.child = server.handle_requests('HelloWorld.autopackage') policy = Policy(os.path.abspath('Autopackage.xml'), config=self.config) try: download_and_execute(policy, []) assert False except model.SafeException as ex: if "HelloWorld/Missing" not in str(ex): raise finally: sys.stdout = old_out
def testNoMain(self): tmp = tempfile.NamedTemporaryFile() tmp.write("""<?xml version="1.0" ?> <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> <implementation version='1.0' id='/bin'/> </interface>""") tmp.flush() policy = Policy(tmp.name, config=self.config) try: download_and_execute(policy, ['Hello']) assert 0 except model.SafeException as ex: assert "library" in str(ex), ex tmp.close()
def testReplay(self): old_out = sys.stdout try: sys.stdout = StringIO() getLogger().setLevel(ERROR) iface = self.config.iface_cache.get_interface( 'http://example.com:8000/Hello.xml') mtime = int(os.stat('Hello-new.xml').st_mtime) self.config.iface_cache.update_feed_from_network( iface.uri, file('Hello-new.xml').read(), mtime + 10000) trust.trust_db.trust_key( 'DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') self.child = server.handle_requests( server.Give404('/Hello.xml'), 'latest.xml', '/0mirror/keys/6FCF121BE2390E0B.gpg', 'Hello.xml') policy = Policy('http://example.com:8000/Hello.xml', config=self.config) self.config.feed_mirror = 'http://example.com:8000/0mirror' # Update from mirror (should ignore out-of-date timestamp) refreshed = policy.fetcher.download_and_import_feed( iface.uri, self.config.iface_cache) policy.handler.wait_for_blocker(refreshed) # Update from upstream (should report an error) refreshed = policy.fetcher.download_and_import_feed( iface.uri, self.config.iface_cache) try: policy.handler.wait_for_blocker(refreshed) raise Exception("Should have been rejected!") except model.SafeException as ex: assert "New feed's modification time is before old version" in str( ex) # Must finish with the newest version self.assertEquals( 1235911552, self.config.iface_cache._get_signature_date(iface.uri)) finally: sys.stdout = old_out
def testSymlink(self): old_out = sys.stdout try: sys.stdout = StringIO() self.child = server.handle_requests( ('HelloWorld.tar.bz2', 'HelloSym.tgz')) policy = Policy(os.path.abspath('RecipeSymlink.xml'), config=self.config) try: download_and_execute(policy, []) assert False except model.SafeException as ex: if 'Attempt to unpack dir over symlink "HelloWorld"' not in str( ex): raise self.assertEquals( None, basedir.load_first_cache('0install.net', 'implementations', 'main')) finally: sys.stdout = old_out
def testSource(self): iface_cache = self.config.iface_cache warnings.filterwarnings("ignore", category=DeprecationWarning) foo = iface_cache.get_interface("http://foo/Binary.xml") self.import_feed(foo.uri, "Binary.xml") foo_src = iface_cache.get_interface("http://foo/Source.xml") self.import_feed(foo_src.uri, "Source.xml") compiler = iface_cache.get_interface("http://foo/Compiler.xml") self.import_feed(compiler.uri, "Compiler.xml") p = Policy("http://foo/Binary.xml", config=self.config) p.freshness = 0 p.network_use = model.network_full p.recalculate() # Deprecated assert p.implementation[foo].id == "sha1=123" # Now ask for source instead p.requirements.source = True p.requirements.command = "compile" p.recalculate() assert p.solver.ready, p.solver.get_failure_reason() assert p.implementation[foo].id == "sha1=234" # The source assert p.implementation[compiler].id == "sha1=345" # A binary needed to compile it
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 testBinding(self): local_impl = os.path.dirname(os.path.abspath(__file__)) tmp = tempfile.NamedTemporaryFile() tmp.write( """<?xml version="1.0" ?> <interface main='testautopolicy.py' xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Bar</name> <summary>Bar</summary> <description>Bar</description> <group> <requires interface='%s'> <environment name='FOO_PATH' insert='.'/> <environment name='BAR_PATH' insert='.' default='/a:/b'/> <environment name='NO_PATH' value='val'/> <environment name='XDG_DATA_DIRS' insert='.'/> </requires> <environment name='SELF_GROUP' insert='group' mode='replace'/> <implementation version='1.0' id='%s'> <environment name='SELF_IMPL' insert='impl' mode='replace'/> </implementation> </group> </interface>""" % (foo_iface_uri, local_impl)) tmp.flush() self.cache_iface(foo_iface_uri, """<?xml version="1.0" ?> <interface last-modified="0" uri="%s" 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'/> </interface>""" % foo_iface_uri) cached_impl = basedir.save_cache_path('0install.net', 'implementations', 'sha1=123') policy = Policy(tmp.name, config = self.config) policy.network_use = model.network_offline os.environ['FOO_PATH'] = "old" old, sys.stdout = sys.stdout, StringIO() try: download_and_execute(policy, ['Hello']) finally: sys.stdout = old self.assertEquals(cached_impl + '/.:old', os.environ['FOO_PATH']) self.assertEquals(cached_impl + '/.:/a:/b', os.environ['BAR_PATH']) self.assertEquals('val', os.environ['NO_PATH']) self.assertEquals(os.path.join(local_impl, 'group'), os.environ['SELF_GROUP']) self.assertEquals(os.path.join(local_impl, 'impl'), os.environ['SELF_IMPL']) del os.environ['FOO_PATH'] if 'XDG_DATA_DIRS' in os.environ: del os.environ['XDG_DATA_DIRS'] os.environ['BAR_PATH'] = '/old' old, sys.stdout = sys.stdout, StringIO() try: download_and_execute(policy, ['Hello']) finally: sys.stdout = old self.assertEquals(cached_impl + '/.', os.environ['FOO_PATH']) self.assertEquals(cached_impl + '/.:/old', os.environ['BAR_PATH']) self.assertEquals(cached_impl + '/.:/usr/local/share:/usr/share', os.environ['XDG_DATA_DIRS'])
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 handle(config, options, args, add_ok = True, remove_ok = False): if options.offline: config.network_use = model.network_offline if len(args) == 2: iface = config.iface_cache.get_interface(model.canonical_iface_uri(args[0])) feed_url = args[1] if find_feed_import(iface, feed_url): raise SafeException(_('Interface %(interface)s already has feed %(feed)s') % {'interface': iface.uri, 'feed': feed_url}) feed = config.iface_cache.get_feed(feed_url) if not feed: blocker = config.fetcher.download_and_import_feed(feed_url, config.iface_cache) tasks.wait_for_blocker(blocker) iface.extra_feeds.append(model.Feed(feed_url, arch = None, user_override = True)) writer.save_interface(iface) return elif len(args) != 1: raise UsageError() x = args[0] print _("Feed '%s':") % x + '\n' x = model.canonical_iface_uri(x) policy = Policy(x, config = config) feed = config.iface_cache.get_feed(x) if policy.network_use != model.network_offline and policy.is_stale(feed): blocker = config.fetcher.download_and_import_feed(x, config.iface_cache) tasks.wait_for_blocker(blocker) candidate_interfaces = policy.get_feed_targets(x) assert candidate_interfaces interfaces = [] for i in range(len(candidate_interfaces)): iface = candidate_interfaces[i] if find_feed_import(iface, x): if remove_ok: print _("%(index)d) Remove as feed for '%(uri)s'") % {'index': i + 1, 'uri': iface.uri} interfaces.append(iface) else: if add_ok: print _("%(index)d) Add as feed for '%(uri)s'") % {'index': i + 1, 'uri': iface.uri} interfaces.append(iface) if not interfaces: if remove_ok: raise SafeException(_("%(feed)s is not registered as a feed for %(interface)s") % {'feed': x, 'interface': candidate_interfaces[0]}) else: raise SafeException(_("%(feed)s already registered as a feed for %(interface)s") % {'feed': x, 'interface': candidate_interfaces[0]}) print while True: try: i = raw_input(_('Enter a number, or CTRL-C to cancel [1]: ')).strip() except KeyboardInterrupt: print raise SafeException(_("Aborted at user request.")) if i == '': i = 1 else: try: i = int(i) except ValueError: i = 0 if i > 0 and i <= len(interfaces): break print _("Invalid number. Try again. (1 to %d)") % len(interfaces) iface = interfaces[i - 1] feed_import = find_feed_import(iface, x) if feed_import: iface.extra_feeds.remove(feed_import) else: iface.extra_feeds.append(model.Feed(x, arch = None, user_override = True)) writer.save_interface(iface) print '\n' + _("Feed list for interface '%s' is now:") % iface.get_name() if iface.extra_feeds: for f in iface.extra_feeds: print "- " + f.uri else: print _("(no feeds)")
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)
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