[CVS] RPM: mancoosi/framework/ rpmtest.py

2011-04-13 Thread Jeff Johnson
  RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  

  Server: rpm5.org Name:   Jeff Johnson
  Root:   /v/rpm/cvs   Email:  j...@rpm5.org
  Module: mancoosi Date:   13-Apr-2011 13:30:25
  Branch: HEAD Handle: 2011041311302500

  Modified files:
mancoosi/framework  rpmtest.py

  Log:
- sanity.

  Summary:
RevisionChanges Path
1.6 +672 -231   mancoosi/framework/rpmtest.py
  

  patch -p0 '@@ .'
  Index: mancoosi/framework/rpmtest.py
  
  $ cvs diff -u -r1.5 -r1.6 rpmtest.py
  --- mancoosi/framework/rpmtest.py 5 Apr 2011 11:07:57 -   1.5
  +++ mancoosi/framework/rpmtest.py 13 Apr 2011 11:30:25 -  1.6
  @@ -15,26 +15,40 @@
   import subprocess
   import csvwriter
   
  +from copy import deepcopy
   from termcolor import colored
   
   # Globals
   
  -initial_contents = {}  # PKGNAME: [(FILE, mtime),...]
  -initial_versions = {}  # PKGNAME: (NEVRA, INSTALLTID)
  +#initial_versions = {}  # PKGNAME: (NVRA, INSTALLTID)
  +
  +# pkg_up_contents = {}
  +# pkg_up_versions = {}
  +# current_killtime = 0
  +# rollback_list = []
  +# upgrade_list = []
  +# sgl_pkg_NEVRA = []
  +# mainrelease_dir = './repo/cm14-main-release/'
  +# rpm_version = 0
   
   bin_rpm =/bin/rpm
   var_lib_rpm ='/var/lib/rpm/'
   usr_bin_dbrecover =  '/usr/bin/db_recover'
   usr_bin_dbstat = '/usr/bin/db_stat'
   
  +qf_NVRA =--qf=%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}
  +qf_NEV = --qf='%{NAME}-%{EPOCH}:%{VERSION}'
  +qf_NEVR =--qf='%{NAME}-%{EPOCH}:%{VERSION}-%{RELEASE}'
  +qf_INSTALLTID =  --qf='%{INSTALLTID}'
  +
  +# -- Careful: E:V:R not E:V-R
  +qf_EVR = --qf='%{EPOCH}:%{VERSION}:%{RELEASE}'
  +
   class Uut:
  -def __init__(self, pkgset, niters=10, maxdelay=3.0, **kwargs):
  -self.pkgset = pkgset
  - self.npkgs = len(self.pkgset)
  -self.pkgs = [p for (p, fn) in pkgset]
  - print 'pkgs: ' + str(self.pkgs)
  -self.rpms = [fn for (p, fn) in pkgset]
  - print 'rpms: ' + str(self.rpms)
  +def __init__(self, pkgstr, pkgdir, niters=10, maxdelay=3.0, **kwargs):
  +
  + self.pkgstr = pkgstr
  + self.pkgdir = pkgdir
if niters:
self.niters = niters
if maxdelay:
  @@ -43,26 +57,94 @@
