Module utils
[hide private]
[frames] | no frames]

Source Code for Module utils

  1  #!/usr/bin/python -t 
  2  # This program is free software; you can redistribute it and/or modify 
  3  # it under the terms of the GNU General Public License as published by 
  4  # the Free Software Foundation; either version 2 of the License, or 
  5  # (at your option) any later version. 
  6  # 
  7  # This program is distributed in the hope that it will be useful, 
  8  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  9  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 10  # GNU Library General Public License for more details. 
 11  # 
 12  # You should have received a copy of the GNU General Public License 
 13  # along with this program; if not, write to the Free Software 
 14  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
 15   
 16  import sys 
 17  import time 
 18  import exceptions 
 19   
 20  import yum 
 21  from cli import * 
 22  from yum import Errors 
 23  from yum import _ 
 24  from yum import logginglevels 
 25  from optparse import OptionGroup 
 26   
 27  import yum.plugins as plugins 
 28  from urlgrabber.progress import format_number 
 29   
30 -def suppress_keyboard_interrupt_message():
31 old_excepthook = sys.excepthook 32 33 def new_hook(type, value, traceback): 34 if type != exceptions.KeyboardInterrupt: 35 old_excepthook(type, value, traceback) 36 else: 37 pass
38 39 sys.excepthook = new_hook 40
41 -def jiffies_to_seconds(jiffies):
42 Hertz = 100 # FIXME: Hack, need to get this, AT_CLKTCK elf note *sigh* 43 return int(jiffies) / Hertz
44
45 -def seconds_to_ui_time(seconds):
46 if seconds >= 60 * 60 * 24: 47 return "%d day(s) %d:%02d:%02d" % (seconds / (60 * 60 * 24), 48 (seconds / (60 * 60)) % 24, 49 (seconds / 60) % 60, 50 seconds % 60) 51 if seconds >= 60 * 60: 52 return "%d:%02d:%02d" % (seconds / (60 * 60), (seconds / 60) % 60, 53 (seconds % 60)) 54 return "%02d:%02d" % ((seconds / 60), seconds % 60)
55
56 -def get_process_info(pid):
57 if not pid: 58 return 59 60 # Maybe true if /proc isn't mounted, or not Linux ... or something. 61 if (not os.path.exists("/proc/%d/status" % pid) or 62 not os.path.exists("/proc/stat") or 63 not os.path.exists("/proc/%d/stat" % pid)): 64 return 65 66 ps = {} 67 for line in open("/proc/%d/status" % pid): 68 if line[-1] != '\n': 69 continue 70 data = line[:-1].split(':\t', 1) 71 if len(data) < 2: 72 continue 73 if data[1].endswith(' kB'): 74 data[1] = data[1][:-3] 75 ps[data[0].strip().lower()] = data[1].strip() 76 if 'vmrss' not in ps: 77 return 78 if 'vmsize' not in ps: 79 return 80 boot_time = None 81 for line in open("/proc/stat"): 82 if line.startswith("btime "): 83 boot_time = int(line[len("btime "):-1]) 84 break 85 if boot_time is None: 86 return 87 ps_stat = open("/proc/%d/stat" % pid).read().split() 88 ps['utime'] = jiffies_to_seconds(ps_stat[13]) 89 ps['stime'] = jiffies_to_seconds(ps_stat[14]) 90 ps['cutime'] = jiffies_to_seconds(ps_stat[15]) 91 ps['cstime'] = jiffies_to_seconds(ps_stat[16]) 92 ps['start_time'] = boot_time + jiffies_to_seconds(ps_stat[21]) 93 ps['state'] = {'R' : _('Running'), 94 'S' : _('Sleeping'), 95 'D' : _('Uninterruptible'), 96 'Z' : _('Zombie'), 97 'T' : _('Traced/Stopped') 98 }.get(ps_stat[2], _('Unknown')) 99 100 return ps
101
102 -def show_lock_owner(pid, logger):
103 if not pid: 104 return 105 106 ps = get_process_info(pid) 107 # This yumBackend isn't very friendly, so... 108 if ps['name'] == 'yumBackend.py': 109 nmsg = _(" The other application is: PackageKit") 110 else: 111 nmsg = _(" The other application is: %s") % ps['name'] 112 113 logger.critical("%s", nmsg) 114 logger.critical(_(" Memory : %5s RSS (%5sB VSZ)") % 115 (format_number(int(ps['vmrss']) * 1024), 116 format_number(int(ps['vmsize']) * 1024))) 117 118 ago = seconds_to_ui_time(int(time.time()) - ps['start_time']) 119 logger.critical(_(" Started: %s - %s ago") % 120 (time.ctime(ps['start_time']), ago)) 121 logger.critical(_(" State : %s, pid: %d") % (ps['state'], pid))
122
123 -class YumUtilBase(YumBaseCli):
124 - def __init__(self,name,ver,usage):
125 YumBaseCli.__init__(self) 126 self._parser = YumOptionParser(base=self,utils=True,usage=usage) 127 self._usage = usage 128 self._utilName = name 129 self._utilVer = ver 130 self._option_group = OptionGroup(self._parser, "%s options" % self._utilName,"") 131 self._parser.add_option_group(self._option_group) 132 suppress_keyboard_interrupt_message() 133 logger = logging.getLogger("yum.util") 134 verbose_logger = logging.getLogger("yum.verbose.util")
135 136
137 - def getOptionParser(self):
138 return self._parser
139
140 - def getOptionGroup(self):
141 """ Get an option group to add non inherited options""" 142 return self._option_group
143
144 - def waitForLock(self):
145 lockerr = "" 146 while True: 147 try: 148 self.doLock() 149 except Errors.LockError, e: 150 if "%s" %(e.msg,) != lockerr: 151 lockerr = "%s" %(e.msg,) 152 self.logger.critical(lockerr) 153 self.logger.critical("Another app is currently holding the yum lock; waiting for it to exit...") 154 show_lock_owner(e.pid, self.logger) 155 time.sleep(2) 156 else: 157 break
158
159 - def _printUtilVersion(self):
160 print "%s - %s (yum - %s)" % (self._utilName,self._utilVer,yum.__version__)
161
162 - def doUtilConfigSetup(self,args = sys.argv[1:],pluginsTypes=(plugins.TYPE_CORE,)):
163 # Parse only command line options that affect basic yum setup 164 opts = self._parser.firstParse(args) 165 # Just print out the version if that's what the user wanted 166 if opts.version: 167 self._printUtilVersion() 168 sys.exit(0) 169 # get the install root to use 170 root = self._parser.getRoot(opts) 171 if opts.quiet: 172 opts.debuglevel = 0 173 if opts.verbose: 174 opts.debuglevel = opts.errorlevel = 6 175 176 # Read up configuration options and initialise plugins 177 try: 178 pc = self.preconf 179 pc.fn = opts.conffile 180 pc.root = root 181 pc.init_plugins = not opts.noplugins 182 pc.plugin_types = pluginsTypes 183 pc.optparser = self._parser 184 pc.debuglevel = opts.debuglevel 185 pc.errorlevel = opts.errorlevel 186 if hasattr(opts, "disableplugins"): 187 pc.disabled_plugins =self._parser._splitArg(opts.disableplugins) 188 if hasattr(opts, "enableplugins"): 189 pc.enabled_plugins = self._parser._splitArg(opts.enableplugins) 190 self.conf 191 192 except Errors.ConfigError, e: 193 self.logger.critical(_('Config Error: %s'), e) 194 sys.exit(1) 195 except ValueError, e: 196 self.logger.critical(_('Options Error: %s'), e) 197 sys.exit(1) 198 except plugins.PluginYumExit, e: 199 self.logger.critical(_('PluginExit Error: %s'), e) 200 sys.exit(1) 201 except Errors.YumBaseError, e: 202 self.logger.critical(_('Yum Error: %s'), e) 203 sys.exit(1) 204 205 # update usage in case plugins have added commands 206 self._parser.set_usage(self._usage) 207 208 # Now parse the command line for real and 209 # apply some of the options to self.conf 210 (opts, self.cmds) = self._parser.setupYumConfig() 211 if self.cmds: 212 self.basecmd = self.cmds[0] # our base command 213 else: 214 self.basecmd = None 215 self.extcmds = self.cmds[1:] # out extended arguments/commands 216 217 return opts
218
219 - def doUtilYumSetup(self):
220 """do a default setup for all the normal/necessary yum components, 221 really just a shorthand for testing""" 222 # FIXME - we need another way to do this, I think. 223 try: 224 self.waitForLock() 225 self._getTs() 226 self._getRpmDB() 227 self._getRepos(doSetup = True) 228 self._getSacks() 229 except Errors.YumBaseError, msg: 230 self.logger.critical(str(msg)) 231 sys.exit(1)
232
233 - def doUtilTransaction(self):
234 def exUserCancel(): 235 self.logger.critical(_('\n\nExiting on user cancel')) 236 if unlock(): return 200 237 return 1
238 239 def exIOError(e): 240 if e.errno == 32: 241 self.logger.critical(_('\n\nExiting on Broken Pipe')) 242 else: 243 self.logger.critical(_('\n\n%s') % str(e)) 244 if unlock(): return 200 245 return 1
246 247 def exPluginExit(e): 248 '''Called when a plugin raises PluginYumExit. 249 250 Log the plugin's exit message if one was supplied. 251 ''' # ' xemacs hack 252 exitmsg = str(e) 253 if exitmsg: 254 self.logger.warn('\n\n%s', exitmsg) 255 if unlock(): return 200 256 return 1 257 258 def exFatal(e): 259 self.logger.critical('\n\n%s', to_unicode(e.value)) 260 if unlock(): return 200 261 return 1 262 263 def unlock(): 264 try: 265 self.closeRpmDB() 266 self.doUnlock() 267 except Errors.LockError, e: 268 return 200 269 return 0 270 271 try: 272 return_code = self.doTransaction() 273 except plugins.PluginYumExit, e: 274 return exPluginExit(e) 275 except Errors.YumBaseError, e: 276 return exFatal(e) 277 except KeyboardInterrupt: 278 return exUserCancel() 279 except IOError, e: 280 return exIOError(e) 281 282 self.verbose_logger.log(logginglevels.INFO_2, _('Complete!')) 283 if unlock(): return 200 284 return return_code 285
286 -def main():
287 name = 'testutil' 288 ver = '0.1' 289 usage = 'testutil [options] [args]' 290 util = YumUtilBase(name,ver,usage) 291 parser = util.getOptionParser() 292 parser.add_option("", "--myoption", dest="myoption", 293 action="store_true", default=False, 294 help="This is an util option") 295 util.logger.info("Setup Yum Config") 296 opts = util.doUtilConfigSetup() 297 util.logger.info("Setup Yum") 298 util.doUtilYumSetup() 299 print "Command line args: %s" % " ".join(util.cmds) 300 print "Command line options :" 301 print opts 302 303 util.logger.info("%s Completed" % name)
304 if __name__ == '__main__': 305 main() 306