From 142e015192e7c4f97664a08d50753073106a689f Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Fri, 22 Aug 2008 05:11:47 +0200 Subject: Add DpkgInstallProgress from the GTK GDebi interface to the progress package. --- apt/progress.py | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'apt/progress.py') diff --git a/apt/progress.py b/apt/progress.py index bb1bce35..ff877ff8 100644 --- a/apt/progress.py +++ b/apt/progress.py @@ -233,6 +233,89 @@ class CdromProgress: def changeCdrom(self): pass + +class DpkgInstallProgress(object): + def __init__(self, debfile, status, progress, term, expander): + self.debfile = debfile + self.status = status + self.progress = progress + self.term = term + self.term_expander = expander + self.time_last_update = time.time() + self.term_expander.set_expanded(False) + def commit(self): + def finish_dpkg(term, pid, status, lock): + " helper " + self.exitstatus = posix.WEXITSTATUS(status) + #print "dpkg finished %s %s" % (pid,status) + #print "exit status: %s" % self.exitstatus + #print "was signaled %s" % posix.WIFSIGNALED(status) + lock.release() + + # get a lock + lock = thread.allocate_lock() + lock.acquire() + + # ui + self.status.set_markup(""+_("Installing '%s'...") % \ + os.path.basename(self.debfile)+"") + self.progress.pulse() + self.progress.set_text("") + + # prepare reading the pipe + (readfd, writefd) = os.pipe() + fcntl.fcntl(readfd, fcntl.F_SETFL,os.O_NONBLOCK) + #print "fds (%i,%i)" % (readfd,writefd) + + # the command + cmd = "/usr/bin/dpkg" + argv = [cmd,"--status-fd", "%s"%writefd, "-i", self.debfile] + env = ["VTE_PTY_KEEP_FD=%s"% writefd, + "DEBIAN_FRONTEND=gnome", + "APT_LISTCHANGES_FRONTEND=gtk"] + #print cmd + #print argv + #print env + #print self.term + + # prepare for the fork + reaper = vte.reaper_get() + signal_id = reaper.connect("child-exited", finish_dpkg, lock) + pid = self.term.fork_command(command=cmd, argv=argv, envv=env) + read = "" + while lock.locked(): + while True: + try: + read += os.read(readfd,1) + except OSError, (errno,errstr): + # resource temporarly unavailable is ignored + if errno != 11: + print errstr + break + self.time_last_update = time.time() + if read.endswith("\n"): + statusl = string.split(read, ":") + if len(statusl) < 3: + print "got garbage from dpkg: '%s'" % read + read = "" + break + status = statusl[2].strip() + #print status + if status == "error" or status == "conffile-prompt": + self.term_expander.set_expanded(True) + read = "" + self.progress.pulse() + while gtk.events_pending(): + gtk.main_iteration() + time.sleep(0.2) + # if the terminal has not reacted for some time, do something + if (not self.term_expander.get_expanded() and + (self.time_last_update + GDEBI_TERMINAL_TIMEOUT) < time.time()): + self.term_expander.set_expanded(True) + self.progress.set_fraction(1.0) + reaper.disconnect(signal_id) + + # module test code if __name__ == "__main__": import apt_pkg -- cgit v1.2.3 From 5ea022079850f3d7ab2411cf3f150435f140fdfe Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Fri, 22 Aug 2008 06:11:16 +0200 Subject: Make DpkgInstallProgress an inheritance of InstallProgress --- apt/dpkg.py | 13 +++++++ apt/progress.py | 105 ++++++++++++++++++++------------------------------------ 2 files changed, 51 insertions(+), 67 deletions(-) (limited to 'apt/progress.py') diff --git a/apt/dpkg.py b/apt/dpkg.py index 7f4341f3..7ebc551f 100644 --- a/apt/dpkg.py +++ b/apt/dpkg.py @@ -29,6 +29,7 @@ import sys import os from gettext import gettext as _ from cache import Cache +from progress import DpkgInstallProgress class DebPackage(object): debug = 0 @@ -397,6 +398,13 @@ class DebPackage(object): if level <= self.debug: print >> sys.stderr, msg + def install(self, installProgress=None): + """ Install the package """ + if installProgress == None: + res = os.system("/usr/sbin/dpkg -i %s" % self.file) + else: + res = installProgress.run(self.file) + return res class DscSrcPackage(DebPackage): def __init__(self, cache, file=None): @@ -468,6 +476,10 @@ if __name__ == "__main__": print "missing deps: %s" % d.missingDeps print d.requiredChanges + print "Installing ..." + ret = d.install(DpkgInstallProgress()) + print ret + #s = DscSrcPackage(cache, "../tests/3ddesktop_0.2.9-6.dsc") #s.checkDep() #print "Missing deps: ",s.missingDeps @@ -477,3 +489,4 @@ if __name__ == "__main__": d = "libc6 (>= 2.3.2), libaio (>= 0.3.96) | libaio1 (>= 0.3.96)" print s._satisfyDepends(apt_pkg.ParseDepends(d)) + diff --git a/apt/progress.py b/apt/progress.py index ff877ff8..87ccb03b 100644 --- a/apt/progress.py +++ b/apt/progress.py @@ -234,87 +234,58 @@ class CdromProgress: pass -class DpkgInstallProgress(object): - def __init__(self, debfile, status, progress, term, expander): +class DpkgInstallProgress(InstallProgress): + """ + Progress handler for a local Debian package installation + """ + def run(self, debfile): + """ + Start installing the given Debian package + """ self.debfile = debfile - self.status = status - self.progress = progress - self.term = term - self.term_expander = expander - self.time_last_update = time.time() - self.term_expander.set_expanded(False) - def commit(self): - def finish_dpkg(term, pid, status, lock): - " helper " - self.exitstatus = posix.WEXITSTATUS(status) - #print "dpkg finished %s %s" % (pid,status) - #print "exit status: %s" % self.exitstatus - #print "was signaled %s" % posix.WIFSIGNALED(status) - lock.release() - - # get a lock - lock = thread.allocate_lock() - lock.acquire() - - # ui - self.status.set_markup(""+_("Installing '%s'...") % \ - os.path.basename(self.debfile)+"") - self.progress.pulse() - self.progress.set_text("") - - # prepare reading the pipe - (readfd, writefd) = os.pipe() - fcntl.fcntl(readfd, fcntl.F_SETFL,os.O_NONBLOCK) - #print "fds (%i,%i)" % (readfd,writefd) - - # the command - cmd = "/usr/bin/dpkg" - argv = [cmd,"--status-fd", "%s"%writefd, "-i", self.debfile] - env = ["VTE_PTY_KEEP_FD=%s"% writefd, - "DEBIAN_FRONTEND=gnome", - "APT_LISTCHANGES_FRONTEND=gtk"] - #print cmd - #print argv - #print env - #print self.term + self.debname = os.path.basename(debfile).split("_")[0] + pid = self.fork() + if pid == 0: + # child + res = os.system("/usr/bin/dpkg --status-fd %s -i %s" % \ + (self.writefd, self.debfile)) + os._exit(res) + self.child_pid = pid + res = self.waitChild() + return res - # prepare for the fork - reaper = vte.reaper_get() - signal_id = reaper.connect("child-exited", finish_dpkg, lock) - pid = self.term.fork_command(command=cmd, argv=argv, envv=env) - read = "" - while lock.locked(): + def updateInterface(self): + """ + Process status messages from dpkg + """ + if self.statusfd != None: while True: try: - read += os.read(readfd,1) + self.read += os.read(self.statusfd.fileno(),1) except OSError, (errno,errstr): # resource temporarly unavailable is ignored if errno != 11: print errstr break - self.time_last_update = time.time() - if read.endswith("\n"): - statusl = string.split(read, ":") + if self.read.endswith("\n"): + statusl = string.split(self.read, ":") if len(statusl) < 3: print "got garbage from dpkg: '%s'" % read - read = "" + self.read = "" break status = statusl[2].strip() #print status - if status == "error" or status == "conffile-prompt": - self.term_expander.set_expanded(True) - read = "" - self.progress.pulse() - while gtk.events_pending(): - gtk.main_iteration() - time.sleep(0.2) - # if the terminal has not reacted for some time, do something - if (not self.term_expander.get_expanded() and - (self.time_last_update + GDEBI_TERMINAL_TIMEOUT) < time.time()): - self.term_expander.set_expanded(True) - self.progress.set_fraction(1.0) - reaper.disconnect(signal_id) - + if status == "error": + self.error(self.debname, status) + elif status == "conffile-prompt": + # we get a string like this: + # 'current-conffile' 'new-conffile' useredited distedited + match = re.compile("\s*\'(.*)\'\s*\'(.*)\'.*").match(status_str) + if match: + self.conffile(match.group(1), match.group(2)) + else: + self.status = status + self.read = "" # module test code if __name__ == "__main__": -- cgit v1.2.3 From a39a102e437702e7cd1c3f314e507d6b0d466eb5 Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Fri, 22 Aug 2008 06:11:52 +0200 Subject: Fix: os._exit does not send the exit status the main process --- apt/progress.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt/progress.py') diff --git a/apt/progress.py b/apt/progress.py index 87ccb03b..2ef100a8 100644 --- a/apt/progress.py +++ b/apt/progress.py @@ -214,7 +214,7 @@ class InstallProgress(DumbInstallProgress): if pid == 0: # child res = pm.DoInstall(self.writefd) - os._exit(res) + os.exit(res) self.child_pid = pid res = self.waitChild() return res @@ -249,7 +249,7 @@ class DpkgInstallProgress(InstallProgress): # child res = os.system("/usr/bin/dpkg --status-fd %s -i %s" % \ (self.writefd, self.debfile)) - os._exit(res) + os.exit(res) self.child_pid = pid res = self.waitChild() return res -- cgit v1.2.3 From e671440114f46b0c6a961cd995a0b7d8bfb3f2ba Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Sun, 24 Aug 2008 21:39:38 +0200 Subject: Revert the os._exit call in the child of the progress --- apt/progress.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt/progress.py') diff --git a/apt/progress.py b/apt/progress.py index 2ef100a8..09a3fb06 100644 --- a/apt/progress.py +++ b/apt/progress.py @@ -214,7 +214,7 @@ class InstallProgress(DumbInstallProgress): if pid == 0: # child res = pm.DoInstall(self.writefd) - os.exit(res) + os._exit(res) self.child_pid = pid res = self.waitChild() return res @@ -249,7 +249,7 @@ class DpkgInstallProgress(InstallProgress): # child res = os.system("/usr/bin/dpkg --status-fd %s -i %s" % \ (self.writefd, self.debfile)) - os.exit(res) + os._exit(os.WEXITSTATUS(res)) self.child_pid = pid res = self.waitChild() return res -- cgit v1.2.3