self.query_maxdelay = maxdelay
self.verify_maxdelay = maxdelay
self.install_maxdelay = maxdelay
  +
  + self.contents = {}  # PKGNAME: [(FILE,mtime), ...]
  + self.initial_sizes = {} # PKGNAME: (NVRA, fileSize(file))
  +self.to_preinstall = []
  +self.to_install = []
  +
  + # Build a package set by globbing the pkgstr CSV list
  +self.ts = rpm.TransactionSet()
  +for pkgname in self.pkgstr.split(','):
  +pat = self.pkgdir + os.path.sep + pkgname + '-'
  +if string.find(pkgname, '-')  0:
  +pat += '[0-9]'
  +pat += '*.rpm'
  +flist = glob.glob(pat)
  +for file in flist:
  + NVRA = self.pkgNVRA(file)
  +if NVRA not in self.initial_sizes.keys():
  +self.contents[NVRA] = [(f, fileTimestamp(f))
  +for f in listPkgContent(self, NVRA)]
  +self.initial_sizes[NVRA] = fileSize(file)
  +self.to_install.append((NVRA, file))
  +del self.ts
   self.ts = None
  +
  + # Initialize other items from the package set
  +self.pkgset = self.to_install
  + self.npkgs = len(self.pkgset)
  +self.pkgs = [p for (p, fn) in self.pkgset]
  +self.rpms = [fn for (p, fn) in self.pkgset]
  + self.rpm_version = self.getVersion()
  +
   self.killtimes = []
  +# pkg_kill_times = {} # {pkgname, killtimes[]}
  + self.total_kill_time = 0
  +
  + self.success_cases_fs = {}
  + self.failure_cases_fs = {}
  +self.num_fs_sgl_pkg_failures = {}
  +self.num_fs_sgl_pkg_successes = {}
  +
  +# success_cases = {}
  +# failure_cases = {}
  +# pkg_upgraded = {}
  +# pkg_not_upgraded = {}
  +# num_pkgs_upgraded = 0
  +# num_pkgs_not_upgraded = 0
  +
  +# num_iters_pkg_upgrade = 100
  +# mpl_pkg_ud = './mpl_pkg/updates/'
  +# mpl_pkg_bd = './mpl_pkg/baseline/'
  +
  +# num_iters_pkg_upgrade = 10
  +# fs_bd = './fs_pkg/baseline/'
  +# fs_ud = './fs_pkg/updates/'
  +
  +# num_iters_pkg_upgrade = 10
  +# uni_bd = './uni_pkg/baseline/'
  +# uni_ud = './uni_pkg/updates/'
  +
  +# num_iters_pkg_upgrade = 25
  +# sgl_pkg_ud = './sgl_pkg/updates/'
  +# sgl_pkg_bd = './sgl_pkg/baseline/'
   
self.stats = {}
   self.stats['tests_run'] = 0
  

[CVS] RPM: mancoosi/framework/ rpmtest.py

2011-04-05 Thread Jeff Johnson
  RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  

  Server: rpm5.org Name:   Jeff Johnson
  Root:   /v/rpm/cvs   Email:  j...@rpm5.org
  Module: mancoosi Date:   05-Apr-2011 13:07:58
  Branch: HEAD Handle: 2011040511075700

  Modified files:
mancoosi/framework  rpmtest.py

  Log:
- WIP.

  Summary:
RevisionChanges Path
1.5 +79 -123mancoosi/framework/rpmtest.py
  

  patch -p0 '@@ .'
  Index: mancoosi/framework/rpmtest.py
  
  $ cvs diff -u -r1.4 -r1.5 rpmtest.py
  --- mancoosi/framework/rpmtest.py 4 Apr 2011 19:20:35 -   1.4
  +++ mancoosi/framework/rpmtest.py 5 Apr 2011 11:07:57 -   1.5
  @@ -21,10 +21,6 @@
   
   initial_contents = {}  # PKGNAME: [(FILE, mtime),...]
   initial_versions = {}  # PKGNAME: (NEVRA, INSTALLTID)
  -#mainrelease_dir = '/tmp/rpms/baseline/'
  -#multi_updates_dir = '/home/agrr/pacotes/multi-updates/'
  -#multi_release_dir = '/home/agrr/pacotes/multi-base/'
  -precondition_dir = CM15/RPMS/
   
   bin_rpm =/bin/rpm
   var_lib_rpm ='/var/lib/rpm/'
  @@ -45,16 +41,25 @@
self.maxdelay = maxdelay
self.erase_maxdelay = maxdelay
self.query_maxdelay = maxdelay
  + self.verify_maxdelay = maxdelay
self.install_maxdelay = maxdelay
   self.ts = None
   self.killtimes = []
  -self.success_cases = 0
  - self.details = [0,0] # (no. of transactions, no. of nop transactions)
  +
