Example #1
0
	def spawn_build(self, iface_name):
		assert self.child is None

		self.details.insert_at_end_and_scroll('Building %s\n' % iface_name, 'heading')

		# Group all the child processes so we can kill them easily
		def become_group_leader():
			os.setpgid(0, 0)
		devnull = os.open(os.devnull, os.O_RDONLY)
		try:
			self.child = subprocess.Popen([sys.executable, '-u', sys.argv[0], 'build'],
							stdin = devnull,
							stdout = subprocess.PIPE, stderr = subprocess.STDOUT,
							preexec_fn = become_group_leader)
		finally:
			os.close(devnull)

		import codecs
		decoder = codecs.getincrementaldecoder('utf-8')(errors = 'replace')

		while True:
			yield tasks.InputBlocker(self.child.stdout, 'output from child')
			got = os.read(self.child.stdout.fileno(), 100)
			chars = decoder.decode(got, final = not got)
			self.details.insert_at_end_and_scroll(chars)
			if not got: break

		self.child.wait()
		code = self.child.returncode
		self.child = None
		if code:
			self.details.insert_at_end_and_scroll('Build process exited with error status %d\n' % code, 'error')
			raise SafeException('Build process exited with error status %d' % code)
		self.details.insert_at_end_and_scroll('Build completed successfully\n', 'heading')
Example #2
0
 def handle_events():
     while True:
         logger.debug("waiting for stdin")
         yield tasks.InputBlocker(stdin, 'wait for commands from master')
         logger.debug("reading JSON")
         message = recv_json()
         logger.debug("got %s", message)
         if message is None: break
         handle_message(config, options, message)
Example #3
0
    def testInputBlocker(self):
        r, w = os.pipe()
        b = tasks.InputBlocker(r, "waiting for input")
        t = tasks.TimeoutBlocker(0.01, "timeout")

        @tasks. async
        def run():
            yield b, t
            assert t.happened
            assert not b.happened

            os.write(w, b"!")

            yield b
            assert b.happened

            os.close(r)
            os.close(w)

        tasks.wait_for_blocker(run())
Example #4
0
	def confirm_import_feed(self, pending, valid_sigs):
		"""Sub-classes should override this method to interact with the user about new feeds.
		If multiple feeds need confirmation, L{trust.TrustMgr.confirm_keys} will only invoke one instance of this
		method at a time.
		@param pending: the new feed to be imported
		@type pending: L{PendingFeed}
		@param valid_sigs: maps signatures to a list of fetchers collecting information about the key
		@type valid_sigs: {L{gpg.ValidSig} : L{fetch.KeyInfoFetcher}}
		@since: 0.42"""
		from zeroinstall.injector import trust

		assert valid_sigs

		domain = trust.domain_from_url(pending.url)

		# Ask on stderr, because we may be writing XML to stdout
		print >>sys.stderr, _("Feed: %s") % pending.url
		print >>sys.stderr, _("The feed is correctly signed with the following keys:")
		for x in valid_sigs:
			print >>sys.stderr, "-", x

		def text(parent):
			text = ""
			for node in parent.childNodes:
				if node.nodeType == node.TEXT_NODE:
					text = text + node.data
			return text

		shown = set()
		key_info_fetchers = valid_sigs.values()
		while key_info_fetchers:
			old_kfs = key_info_fetchers
			key_info_fetchers = []
			for kf in old_kfs:
				infos = set(kf.info) - shown
				if infos:
					if len(valid_sigs) > 1:
						print "%s: " % kf.fingerprint
					for key_info in infos:
						print >>sys.stderr, "-", text(key_info)
						shown.add(key_info)
				if kf.blocker:
					key_info_fetchers.append(kf)
			if key_info_fetchers:
				for kf in key_info_fetchers: print >>sys.stderr, kf.status
				stdin = tasks.InputBlocker(0, 'console')
				blockers = [kf.blocker for kf in key_info_fetchers] + [stdin]
				yield blockers
				for b in blockers:
					try:
						tasks.check(b)
					except Exception as ex:
						warn(_("Failed to get key info: %s"), ex)
				if stdin.happened:
					print >>sys.stderr, _("Skipping remaining key lookups due to input from user")
					break
		if not shown:
			print >>sys.stderr, _("Warning: Nothing known about this key!")

		if len(valid_sigs) == 1:
			print >>sys.stderr, _("Do you want to trust this key to sign feeds from '%s'?") % domain
		else:
			print >>sys.stderr, _("Do you want to trust all of these keys to sign feeds from '%s'?") % domain
		while True:
			print >>sys.stderr, _("Trust [Y/N] "),
			i = raw_input()
			if not i: continue
			if i in 'Nn':
				raise NoTrustedKeys(_('Not signed with a trusted key'))
			if i in 'Yy':
				break
		for key in valid_sigs:
			print >>sys.stderr, _("Trusting %(key_fingerprint)s for %(domain)s") % {'key_fingerprint': key.fingerprint, 'domain': domain}
			trust.trust_db.trust_key(key.fingerprint, domain)
