
- The client will be able to know if there is a package manager instance running and to follow the package manager logfiles to know what is happening within. Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com> --- plugins/kimchi/control/host.py | 1 + plugins/kimchi/model/host.py | 10 ++++++++ plugins/kimchi/swupdate.py | 54 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/plugins/kimchi/control/host.py b/plugins/kimchi/control/host.py index 0a40f1b..6c2ed43 100644 --- a/plugins/kimchi/control/host.py +++ b/plugins/kimchi/control/host.py @@ -39,6 +39,7 @@ class Host(Resource): self.packagesupdate = PackagesUpdate(self.model) self.repositories = Repositories(self.model) self.swupdate = self.generate_action_handler_task('swupdate') + self.taillogs = self.generate_action_handler_task('taillogs') self.cpuinfo = CPUInfo(self.model) @property diff --git a/plugins/kimchi/model/host.py b/plugins/kimchi/model/host.py index 23fda3b..a159f0e 100644 --- a/plugins/kimchi/model/host.py +++ b/plugins/kimchi/model/host.py @@ -128,6 +128,16 @@ class HostModel(object): self.host_info['memory'] = psutil.virtual_memory().total return self.host_info + def taillogs(self, *name): + try: + swupdate = SoftwareUpdate() + except: + raise OperationFailed('KCHPKGUPD0004E') + + taskid = add_task('/plugins/kimchi/host/taillogs', + swupdate.tailUpdateLogs, self.objstore, None) + return self.task.lookup(taskid) + def swupdate(self, *name): try: swupdate = SoftwareUpdate() diff --git a/plugins/kimchi/swupdate.py b/plugins/kimchi/swupdate.py index 4d92731..6045467 100644 --- a/plugins/kimchi/swupdate.py +++ b/plugins/kimchi/swupdate.py @@ -18,6 +18,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import fcntl +import os import subprocess import time @@ -112,6 +113,59 @@ class SoftwareUpdate(object): self._scanUpdates() return self._num2update + def tailUpdateLogs(self, cb, params): + """ + When the package manager is already running (started outside kimchi or + if wokd is restarted) we can only know what's happening by reading the + logfiles. This method acts like a 'tail -f' on the default package + manager logfile. If the logfile is not found, a simple '*' is + displayed to track progress. This will be until the process finishes. + """ + if not self._pkg_mnger.isRunning(): + return + + fd = None + try: + fd = os.open(self._pkg_mnger.logfile, os.O_RDONLY) + + # cannot open logfile, print something to let users know that the + # system is being upgrading until the package manager finishes its + # job + except (TypeError, OSError): + msgs = [] + while self._pkg_mnger.isRunning(): + msgs.append('*') + cb(''.join(msgs)) + time.sleep(1) + msgs.append('\n') + cb(''.join(msgs), True) + return + + # go to the end of logfile and starts reading, if nothing is read or + # a pattern is not found in the message just wait and retry until + # the package manager finishes + os.lseek(fd, 0, os.SEEK_END) + msgs = [] + progress = [] + while True: + read = os.read(fd, 1024) + if not read: + if not self._pkg_mnger.isRunning(): + break + + if not msgs: + progress.append('*') + cb(''.join(progress)) + + time.sleep(1) + continue + + msgs.append(read) + cb(''.join(msgs)) + + os.close(fd) + return cb(''.join(msgs), True) + def doUpdate(self, cb, params): """ Execute the update -- 1.9.1