self.stats = {}
  +self.stats['tests_run'] = 0
  +self.stats['tests_success'] = 0
  + self.stats['tests_updated'] = 0
  + self.stats['tests_nochange'] = 0
  + self.stats['version_wrong'] = 0 # XXX unused
  +self.stats['files_wrong'] = 0# XXX unused
  +
self.stats['stale_lock'] = 0
self.stats['recover_failed'] = 0
self.stats['script_error'] = 0
  + self.stats['deps_missing'] = 0
self.stats['file_truncated'] = 0
  + self.stats['ldconfig_file_empty'] = 0
self.stats['config_rpmnew'] = 0
self.stats['config_rpmsave'] = 0
   
  @@ -75,14 +80,18 @@
self.created_as = '^warning: (.*) created as (.*)'
self.saved_as = '^warning: (.*) saved as (.*)'
   # ldconfig: file /usr/lib/libldap-2.4.so.2.5.5;4d99f2c1 is truncated
  -self.file_truncated = '^ldconfig: file ([^ ]*) is truncated'
  +# ldconfig: File /usr/lib/libmimerS.so.1.0.0;4d9a25ae is empty, not checked.
  +self.ldconfig_file_truncated = '^ldconfig: file ([^ ]*) is truncated'
  + self.ldconfig_file_empty = '^ldconfig: File ([^ ]*) is empty, not 
checked.'
   # warning: cleaning stale lock
   self.script_pats = [
  +# bind
'rndc: decode base64 secret: bad base64 encoding',
'rndc: connect failed: 127.0.0.1#953: connection refused',
  +# openldap-servers
  + 'Usage: service -[Rfshv] SERVICE ARGUMENTS',
]

  -
   def bad(self, args):
   print colored(args, 'red')
   
  @@ -91,14 +100,14 @@
   
   # Run a command.
   def run(self, args):
  -print 'Running: ' + str(args)
  +#print 'Running: ' + str(args)
   po = subprocess.Popen(args, stdout=None, stderr=None)
   res = po.wait() == 0
   return res
   
   # Run a command with a watchdog timer.
   def timed(self, args, delay):
  -print 'Running(' + str(delay) + '): ' + str(args)
  +#print 'Running(' + str(delay) + '): ' + str(args)
   po = subprocess.Popen(args, stdout=None, stderr=None)
   pid = po.pid
res = None
  @@ -118,7 +127,7 @@
   
   # Run a command capturing stdout/stderr.
   def communicate(self, args):
  -print 'Running: ' + str(args)
  +#print 'Running: ' + str(args)
   xx = subprocess.Popen(args, stdout=subprocess.PIPE, 
stderr=subprocess.PIPE).communicate()
return xx
   
  @@ -140,14 +149,23 @@
continue
   mo = re.match(self.is_needed_by, l)
if mo:
  + self.stats['deps_missing'] += 1
  + self.bad(missing:  + mo.group(0))
continue
  -mo = re.match(self.file_truncated, l)
  +mo = re.match(self.ldconfig_file_truncated, l)
if mo:
fn = mo.group(1)
  - self.stats['file_truncated'] += 1
  + self.stats['ldconfig_file_truncated'] += 1
self.bad(truncated:  + fn)
os.unlink(fn)
continue
  +mo = 

[CVS] RPM: mancoosi/framework/ rpmtest.py

2011-04-04 Thread Jeff Johnson
  RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  

  Server: rpm5.org Name:   Jeff Johnson
  Root:   /v/rpm/cvs   Email:  j...@rpm5.org
  Module: mancoosi Date:   04-Apr-2011 21:20:35
  Branch: HEAD Handle: 2011040419203500

  Modified files:
mancoosi/framework  rpmtest.py

  Log:
P.PR:

  Summary:
RevisionChanges Path
1.4 +81 -18 mancoosi/framework/rpmtest.py
  

  patch -p0 '@@ .'
  Index: mancoosi/framework/rpmtest.py
  
  $ cvs diff -u -r1.3 -r1.4 rpmtest.py
  --- mancoosi/framework/rpmtest.py 4 Apr 2011 16:10:08 -   1.3
  +++ mancoosi/framework/rpmtest.py 4 Apr 2011 19:20:35 -   1.4
  @@ -44,6 +44,7 @@
if maxdelay:
self.maxdelay = maxdelay
self.erase_maxdelay = maxdelay
  + self.query_maxdelay = maxdelay
self.install_maxdelay = maxdelay
   self.ts = None
   self.killtimes = []
  @@ -52,6 +53,10 @@
self.stats = {}
self.stats['stale_lock'] = 0
self.stats['recover_failed'] = 0
  + self.stats['script_error'] = 0
  + self.stats['file_truncated'] = 0
  + self.stats['config_rpmnew'] = 0
  + self.stats['config_rpmsave'] = 0
   
self.warning_pat = '.*warning: (.*)$'
self.error_pat = '.*error: (.*)$'
  @@ -66,7 +71,17 @@
self.failed_deps = '^error: Failed dependencies:'
self.is_needed_by = '(.*) is needed by (.*)'
   # warning: /etc/sysconfig/ldap created as /etc/sysconfig/ldap.rpmnew
  - self.created_as = '.*warning: (.*) created as (.*)'
  +# warning: /etc/sysconfig/ldap saved as /etc/sysconfig/ldap.rpmsave
  + self.created_as = '^warning: (.*) created as (.*)'
  + self.saved_as = '^warning: (.*) saved as (.*)'
  +# ldconfig: file /usr/lib/libldap-2.4.so.2.5.5;4d99f2c1 is truncated
  +self.file_truncated = '^ldconfig: file ([^ ]*) is truncated'
  +# warning: cleaning stale lock
  +self.script_pats = [
  + 'rndc: decode base64 secret: bad base64 encoding',
  + 'rndc: connect failed: 127.0.0.1#953: connection refused',
  + ]
  + 
   
   def bad(self, args):
   print colored(args, 'red')
  @@ -86,8 +101,13 @@
   print 'Running(' + str(delay) + '): ' + str(args)
   po = subprocess.Popen(args, stdout=None, stderr=None)
   pid = po.pid
  -time.sleep(delay)
  -res = subprocess.Popen.poll(po)
  + res = None
  + for i in range(int(delay+1)):
  +time.sleep(1)
  +res = subprocess.Popen.poll(po)
  + if res:
  + break
  +
   if not res:
  try:
   po.kill()
  @@ -121,6 +141,34 @@
   mo = re.match(self.is_needed_by, l)
if mo:
continue
  +mo = re.match(self.file_truncated, l)
  + if mo:
  + fn = mo.group(1)
  + self.stats['file_truncated'] += 1
  + self.bad(truncated:  + fn)
  + os.unlink(fn)
  + continue
  +mo = re.match(self.created_as, l)
  + if mo:
  + fn = mo.group(2)
  + self.stats['config_rpmnew'] += 1
  + self.bad(rpmnew:  + fn)
  + os.unlink(fn)
  + continue
  +mo = re.match(self.saved_as, l)
  + if mo:
  + fn = mo.group(2)
  + self.stats['config_rpmsave'] += 1
  + self.bad(rpmsave:  + fn)
  + os.unlink(fn)
  + continue
  + for pat in self.script_pats:
  +mo = re.match(pat, l)
  + if mo:
  + break
  + if mo:
  + self.stats['script_error'] += 1
  + continue;
a.append(l)
res = '\n'.join(a)
return res
  @@ -159,14 +207,22 @@
   # Calibrate maxdelay from pkg set install/erase times.
   def calibrate(self):
xx = self.erase_pkgset()
  +
bgn = time.time()
args = [bin_rpm, '-U' ] + self.rpms
xx = self.run(args)
self.install_maxdelay = (time.time() - bgn) * 1000.
  +
  + bgn = time.time()
  + args = [bin_rpm, '-q' ] + self.pkgs
  + xx = self.run(args)
  + self.query_maxdelay = (time.time() - bgn) * 1000.
  +