Example #5
0
    def confirm_import_feed(self, pending, valid_sigs):
        """
        verify the feed
        """
        from zeroinstall.injector import trust

        assert valid_sigs

        domain = trust.domain_from_url(pending.url)

        # Ask on stderr, because we may be writing XML to stdout
        print "Feed: %s" % pending.url
        print "The feed is correctly signed with the following keys:"
        for x in valid_sigs:
            print "-", x

        def text(parent):
            text = ""
            for node in parent.childNodes:
                if node.nodeType == node.TEXT_NODE:
                    text = text + node.data
            return text

        shown = set()
        key_info_fetchers = valid_sigs.values()
        while key_info_fetchers:
            old_kfs = key_info_fetchers
            key_info_fetchers = []
            for kf in old_kfs:
                infos = set(kf.info) - shown
                if infos:
                    if len(valid_sigs) > 1:
                        print("%s: " % kf.fingerprint)
                    for key_info in infos:
                        print("-", text(key_info))
                        shown.add(key_info)
                if kf.blocker:
                    key_info_fetchers.append(kf)
            if key_info_fetchers:
                for kf in key_info_fetchers:
                    print(kf.status)
                stdin = tasks.InputBlocker(0, 'console')
                blockers = [kf.blocker for kf in key_info_fetchers] + [stdin]
                yield blockers
                for b in blockers:
                    try:
                        tasks.check(b)
                    except Exception as ex:
                        warn(_("Failed to get key info: %s"), ex)
                if stdin.happened:
                    print(
                        "Skipping remaining key lookups due to input from user"
                    )
                    break

        for key in valid_sigs:
            print("Trusting %(key_fingerprint)s for %(domain)s") % {
                'key_fingerprint': key.fingerprint,
                'domain': domain
            }
            trust.trust_db.trust_key(key.fingerprint, domain)
    def _do_download(self):
        """Will trigger L{downloaded} when done (on success or failure)."""
        self.errors = ''

        # Can't use fork here, because Windows doesn't have it
        assert self.child is None, self.child
        child_args = [sys.executable, '-u', __file__, self.url]
        if self.modification_time: child_args.append(self.modification_time)
        self.child = subprocess.Popen(child_args,
                                      stderr=subprocess.PIPE,
                                      stdout=self.tempfile)

        self.status = download_fetching

        # Wait for child to exit, collecting error output as we go

        while True:
            yield tasks.InputBlocker(self.child.stderr,
                                     "read data from " + self.url)

            data = os.read(self.child.stderr.fileno(), 100)
            if not data:
                break
            self.errors += data

        # Download is complete...

        assert self.status is download_fetching
        assert self.tempfile is not None
        assert self.child is not None

        status = self.child.wait()
        self.child = None

        errors = self.errors
        self.errors = None

        if status == RESULT_NOT_MODIFIED:
            debug("%s not modified", self.url)
            self.tempfile = None
            self.unmodified = True
            self.status = download_complete
            self._final_total_size = 0
            self.downloaded.trigger()
            return

        if status and not self.aborted_by_user and not errors:
            errors = _('Download process exited with error status '
                       'code %s') % hex(status)

        self._final_total_size = self.get_bytes_downloaded_so_far()

        stream = self.tempfile
        self.tempfile = None

        try:
            if self.aborted_by_user:
                raise DownloadAborted(errors)

            if errors:
                raise DownloadError(errors.strip())

            # Check that the download has the correct size, if we know what it should be.
            if self.expected_size is not None:
                size = os.fstat(stream.fileno()).st_size
                if size != self.expected_size:
                    raise SafeException(
                        _('Downloaded archive has incorrect size.\n'
                          'URL: %(url)s\n'
                          'Expected: %(expected_size)d bytes\n'
                          'Received: %(size)d bytes') % {
                              'url': self.url,
                              'expected_size': self.expected_size,
                              'size': size
                          })
        except:
            self.status = download_failed
            _unused, ex, tb = sys.exc_info()
            self.downloaded.trigger(exception=(ex, tb))
        else:
            self.status = download_complete
            self.downloaded.trigger()
    def confirm_import_feed(self, pending, valid_sigs):
        """Sub-classes should override this method to interact with the user about new feeds.
		If multiple feeds need confirmation, L{confirm_keys} will only invoke one instance of this
		method at a time.
		@param pending: the new feed to be imported
		@type pending: L{PendingFeed}
		@param valid_sigs: maps signatures to a list of fetchers collecting information about the key
		@type valid_sigs: {L{gpg.ValidSig} : L{fetch.KeyInfoFetcher}}
		@since: 0.42
		@see: L{confirm_keys}"""
        from zeroinstall.injector import trust

        assert valid_sigs

        domain = trust.domain_from_url(pending.url)

        # Ask on stderr, because we may be writing XML to stdout
        print >> sys.stderr, _("Feed: %s") % pending.url
        print >> sys.stderr, _(
            "The feed is correctly signed with the following keys:")
        for x in valid_sigs:
            print >> sys.stderr, "-", x

        def text(parent):
            text = ""
            for node in parent.childNodes:
                if node.nodeType == node.TEXT_NODE:
                    text = text + node.data
            return text

        shown = set()
        key_info_fetchers = valid_sigs.values()
        while key_info_fetchers:
            old_kfs = key_info_fetchers
            key_info_fetchers = []
            for kf in old_kfs:
                infos = set(kf.info) - shown
                if infos:
                    if len(valid_sigs) > 1:
                        print "%s: " % kf.fingerprint
                    for info in infos:
                        print >> sys.stderr, "-", text(info)
                        shown.add(info)
                if kf.blocker:
                    key_info_fetchers.append(kf)
            if key_info_fetchers:
                for kf in key_info_fetchers:
                    print >> sys.stderr, kf.status
                stdin = tasks.InputBlocker(0, 'console')
                blockers = [kf.blocker for kf in key_info_fetchers] + [stdin]
                yield blockers
                for b in blockers:
                    try:
                        tasks.check(b)
                    except Exception, ex:
                        warn(_("Failed to get key info: %s"), ex)
                if stdin.happened:
                    print >> sys.stderr, _(
                        "Skipping remaining key lookups due to input from user"
                    )
                    break