bgn = time.time()
args = [bin_rpm, '-e' ] + self.pkgs
xx = self.run(args)
self.erase_maxdelay = (time.time() - bgn) * 1000.
  +
return xx
   
   def rollback(self, rollback_list):
  

[CVS] RPM: mancoosi/framework/ rpmtest.py

2011-04-01 Thread Jeff Johnson
  RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  

  Server: rpm5.org Name:   Jeff Johnson
  Root:   /v/rpm/cvs   Email:  j...@rpm5.org
  Module: mancoosi Date:   01-Apr-2011 20:22:34
  Branch: HEAD Handle: 2011040118223400

  Modified files:
mancoosi/framework  rpmtest.py

  Log:
- add patterns to capture --verify errors.
- add more methods to the Uuut class.

  Summary:
RevisionChanges Path
1.2 +318 -245   mancoosi/framework/rpmtest.py
  

  patch -p0 '@@ .'
  Index: mancoosi/framework/rpmtest.py
  
  $ cvs diff -u -r1.1 -r1.2 rpmtest.py
  --- mancoosi/framework/rpmtest.py 28 Mar 2011 14:30:19 -  1.1
  +++ mancoosi/framework/rpmtest.py 1 Apr 2011 18:22:34 -   1.2
  @@ -8,6 +8,7 @@
   import glob
   import string
   import sys
  +import re
   import rpm
   import signal
   import optparse
  @@ -20,117 +21,285 @@
   
   initial_contents = {}  # PKGNAME: [(FILE, mtime),...]
   initial_versions = {}  # PKGNAME: (NEVRA, INSTALLTID)
  -killtimes = []  # list of killtimes
  -rollback_list = []
   #mainrelease_dir = '/tmp/rpms/baseline/'
   #multi_updates_dir = '/home/agrr/pacotes/multi-updates/'
   #multi_release_dir = '/home/agrr/pacotes/multi-base/'
   precondition_dir = CM15/RPMS/
  -multi_test_details = [0, 0]  # (Number of all upgraded transactions, number 
of nop transactions)
  -global_transaction = None
   
  -def test_case(list_of_pkgs, max_delay):
  -global killtimes
  -print -- test_case(list_of_pkgs,  + str(max_delay) + )
  -args = ['rpm', '-Uvh', '--force', '--nodeps', '--noscripts']
  -print 'Test Case: ' + str(list_of_pkgs)
  -
  -args_final = args + list_of_pkgs
  -
  -print 'About to run ' + str(args_final)
  -rpm_pid = os.spawnv(os.P_NOWAIT, '/bin/rpm', args_final)
  -mult = random.random()
  -actual_killtime = mult * max_delay * len(list_of_pkgs)
  -print 'Killtime actual: ' + str(actual_killtime) + ' '
  -
  -time.sleep(actual_killtime)
  -
  -killtimes.append(actual_killtime)
  -sys.stderr.write('Killing rpm after %f\n' % actual_killtime)
  -os.kill(rpm_pid, signal.SIGKILL)
  -
  -
  -def test_case_single_pkg(pkg, max_delay):
  -global killtimes
  -print -- test_case_single_pkg(pkg,  + str(max_delay) + )
  -args = ['rpm', '-Uvh', '--force', '--nodeps', '--quiet']
  -(blah, filename) = pkg
  -args.append(filename)
  -
  -print 'About to run rpm -Uvh ' + str(args)
  -rpm_pid = os.spawnv(os.P_NOWAIT, '/bin/rpm', args)
  -mult = random.random() * max_delay
  -killtimes.append(mult)
  -
  -time.sleep(mult)
  -
  -sys.stderr.write('Killing rpm after %f\n' % mult)
  -os.kill(rpm_pid, signal.SIGKILL)
  -
  -
  -def install_forced(install_list):
  -args = ['/bin/rpm', '-Uvh', '--force', '--nodeps', '--quiet'] \
  -+ install_list
  -p = subprocess.Popen(args)
  -ret = p.wait()
  -res = ret == 0
  -print -- install_forced( + str(install_list) + ) res  + str(res)
  -return res
  +bin_rpm =/bin/rpm
  +var_lib_rpm ='/var/lib/rpm/'
  +usr_bin_dbrecover =  '/usr/bin/db_recover'
  +usr_bin_dbstat = '/usr/bin/db_stat'
  +
  +class Uut:
  +def __init__(self, pkgset, niters=10, maxdelay=3.0, **kwargs):
  +self.pkgset = pkgset
  + self.npkgs = len(self.pkgset)
  +self.pkgs = [p for (p, fn) in pkgset]
  + print 'pkgs: ' + str(self.pkgs)
  +self.rpms = [fn for (p, fn) in pkgset]
  + print 'rpms: ' + str(self.rpms)
  + if niters:
  + self.niters = niters
  + if maxdelay:
  + self.maxdelay = maxdelay
  +self.ts = None
  +self.killtimes = []
  +self.success_cases = 0
  + self.details = [0,0] # (no. of transactions, no. of nop transactions)
  +
  + self.warning_pat = '.*warning: (.*)$'
  + self.error_pat = '.*error: (.*)$'
  +
  +# error: package libunixODBC1 is not installed
  + self.package_not_installed = '.*package ([^ ]*) is not installed$'
  +# Unsatisfied dependencies for openldap-clients-2.4.22-2mdv2010.1.i586:
  +#libldap2.4_2 = 2.4.22-2mdv2010.1 is needed by 
openldap-clients-2.4.22-2mdv2010.1.i586
  +#liblber-2.4.so.2 is needed by openldap-clients-2.4.22-2mdv2010.1.i586
  +#libldap-2.4.so.2 is needed by openldap-clients-2.4.22-2mdv2010.1.i586
  + self.unsatisfied_deps = '^Unsatisfied dependencies for (.*):'
  + self.is_needed_by = '(.*) is needed by (.*)'
  +# warning: /etc/sysconfig/ldap created as /etc/sysconfig/ldap.rpmnew
  + self.created_as = '.*warning: (.*) created as (.*)'
  +
  +def bad(self, args):
  +  

[CVS] RPM: mancoosi/framework/ rpmtest.py

2011-03-28 Thread Jeff Johnson
  RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  

  Server: rpm5.org Name:   Jeff Johnson
  Root:   /v/rpm/cvs   Email:  j...@rpm5.org
  Module: mancoosi Date:   28-Mar-2011 16:30:20
  Branch: HEAD Handle: 2011032814301900

  Added files:
mancoosi/framework  rpmtest.py

  Log:
- swipe a copy of rpm4_test.py for developpment/extension.

  Summary:
RevisionChanges Path
1.1 +492 -0 mancoosi/framework/rpmtest.py
  

  patch -p0 '@@ .'
  Index: mancoosi/framework/rpmtest.py
  
  $ cvs diff -u -r0 -r1.1 rpmtest.py
  --- /dev/null 2011-03-28 16:30:19.0 +0200
  +++ rpmtest.py2011-03-28 16:30:20.133414672 +0200
  @@ -0,0 +1,492 @@
  +#!/usr/bin/python
  +# -*- coding: utf-8 -*-
  +
  +import random
  +import time
  +import os
  +import fnmatch
  +import glob
  +import string
  +import sys
  +import rpm
  +import signal
  +import optparse
  +import subprocess
  +import csvwriter
  +
  +from termcolor import colored
  +
  +# Globals
  +
  +initial_contents = {}  # PKGNAME: [(FILE, mtime),...]
  +initial_versions = {}  # PKGNAME: (NEVRA, INSTALLTID)
  +killtimes = []  # list of killtimes
  +rollback_list = []
  +#mainrelease_dir = '/tmp/rpms/baseline/'
  +#multi_updates_dir = '/home/agrr/pacotes/multi-updates/'
  +#multi_release_dir = '/home/agrr/pacotes/multi-base/'
  +precondition_dir = CM15/RPMS/
  +multi_test_details = [0, 0]  # (Number of all upgraded transactions, number 
of nop transactions)
  +global_transaction = None
  +
  +def test_case(list_of_pkgs, max_delay):
  +global killtimes
  +print -- test_case(list_of_pkgs,  + str(max_delay) + )
  +args = ['rpm', '-Uvh', '--force', '--nodeps', '--noscripts']
  +print 'Test Case: ' + str(list_of_pkgs)
  +
  +args_final = args + list_of_pkgs
  +
  +print 'About to run ' + str(args_final)
  +rpm_pid = os.spawnv(os.P_NOWAIT, '/bin/rpm', args_final)
  +mult = random.random()
  +actual_killtime = mult * max_delay * len(list_of_pkgs)
  +print 'Killtime actual: ' + str(actual_killtime) + ' '
  +
  +time.sleep(actual_killtime)
  +
  +killtimes.append(actual_killtime)
  +sys.stderr.write('Killing rpm after %f\n' % actual_killtime)
  +os.kill(rpm_pid, signal.SIGKILL)
  +
  +
  +def test_case_single_pkg(pkg, max_delay):
  +global killtimes
  +print -- test_case_single_pkg(pkg,  + str(max_delay) + )
  +args = ['rpm', '-Uvh', '--force', '--nodeps', '--quiet']
  +(blah, filename) = pkg
  +args.append(filename)
  +
  +print 'About to run rpm -Uvh ' + str(args)
  +rpm_pid = os.spawnv(os.P_NOWAIT, '/bin/rpm', args)
  +mult = random.random() * max_delay
  +killtimes.append(mult)
  +
  +time.sleep(mult)
  +
  +sys.stderr.write('Killing rpm after %f\n' % mult)
  +os.kill(rpm_pid, signal.SIGKILL)
  +
  +
  +def install_forced(install_list):
  +args = ['/bin/rpm', '-Uvh', '--force', '--nodeps', '--quiet'] \
  ++ install_list
  +p = subprocess.Popen(args)
  +ret = p.wait()
  +res = ret == 0
  +print -- install_forced( + str(install_list) + ) res  + str(res)
  +return res
  +
  +
  +def do_rollback(rollback_list):
  +print -- do_rollback( + str(rollback_list) + )
  +print 'Rollback for ' + str(rollback_list)
  +
  +# rollback_list must be really a list !!
  +
  +if not install_forced(rollback_list):
  +print colored('Rollback failed!', 'red')
  +recoverRPMdb()
  +
  +
  +def recoverRPMdb():
  +rpmdb_dir = '/var/lib/rpm/'
  +args = ['sudo', '/usr/bin/db_recover', '-e', '-h', rpmdb_dir]
  +p = subprocess.Popen(args).communicate()[0]
  +print -- recoverRPMdb()
  +
  +
  +def rpmVerify(pkgname):
  +args = ['rpm', '-V', pkgname]
  +verify_output = subprocess.Popen(args,
  +stdout=subprocess.PIPE).communicate()[0]
  +if len(0):
  +print 'Package %s is not OK' % pkgname
  +res = False
  +else:
  +res = True
  +print -- rpmVerify( + pkgname + ) res  + str(res)
  +
  +
  +def listPkgContent(ts, pkgname):
  +h = queryByPkgName(ts, pkgname)
  +if h and h[rpm.RPMTAG_FILENAMES]:
  +for file in h[rpm.RPMTAG_FILENAMES]:
  +#print -- listPkgContent(ts,  + pkgname + ) fn  + file
  +yield file
  +
  +
  +def queryByPkgName(ts, name):
  +#print -- queryByPkgName(ts,  + name + )
  +match = ts.dbMatch('name', name)
  +if not match:
  +
  +# We need to catch the 'timezone' case...
  +
  +for p in ts.dbMatch():
  +if p['name'].startswith(pkgname):
  +return p
  +else:
  +return