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

Source Code for Module cli

   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  # Copyright 2005 Duke University  
  16  # Written by Seth Vidal 
  17   
  18  """ 
  19  Command line interface yum class and related. 
  20  """ 
  21   
  22  import os 
  23  import re 
  24  import sys 
  25  import time 
  26  import random 
  27  import logging 
  28  from optparse import OptionParser,OptionGroup 
  29  import rpm 
  30   
  31  from weakref import proxy as weakref 
  32   
  33  import output 
  34  import shell 
  35  import yum 
  36  import yum.Errors 
  37  import yum.logginglevels 
  38  import yum.misc 
  39  import yum.plugins 
  40  from rpmUtils.arch import isMultiLibArch 
  41  from yum import _ 
  42  from yum.rpmtrans import RPMTransaction 
  43  import signal 
  44  import yumcommands 
  45   
  46  from yum.i18n import to_unicode, to_utf8 
47 48 -def sigquit(signum, frame):
49 """ SIGQUIT handler for the yum cli. """ 50 print >> sys.stderr, "Quit signal sent - exiting immediately" 51 sys.exit(1)
52
53 -class CliError(yum.Errors.YumBaseError):
54 55 """ 56 Command line interface related Exception. 57 """ 58
59 - def __init__(self, args=''):
60 yum.Errors.YumBaseError.__init__(self) 61 self.args = args
62
63 -class YumBaseCli(yum.YumBase, output.YumOutput):
64 """This is the base class for yum cli. 65 Inherits from yum.YumBase and output.YumOutput """ 66
67 - def __init__(self):
68 # handle sigquit early on 69 signal.signal(signal.SIGQUIT, sigquit) 70 yum.YumBase.__init__(self) 71 output.YumOutput.__init__(self) 72 logging.basicConfig() 73 self.logger = logging.getLogger("yum.cli") 74 self.verbose_logger = logging.getLogger("yum.verbose.cli") 75 self.yum_cli_commands = {} 76 self.registerCommand(yumcommands.InstallCommand()) 77 self.registerCommand(yumcommands.UpdateCommand()) 78 self.registerCommand(yumcommands.InfoCommand()) 79 self.registerCommand(yumcommands.ListCommand()) 80 self.registerCommand(yumcommands.EraseCommand()) 81 self.registerCommand(yumcommands.GroupCommand()) 82 self.registerCommand(yumcommands.GroupListCommand()) 83 self.registerCommand(yumcommands.GroupInstallCommand()) 84 self.registerCommand(yumcommands.GroupRemoveCommand()) 85 self.registerCommand(yumcommands.GroupInfoCommand()) 86 self.registerCommand(yumcommands.MakeCacheCommand()) 87 self.registerCommand(yumcommands.CleanCommand()) 88 self.registerCommand(yumcommands.ProvidesCommand()) 89 self.registerCommand(yumcommands.CheckUpdateCommand()) 90 self.registerCommand(yumcommands.SearchCommand()) 91 self.registerCommand(yumcommands.UpgradeCommand()) 92 self.registerCommand(yumcommands.LocalInstallCommand()) 93 self.registerCommand(yumcommands.ResolveDepCommand()) 94 self.registerCommand(yumcommands.ShellCommand()) 95 self.registerCommand(yumcommands.DepListCommand()) 96 self.registerCommand(yumcommands.RepoListCommand()) 97 self.registerCommand(yumcommands.HelpCommand()) 98 self.registerCommand(yumcommands.ReInstallCommand()) 99 self.registerCommand(yumcommands.DowngradeCommand()) 100 self.registerCommand(yumcommands.VersionCommand()) 101 self.registerCommand(yumcommands.HistoryCommand()) 102 self.registerCommand(yumcommands.CheckRpmdbCommand())
103
104 - def registerCommand(self, command):
105 for name in command.getNames(): 106 if name in self.yum_cli_commands: 107 raise yum.Errors.ConfigError(_('Command "%s" already defined') % name) 108 self.yum_cli_commands[name] = command
109
110 - def doRepoSetup(self, thisrepo=None, dosack=1):
111 """grabs the repomd.xml for each enabled repository 112 and sets up the basics of the repository""" 113 114 if self._repos and thisrepo is None: 115 return self._repos 116 117 if not thisrepo: 118 self.verbose_logger.log(yum.logginglevels.INFO_2, 119 _('Setting up repositories')) 120 121 # Call parent class to do the bulk of work 122 # (this also ensures that reposetup plugin hook is called) 123 if thisrepo: 124 yum.YumBase._getRepos(self, thisrepo=thisrepo, doSetup=True) 125 else: 126 yum.YumBase._getRepos(self, thisrepo=thisrepo) 127 128 if dosack: # so we can make the dirs and grab the repomd.xml but not import the md 129 self.verbose_logger.log(yum.logginglevels.INFO_2, 130 _('Reading repository metadata in from local files')) 131 self._getSacks(thisrepo=thisrepo) 132 133 return self._repos
134
135 - def _makeUsage(self):
136 """ 137 Format an attractive usage string for yum, listing subcommand 138 names and summary usages. 139 """ 140 usage = 'yum [options] COMMAND\n\nList of Commands:\n\n' 141 commands = yum.misc.unique(self.yum_cli_commands.values()) 142 commands.sort(key=lambda x: x.getNames()[0]) 143 for command in commands: 144 # XXX Remove this when getSummary is common in plugins 145 try: 146 summary = command.getSummary() 147 usage += "%-14s %s\n" % (command.getNames()[0], summary) 148 except (AttributeError, NotImplementedError): 149 usage += "%s\n" % command.getNames()[0] 150 151 return usage
152
153 - def getOptionsConfig(self, args):
154 """parses command line arguments, takes cli args: 155 sets up self.conf and self.cmds as well as logger objects 156 in base instance""" 157 158 self.optparser = YumOptionParser(base=self, usage=self._makeUsage()) 159 160 # Parse only command line options that affect basic yum setup 161 opts = self.optparser.firstParse(args) 162 163 # Just print out the version if that's what the user wanted 164 if opts.version: 165 print yum.__version__ 166 opts.quiet = True 167 opts.verbose = False 168 169 # get the install root to use 170 root = self.optparser.getRoot(opts) 171 172 if opts.quiet: 173 opts.debuglevel = 0 174 if opts.verbose: 175 opts.debuglevel = opts.errorlevel = 6 176 177 # Read up configuration options and initialise plugins 178 try: 179 pc = self.preconf 180 pc.fn = opts.conffile 181 pc.root = root 182 pc.init_plugins = not opts.noplugins 183 pc.plugin_types = (yum.plugins.TYPE_CORE, 184 yum.plugins.TYPE_INTERACTIVE) 185 pc.optparser = self.optparser 186 pc.debuglevel = opts.debuglevel 187 pc.errorlevel = opts.errorlevel 188 pc.disabled_plugins = self.optparser._splitArg(opts.disableplugins) 189 pc.enabled_plugins = self.optparser._splitArg(opts.enableplugins) 190 pc.releasever = opts.releasever 191 self.conf 192 193 except yum.Errors.ConfigError, e: 194 self.logger.critical(_('Config Error: %s'), e) 195 sys.exit(1) 196 except ValueError, e: 197 self.logger.critical(_('Options Error: %s'), e) 198 sys.exit(1) 199 200 # update usage in case plugins have added commands 201 self.optparser.set_usage(self._makeUsage()) 202 203 self.plugins.run('args', args=args) 204 # Now parse the command line for real and 205 # apply some of the options to self.conf 206 (opts, self.cmds) = self.optparser.setupYumConfig(args=args) 207 208 if opts.version: 209 self.conf.cache = 1 210 yum_progs = self.run_with_package_names 211 done = False 212 def sm_ui_time(x): 213 return time.strftime("%Y-%m-%d %H:%M", time.gmtime(x))
214 def sm_ui_date(x): # For changelogs, there is no time 215 return time.strftime("%Y-%m-%d", time.gmtime(x))
216 for pkg in sorted(self.rpmdb.returnPackages(patterns=yum_progs)): 217 # We should only have 1 version of each... 218 if done: print "" 219 done = True 220 if pkg.epoch == '0': 221 ver = '%s-%s.%s' % (pkg.version, pkg.release, pkg.arch) 222 else: 223 ver = '%s:%s-%s.%s' % (pkg.epoch, 224 pkg.version, pkg.release, pkg.arch) 225 name = "%s%s%s" % (self.term.MODE['bold'], pkg.name, 226 self.term.MODE['normal']) 227 print _(" Installed: %s-%s at %s") %(name, ver, 228 sm_ui_time(pkg.installtime)) 229 print _(" Built : %s at %s") % (pkg.packager, 230 sm_ui_time(pkg.buildtime)) 231 print _(" Committed: %s at %s") % (pkg.committer, 232 sm_ui_date(pkg.committime)) 233 sys.exit(0) 234 235 if opts.sleeptime is not None: 236 sleeptime = random.randrange(opts.sleeptime*60) 237 else: 238 sleeptime = 0 239 240 # save our original args out 241 self.args = args 242 # save out as a nice command string 243 self.cmdstring = 'yum ' 244 for arg in self.args: 245 self.cmdstring += '%s ' % arg 246 247 try: 248 self.parseCommands() # before we return check over the base command + args 249 # make sure they match/make sense 250 except CliError: 251 sys.exit(1) 252 253 # run the sleep - if it's unchanged then it won't matter 254 time.sleep(sleeptime) 255
256 - def parseCommands(self):
257 """reads self.cmds and parses them out to make sure that the requested 258 base command + argument makes any sense at all""" 259 260 self.verbose_logger.debug('Yum Version: %s', yum.__version__) 261 self.verbose_logger.log(yum.logginglevels.DEBUG_4, 262 'COMMAND: %s', self.cmdstring) 263 self.verbose_logger.log(yum.logginglevels.DEBUG_4, 264 'Installroot: %s', self.conf.installroot) 265 if len(self.conf.commands) == 0 and len(self.cmds) < 1: 266 self.cmds = self.conf.commands 267 else: 268 self.conf.commands = self.cmds 269 if len(self.cmds) < 1: 270 self.logger.critical(_('You need to give some command')) 271 self.usage() 272 raise CliError 273 274 self.basecmd = self.cmds[0] # our base command 275 self.extcmds = self.cmds[1:] # out extended arguments/commands 276 277 if len(self.extcmds) > 0: 278 self.verbose_logger.log(yum.logginglevels.DEBUG_4, 279 'Ext Commands:\n') 280 for arg in self.extcmds: 281 self.verbose_logger.log(yum.logginglevels.DEBUG_4, ' %s', arg) 282 283 if self.basecmd not in self.yum_cli_commands: 284 self.logger.critical(_('No such command: %s. Please use %s --help'), 285 self.basecmd, sys.argv[0]) 286 raise CliError 287 288 self.yum_cli_commands[self.basecmd].doCheck(self, self.basecmd, self.extcmds)
289
290 - def doShell(self):
291 """do a shell-like interface for yum commands""" 292 293 yumshell = shell.YumShell(base=self) 294 if len(self.extcmds) == 0: 295 yumshell.cmdloop() 296 else: 297 yumshell.script() 298 return yumshell.result, yumshell.resultmsgs
299
300 - def errorSummary(self, errstring):
301 """ parse the error string for 'interesting' errors which can 302 be grouped, such as disk space issues """ 303 summary = '' 304 # do disk space report first 305 p = re.compile('needs (\d+)MB on the (\S+) filesystem') 306 disk = {} 307 for m in p.finditer(errstring): 308 if not disk.has_key(m.group(2)): 309 disk[m.group(2)] = int(m.group(1)) 310 if disk[m.group(2)] < int(m.group(1)): 311 disk[m.group(2)] = int(m.group(1)) 312 313 if disk: 314 summary += _('Disk Requirements:\n') 315 for k in disk: 316 summary += _(' At least %dMB more space needed on the %s filesystem.\n') % (disk[k], k) 317 318 # TODO: simplify the dependency errors? 319 320 # Fixup the summary 321 summary = _('Error Summary\n-------------\n') + summary 322 323 return summary
324 325
326 - def doCommands(self):
327 """ 328 Calls the base command passes the extended commands/args out to be 329 parsed (most notably package globs). 330 331 Returns a numeric result code and an optional string 332 - 0 = we're done, exit 333 - 1 = we've errored, exit with error string 334 - 2 = we've got work yet to do, onto the next stage 335 """ 336 337 # at this point we know the args are valid - we don't know their meaning 338 # but we know we're not being sent garbage 339 340 # setup our transaction set if the command we're using needs it 341 # compat with odd modules not subclassing YumCommand 342 needTs = True 343 needTsRemove = False 344 cmd = self.yum_cli_commands[self.basecmd] 345 if hasattr(cmd, 'needTs'): 346 needTs = cmd.needTs(self, self.basecmd, self.extcmds) 347 if not needTs and hasattr(cmd, 'needTsRemove'): 348 needTsRemove = cmd.needTsRemove(self, self.basecmd, self.extcmds) 349 350 if needTs or needTsRemove: 351 try: 352 self._getTs(needTsRemove) 353 except yum.Errors.YumBaseError, e: 354 return 1, [str(e)] 355 356 return self.yum_cli_commands[self.basecmd].doCommand(self, self.basecmd, self.extcmds)
357
358 - def doTransaction(self):
359 """takes care of package downloading, checking, user confirmation and actually 360 RUNNING the transaction""" 361 362 # just make sure there's not, well, nothing to do 363 if len(self.tsInfo) == 0: 364 self.verbose_logger.info(_('Trying to run the transaction but nothing to do. Exiting.')) 365 return 1 366 367 # NOTE: In theory we can skip this in -q -y mode, for a slight perf. 368 # gain. But it's probably doom to have a different code path. 369 lsts = self.listTransaction() 370 if self.verbose_logger.isEnabledFor(yum.logginglevels.INFO_1): 371 self.verbose_logger.log(yum.logginglevels.INFO_1, lsts) 372 elif not self.conf.assumeyes: 373 # If we are in quiet, and assumeyes isn't on we want to output 374 # at least the transaction list anyway. 375 self.logger.warn(lsts) 376 377 # Check which packages have to be downloaded 378 downloadpkgs = [] 379 stuff_to_download = False 380 install_only = True 381 for txmbr in self.tsInfo.getMembers(): 382 if txmbr.ts_state not in ('i', 'u'): 383 install_only = False 384 else: 385 stuff_to_download = True 386 po = txmbr.po 387 if po: 388 downloadpkgs.append(po) 389 390 # Close the connection to the rpmdb so that rpm doesn't hold the SIGINT 391 # handler during the downloads. self.ts is reinitialised later in this 392 # function anyway (initActionTs). 393 self.ts.close() 394 395 # Report the total download size to the user, so he/she can base 396 # the answer on this info 397 if stuff_to_download: 398 self.reportDownloadSize(downloadpkgs, install_only) 399 400 # confirm with user 401 if self._promptWanted(): 402 if not self.userconfirm(): 403 self.verbose_logger.info(_('Exiting on user Command')) 404 return 1 405 406 self.verbose_logger.log(yum.logginglevels.INFO_2, 407 _('Downloading Packages:')) 408 problems = self.downloadPkgs(downloadpkgs, callback_total=self.download_callback_total_cb) 409 410 if len(problems) > 0: 411 errstring = '' 412 errstring += _('Error Downloading Packages:\n') 413 for key in problems: 414 errors = yum.misc.unique(problems[key]) 415 for error in errors: 416 errstring += ' %s: %s\n' % (key, error) 417 raise yum.Errors.YumBaseError, errstring 418 419 # Check GPG signatures 420 if self.gpgsigcheck(downloadpkgs) != 0: 421 return 1 422 423 if self.conf.rpm_check_debug: 424 rcd_st = time.time() 425 self.verbose_logger.log(yum.logginglevels.INFO_2, 426 _('Running rpm_check_debug')) 427 msgs = self._run_rpm_check_debug() 428 if msgs: 429 rpmlib_only = True 430 for msg in msgs: 431 if msg.startswith('rpmlib('): 432 continue 433 rpmlib_only = False 434 if rpmlib_only: 435 print _("ERROR You need to update rpm to handle:") 436 else: 437 print _('ERROR with rpm_check_debug vs depsolve:') 438 439 for msg in msgs: 440 print to_utf8(msg) 441 442 if rpmlib_only: 443 return 1, [_('RPM needs to be updated')] 444 return 1, [_('Please report this error in %s') % self.conf.bugtracker_url] 445 446 self.verbose_logger.debug('rpm_check_debug time: %0.3f' % (time.time() - rcd_st)) 447 448 tt_st = time.time() 449 self.verbose_logger.log(yum.logginglevels.INFO_2, 450 _('Running Transaction Test')) 451 if not self.conf.diskspacecheck: 452 self.tsInfo.probFilterFlags.append(rpm.RPMPROB_FILTER_DISKSPACE) 453 454 455 testcb = RPMTransaction(self, test=True) 456 457 self.initActionTs() 458 # save our dsCallback out 459 dscb = self.dsCallback 460 self.dsCallback = None # dumb, dumb dumb dumb! 461 self.populateTs(keepold=0) # sigh 462 tserrors = self.ts.test(testcb) 463 del testcb 464 465 if len(tserrors) > 0: 466 errstring = _('Transaction Check Error:\n') 467 for descr in tserrors: 468 errstring += ' %s\n' % to_unicode(descr) 469 470 raise yum.Errors.YumBaseError, errstring + '\n' + \ 471 self.errorSummary(errstring) 472 self.verbose_logger.log(yum.logginglevels.INFO_2, 473 _('Transaction Test Succeeded')) 474 del self.ts 475 476 self.verbose_logger.debug('Transaction Test time: %0.3f' % (time.time() - tt_st)) 477 478 # unset the sigquit handler 479 signal.signal(signal.SIGQUIT, signal.SIG_DFL) 480 481 ts_st = time.time() 482 self.initActionTs() # make a new, blank ts to populate 483 self.populateTs(keepold=0) # populate the ts 484 self.ts.check() #required for ordering 485 self.ts.order() # order 486 487 # put back our depcheck callback 488 self.dsCallback = dscb 489 # setup our rpm ts callback 490 cb = RPMTransaction(self, 491 display=output.YumCliRPMCallBack(weakref(self))) 492 if self.conf.debuglevel < 2: 493 cb.display.output = False 494 495 self.verbose_logger.log(yum.logginglevels.INFO_2, _('Running Transaction')) 496 resultobject = self.runTransaction(cb=cb) 497 498 self.verbose_logger.debug('Transaction time: %0.3f' % (time.time() - ts_st)) 499 # close things 500 self.verbose_logger.log(yum.logginglevels.INFO_1, 501 self.postTransactionOutput()) 502 503 # put back the sigquit handler 504 signal.signal(signal.SIGQUIT, sigquit) 505 506 return resultobject.return_code
507
508 - def gpgsigcheck(self, pkgs):
509 '''Perform GPG signature verification on the given packages, installing 510 keys if possible 511 512 Returns non-zero if execution should stop (user abort). 513 Will raise YumBaseError if there's a problem 514 ''' 515 for po in pkgs: 516 result, errmsg = self.sigCheckPkg(po) 517 518 if result == 0: 519 # Verified ok, or verify not req'd 520 continue 521 522 elif result == 1: 523 if not sys.stdin.isatty() and not self.conf.assumeyes: 524 raise yum.Errors.YumBaseError, \ 525 _('Refusing to automatically import keys when running ' \ 526 'unattended.\nUse "-y" to override.') 527 528 # the callback here expects to be able to take options which 529 # userconfirm really doesn't... so fake it 530 self.getKeyForPackage(po, lambda x, y, z: self.userconfirm()) 531 532 else: 533 # Fatal error 534 raise yum.Errors.YumBaseError, errmsg 535 536 return 0
537
538 - def _maybeYouMeant(self, arg):
539 """ If install argument doesn't match with case, tell the user. """ 540 matches = self.doPackageLists(patterns=[arg], ignore_case=True) 541 matches = matches.installed + matches.available 542 matches = set(map(lambda x: x.name, matches)) 543 if matches: 544 msg = self.fmtKeyValFill(_(' * Maybe you meant: '), 545 ", ".join(matches)) 546 self.verbose_logger.log(yum.logginglevels.INFO_2, msg)
547
548 - def _checkMaybeYouMeant(self, arg, always_output=True):
549 """ If the update/remove argument doesn't match with case, or due 550 to not being installed, tell the user. """ 551 # always_output is a wart due to update/remove not producing the 552 # same output. 553 matches = self.doPackageLists(patterns=[arg], ignore_case=False) 554 if (matches.installed or (not matches.available and 555 self.returnInstalledPackagesByDep(arg))): 556 return # Found a match so ignore 557 hibeg = self.term.MODE['bold'] 558 hiend = self.term.MODE['normal'] 559 if matches.available: 560 self.verbose_logger.log(yum.logginglevels.INFO_2, 561 _('Package(s) %s%s%s available, but not installed.'), 562 hibeg, arg, hiend) 563 return 564 565 # No package name, so do the maybeYouMeant thing here too 566 matches = self.doPackageLists(patterns=[arg], ignore_case=True) 567 if not matches.installed and matches.available: 568 self.verbose_logger.log(yum.logginglevels.INFO_2, 569 _('Package(s) %s%s%s available, but not installed.'), 570 hibeg, arg, hiend) 571 return 572 matches = set(map(lambda x: x.name, matches.installed)) 573 if always_output or matches: 574 self.verbose_logger.log(yum.logginglevels.INFO_2, 575 _('No package %s%s%s available.'), 576 hibeg, arg, hiend) 577 if matches: 578 msg = self.fmtKeyValFill(_(' * Maybe you meant: '), 579 ", ".join(matches)) 580 self.verbose_logger.log(yum.logginglevels.INFO_2, msg)
581
582 - def installPkgs(self, userlist):
583 """Attempts to take the user specified list of packages/wildcards 584 and install them, or if they are installed, update them to a newer 585 version. If a complete version number if specified, attempt to 586 upgrade (or downgrade if they have been removed) them to the 587 specified version""" 588 # get the list of available packages 589 # iterate over the user's list 590 # add packages to Transaction holding class if they match. 591 # if we've added any packages to the transaction then return 2 and a string 592 # if we've hit a snag, return 1 and the failure explanation 593 # if we've got nothing to do, return 0 and a 'nothing available to install' string 594 595 oldcount = len(self.tsInfo) 596 597 for arg in userlist: 598 if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or 599 os.path.exists(arg))): 600 self.localInstall(filelist=[arg]) 601 continue # it was something on disk and it ended in rpm 602 # no matter what we don't go looking at repos 603 try: 604 self.install(pattern=arg) 605 except yum.Errors.InstallError: 606 self.verbose_logger.log(yum.logginglevels.INFO_2, 607 _('No package %s%s%s available.'), 608 self.term.MODE['bold'], arg, 609 self.term.MODE['normal']) 610 self._maybeYouMeant(arg) 611 if len(self.tsInfo) > oldcount: 612 return 2, [_('Package(s) to install')] 613 return 0, [_('Nothing to do')]
614
615 - def updatePkgs(self, userlist, quiet=0):
616 """take user commands and populate transaction wrapper with 617 packages to be updated""" 618 619 # if there is no userlist, then do global update below 620 # this is probably 90% of the calls 621 # if there is a userlist then it's for updating pkgs, not obsoleting 622 623 oldcount = len(self.tsInfo) 624 if len(userlist) == 0: # simple case - do them all 625 self.update() 626 627 else: 628 # go through the userlist - look for items that are local rpms. If we find them 629 # pass them off to localInstall() and then move on 630 localupdates = [] 631 for item in userlist: 632 if (item.endswith('.rpm') and (yum.misc.re_remote_url(item) or 633 os.path.exists(item))): 634 localupdates.append(item) 635 636 if len(localupdates) > 0: 637 self.localInstall(filelist=localupdates, updateonly=1) 638 for item in localupdates: 639 userlist.remove(item) 640 641 for arg in userlist: 642 if not self.update(pattern=arg): 643 self._checkMaybeYouMeant(arg) 644 645 if len(self.tsInfo) > oldcount: 646 change = len(self.tsInfo) - oldcount 647 msg = _('%d packages marked for Update') % change 648 return 2, [msg] 649 else: 650 return 0, [_('No Packages marked for Update')]
651
652 - def erasePkgs(self, userlist):
653 """take user commands and populate a transaction wrapper with packages 654 to be erased/removed""" 655 656 oldcount = len(self.tsInfo) 657 658 for arg in userlist: 659 if not self.remove(pattern=arg): 660 self._checkMaybeYouMeant(arg, always_output=False) 661 662 if len(self.tsInfo) > oldcount: 663 change = len(self.tsInfo) - oldcount 664 msg = _('%d packages marked for removal') % change 665 return 2, [msg] 666 else: 667 return 0, [_('No Packages marked for removal')]
668
669 - def downgradePkgs(self, userlist):
670 """Attempts to take the user specified list of packages/wildcards 671 and downgrade them. If a complete version number if specified, 672 attempt to downgrade them to the specified version""" 673 674 oldcount = len(self.tsInfo) 675 676 for arg in userlist: 677 if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or 678 os.path.exists(arg))): 679 self.downgradeLocal(arg) 680 continue # it was something on disk and it ended in rpm 681 # no matter what we don't go looking at repos 682 683 try: 684 self.downgrade(pattern=arg) 685 except yum.Errors.DowngradeError: 686 self.verbose_logger.log(yum.logginglevels.INFO_2, 687 _('No package %s%s%s available.'), 688 self.term.MODE['bold'], arg, 689 self.term.MODE['normal']) 690 self._maybeYouMeant(arg) 691 if len(self.tsInfo) > oldcount: 692 return 2, [_('Package(s) to downgrade')] 693 return 0, [_('Nothing to do')]
694
695 - def reinstallPkgs(self, userlist):
696 """Attempts to take the user specified list of packages/wildcards 697 and reinstall them. """ 698 699 oldcount = len(self.tsInfo) 700 701 for arg in userlist: 702 if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or 703 os.path.exists(arg))): 704 self.reinstallLocal(arg) 705 continue # it was something on disk and it ended in rpm 706 # no matter what we don't go looking at repos 707 708 try: 709 self.reinstall(pattern=arg) 710 except yum.Errors.ReinstallRemoveError: 711 self._checkMaybeYouMeant(arg, always_output=False) 712 except yum.Errors.ReinstallInstallError, e: 713 ipkg = self.rpmdb.returnPackages(patterns=[arg])[0] 714 xmsg = '' 715 if 'from_repo' in ipkg.yumdb_info: 716 xmsg = ipkg.yumdb_info.from_repo 717 xmsg = _(' (from %s)') % xmsg 718 self.verbose_logger.log(yum.logginglevels.INFO_2, 719 _('Installed package %s%s%s%s not available.'), 720 self.term.MODE['bold'], ipkg, 721 self.term.MODE['normal'], xmsg) 722 except yum.Errors.ReinstallError, e: 723 assert False, "Shouldn't happen, but just in case" 724 self.verbose_logger.log(yum.logginglevels.INFO_2, e) 725 if len(self.tsInfo) > oldcount: 726 return 2, [_('Package(s) to reinstall')] 727 return 0, [_('Nothing to do')]
728
729 - def localInstall(self, filelist, updateonly=0):
730 """handles installs/updates of rpms provided on the filesystem in a 731 local dir (ie: not from a repo)""" 732 733 # read in each package into a YumLocalPackage Object 734 # append it to self.localPackages 735 # check if it can be installed or updated based on nevra versus rpmdb 736 # don't import the repos until we absolutely need them for depsolving 737 738 if len(filelist) == 0: 739 return 0, [_('No Packages Provided')] 740 741 installing = False 742 for pkg in filelist: 743 txmbrs = self.installLocal(pkg, updateonly=updateonly) 744 if txmbrs: 745 installing = True 746 747 if installing: 748 return 2, [_('Package(s) to install')] 749 return 0, [_('Nothing to do')]
750
751 - def returnPkgLists(self, extcmds, installed_available=False):
752 """Returns packages lists based on arguments on the cli.returns a 753 GenericHolder instance with the following lists defined: 754 available = list of packageObjects 755 installed = list of packageObjects 756 updates = tuples of packageObjects (updating, installed) 757 extras = list of packageObjects 758 obsoletes = tuples of packageObjects (obsoleting, installed) 759 recent = list of packageObjects 760 761 installed_available = that the available package list is present 762 as .hidden_available when doing any of: 763 all/available/installed 764 """ 765 766 special = ['available', 'installed', 'all', 'extras', 'updates', 'recent', 767 'obsoletes'] 768 769 pkgnarrow = 'all' 770 done_hidden_available = False 771 done_hidden_installed = False 772 if len(extcmds) > 0: 773 if installed_available and extcmds[0] == 'installed': 774 done_hidden_available = True 775 extcmds.pop(0) 776 elif installed_available and extcmds[0] == 'available': 777 done_hidden_installed = True 778 extcmds.pop(0) 779 elif extcmds[0] in special: 780 pkgnarrow = extcmds.pop(0) 781 782 ypl = self.doPackageLists(pkgnarrow=pkgnarrow, patterns=extcmds, 783 ignore_case=True) 784 if self.conf.showdupesfromrepos: 785 ypl.available += ypl.reinstall_available 786 787 if installed_available: 788 ypl.hidden_available = ypl.available 789 ypl.hidden_installed = ypl.installed 790 if done_hidden_available: 791 ypl.available = [] 792 if done_hidden_installed: 793 ypl.installed = [] 794 return ypl
795
796 - def search(self, args):
797 """cli wrapper method for module search function, searches simple 798 text tags in a package object""" 799 800 # call the yum module search function with lists of tags to search 801 # and what to search for 802 # display the list of matches 803 804 searchlist = ['name', 'summary', 'description', 'url'] 805 dups = self.conf.showdupesfromrepos 806 args = map(to_unicode, args) 807 matching = self.searchGenerator(searchlist, args, 808 showdups=dups, keys=True) 809 810 okeys = set() 811 akeys = set() 812 for (po, keys, matched_value) in matching: 813 if keys != okeys: 814 if akeys: 815 print "" 816 # Print them in the order they were passed 817 used_keys = [arg for arg in args if arg in keys] 818 print self.fmtSection(_('Matched: %s') % ", ".join(used_keys)) 819 okeys = keys 820 akeys.update(keys) 821 self.matchcallback(po, matched_value, args) 822 823 for arg in args: 824 if arg not in akeys: 825 self.logger.warning(_('Warning: No matches found for: %s'), arg) 826 827 if not akeys: 828 return 0, [_('No Matches found')] 829 return 0, matching
830
831 - def deplist(self, args):
832 """cli wrapper method for findDeps method takes a list of packages and 833 returns a formatted deplist for that package""" 834 835 pkgs = [] 836 for arg in args: 837 if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or 838 os.path.exists(arg))): 839 thispkg = yum.packages.YumUrlPackage(self, self.ts, arg) 840 pkgs.append(thispkg) 841 else: 842 ematch, match, unmatch = self.pkgSack.matchPackageNames([arg]) 843 for po in ematch + match: 844 pkgs.append(po) 845 846 results = self.findDeps(pkgs) 847 self.depListOutput(results) 848 849 return 0, []
850
851 - def provides(self, args):
852 """use the provides methods in the rpmdb and pkgsack to produce a list 853 of items matching the provides strings. This is a cli wrapper to the 854 module""" 855 856 old_sdup = self.conf.showdupesfromrepos 857 # For output, as searchPackageProvides() is always in showdups mode 858 self.conf.showdupesfromrepos = True 859 cb = self.matchcallback_verbose 860 matching = self.searchPackageProvides(args, callback=cb, 861 callback_has_matchfor=True) 862 self.conf.showdupesfromrepos = old_sdup 863 864 if len(matching) == 0: 865 for arg in args: 866 if '*' in arg or (arg and arg[0] == '/'): 867 continue 868 self.logger.warning(_('Warning: 3.0.x versions of yum would erroneously match against filenames.\n You can use "%s*/%s%s" and/or "%s*bin/%s%s" to get that behaviour'), 869 self.term.MODE['bold'], arg, 870 self.term.MODE['normal'], 871 self.term.MODE['bold'], arg, 872 self.term.MODE['normal']) 873 return 0, ['No Matches found'] 874 875 return 0, []
876
877 - def resolveDepCli(self, args):
878 """returns a package (one per user arg) that provide the supplied arg""" 879 880 for arg in args: 881 try: 882 pkg = self.returnPackageByDep(arg) 883 except yum.Errors.YumBaseError: 884 self.logger.critical(_('No Package Found for %s'), arg) 885 else: 886 msg = '%s:%s-%s-%s.%s' % (pkg.epoch, pkg.name, pkg.version, pkg.release, pkg.arch) 887 self.verbose_logger.info(msg) 888 889 return 0, []
890
891 - def cleanCli(self, userlist):
892 hdrcode = pkgcode = xmlcode = dbcode = expccode = 0 893 pkgresults = hdrresults = xmlresults = dbresults = expcresults = [] 894 if 'all' in userlist: 895 self.verbose_logger.log(yum.logginglevels.INFO_2, 896 _('Cleaning up Everything')) 897 pkgcode, pkgresults = self.cleanPackages() 898 hdrcode, hdrresults = self.cleanHeaders() 899 xmlcode, xmlresults = self.cleanMetadata() 900 dbcode, dbresults = self.cleanSqlite() 901 rpmcode, rpmresults = self.cleanRpmDB() 902 self.plugins.run('clean') 903 904 code = hdrcode + pkgcode + xmlcode + dbcode + rpmcode 905 results = (hdrresults + pkgresults + xmlresults + dbresults + 906 rpmresults) 907 for msg in results: 908 self.logger.debug(msg) 909 return code, [] 910 911 if 'headers' in userlist: 912 self.logger.debug(_('Cleaning up Headers')) 913 hdrcode, hdrresults = self.cleanHeaders() 914 if 'packages' in userlist: 915 self.logger.debug(_('Cleaning up Packages')) 916 pkgcode, pkgresults = self.cleanPackages() 917 if 'metadata' in userlist: 918 self.logger.debug(_('Cleaning up xml metadata')) 919 xmlcode, xmlresults = self.cleanMetadata() 920 if 'dbcache' in userlist or 'metadata' in userlist: 921 self.logger.debug(_('Cleaning up database cache')) 922 dbcode, dbresults = self.cleanSqlite() 923 if 'expire-cache' in userlist or 'metadata' in userlist: 924 self.logger.debug(_('Cleaning up expire-cache metadata')) 925 expccode, expcresults = self.cleanExpireCache() 926 if 'rpmdb' in userlist: 927 self.logger.debug(_('Cleaning up cached rpmdb data')) 928 expccode, expcresults = self.cleanRpmDB() 929 if 'plugins' in userlist: 930 self.logger.debug(_('Cleaning up plugins')) 931 self.plugins.run('clean') 932 933 code = hdrcode + pkgcode + xmlcode + dbcode + expccode 934 results = hdrresults + pkgresults + xmlresults + dbresults + expcresults 935 for msg in results: 936 self.verbose_logger.log(yum.logginglevels.INFO_2, msg) 937 return code, []
938
939 - def returnGroupLists(self, userlist):
940 941 uservisible=1 942 943 if len(userlist) > 0: 944 if userlist[0] == 'hidden': 945 uservisible=0 946 userlist.pop(0) 947 if not userlist: 948 userlist = None # Match everything... 949 950 installed, available = self.doGroupLists(uservisible=uservisible, 951 patterns=userlist) 952 953 if len(installed) > 0: 954 self.verbose_logger.log(yum.logginglevels.INFO_2, 955 _('Installed Groups:')) 956 for group in installed: 957 if self.verbose_logger.isEnabledFor(yum.logginglevels.DEBUG_3): 958 self.verbose_logger.log(yum.logginglevels.INFO_2, 959 ' %s (%s)', group.ui_name, 960 group.groupid) 961 else: 962 self.verbose_logger.log(yum.logginglevels.INFO_2, 963 ' %s', group.ui_name) 964 965 if len(available) > 0: 966 self.verbose_logger.log(yum.logginglevels.INFO_2, 967 _('Available Groups:')) 968 for group in available: 969 if self.verbose_logger.isEnabledFor(yum.logginglevels.DEBUG_3): 970 self.verbose_logger.log(yum.logginglevels.INFO_2, 971 ' %s (%s)', group.ui_name, 972 group.groupid) 973 else: 974 self.verbose_logger.log(yum.logginglevels.INFO_2, 975 ' %s', group.ui_name) 976 977 return 0, [_('Done')]
978
979 - def returnGroupInfo(self, userlist):
980 """returns complete information on a list of groups""" 981 for strng in userlist: 982 group_matched = False 983 for group in self.comps.return_groups(strng): 984 self.displayPkgsInGroups(group) 985 group_matched = True 986 987 if not group_matched: 988 self.logger.error(_('Warning: Group %s does not exist.'), strng) 989 990 return 0, []
991
992 - def installGroups(self, grouplist):
993 """for each group requested do 'selectGroup' on them.""" 994 995 pkgs_used = [] 996 997 for group_string in grouplist: 998 group_matched = False 999 for group in self.comps.return_groups(group_string): 1000 group_matched = True 1001 1002 1003 try: 1004 txmbrs = self.selectGroup(group.groupid) 1005 except yum.Errors.GroupsError: 1006 self.logger.critical(_('Warning: Group %s does not exist.'), group_string) 1007 continue 1008 else: 1009 pkgs_used.extend(txmbrs) 1010 1011 if not group_matched: 1012 self.logger.error(_('Warning: Group %s does not exist.'), group_string) 1013 continue 1014 1015 if not pkgs_used: 1016 return 0, [_('No packages in any requested group available to install or update')] 1017 else: 1018 return 2, [_('%d Package(s) to Install') % len(pkgs_used)]
1019
1020 - def removeGroups(self, grouplist):
1021 """Remove only packages of the named group(s). Do not recurse.""" 1022 1023 pkgs_used = [] 1024 for group_string in grouplist: 1025 try: 1026 txmbrs = self.groupRemove(group_string) 1027 except yum.Errors.GroupsError: 1028 self.logger.critical(_('No group named %s exists'), group_string) 1029 continue 1030 else: 1031 pkgs_used.extend(txmbrs) 1032 1033 if not pkgs_used: 1034 return 0, [_('No packages to remove from groups')] 1035 else: 1036 return 2, [_('%d Package(s) to remove') % len(pkgs_used)]
1037 1038 1039
1040 - def _promptWanted(self):
1041 # shortcut for the always-off/always-on options 1042 if self.conf.assumeyes: 1043 return False 1044 if self.conf.alwaysprompt: 1045 return True 1046 1047 # prompt if: 1048 # package was added to fill a dependency 1049 # package is being removed 1050 # package wasn't explictly given on the command line 1051 for txmbr in self.tsInfo.getMembers(): 1052 if txmbr.isDep or \ 1053 txmbr.ts_state == 'e' or \ 1054 txmbr.name not in self.extcmds: 1055 return True 1056 1057 # otherwise, don't prompt 1058 return False
1059
1060 - def usage(self):
1061 ''' Print out command line usage ''' 1062 sys.stdout.write(self.optparser.format_help())
1063
1064 - def shellUsage(self):
1065 ''' Print out the shell usage ''' 1066 sys.stdout.write(self.optparser.get_usage())
1067
1068 - def _installable(self, pkg, ematch=False):
1069 1070 """check if the package is reasonably installable, true/false""" 1071 1072 exactarchlist = self.conf.exactarchlist 1073 # we look through each returned possibility and rule out the 1074 # ones that we obviously can't use 1075 1076 if self.rpmdb.contains(po=pkg): 1077 self.verbose_logger.log(yum.logginglevels.DEBUG_3, 1078 _('Package %s is already installed, skipping'), pkg) 1079 return False 1080 1081 # everything installed that matches the name 1082 installedByKey = self.rpmdb.searchNevra(name=pkg.name) 1083 comparable = [] 1084 for instpo in installedByKey: 1085 if isMultiLibArch(instpo.arch) == isMultiLibArch(pkg.arch): 1086 comparable.append(instpo) 1087 else: 1088 self.verbose_logger.log(yum.logginglevels.DEBUG_3, 1089 _('Discarding non-comparable pkg %s.%s'), instpo.name, instpo.arch) 1090 continue 1091 1092 # go through each package 1093 if len(comparable) > 0: 1094 for instpo in comparable: 1095 if pkg.verGT(instpo): # we're newer - this is an update, pass to them 1096 if instpo.name in exactarchlist: 1097 if pkg.arch == instpo.arch: 1098 return True 1099 else: 1100 return True 1101 1102 elif pkg.verEQ(instpo): # same, ignore 1103 return False 1104 1105 elif pkg.verLT(instpo): # lesser, check if the pkgtup is an exactmatch 1106 # if so then add it to be installed 1107 # if it can be multiply installed 1108 # this is where we could handle setting 1109 # it to be an 'oldpackage' revert. 1110 1111 if ematch and self.allowedMultipleInstalls(pkg): 1112 return True 1113 1114 else: # we've not got any installed that match n or n+a 1115 self.verbose_logger.log(yum.logginglevels.DEBUG_1, _('No other %s installed, adding to list for potential install'), pkg.name) 1116 return True 1117 1118 return False
1119
1120 -class YumOptionParser(OptionParser):
1121 '''Subclass that makes some minor tweaks to make OptionParser do things the 1122 "yum way". 1123 ''' 1124
1125 - def __init__(self,base, **kwargs):
1126 # check if this is called with a utils=True/False parameter 1127 if 'utils' in kwargs: 1128 self._utils = kwargs['utils'] 1129 del kwargs['utils'] 1130 else: 1131 self._utils = False 1132 OptionParser.__init__(self, **kwargs) 1133 self.logger = logging.getLogger("yum.cli") 1134 self.base = base 1135 self.plugin_option_group = OptionGroup(self, _("Plugin Options")) 1136 self.add_option_group(self.plugin_option_group) 1137 1138 self._addYumBasicOptions()
1139
1140 - def error(self, msg):
1141 '''This method is overridden so that error output goes to logger. ''' 1142 self.print_usage() 1143 self.logger.critical(_("Command line error: %s"), msg) 1144 sys.exit(1)
1145
1146 - def firstParse(self,args):
1147 # Parse only command line options that affect basic yum setup 1148 try: 1149 args = _filtercmdline( 1150 ('--noplugins','--version','-q', '-v', "--quiet", "--verbose"), 1151 ('-c', '-d', '-e', '--installroot', 1152 '--disableplugin', '--enableplugin', '--releasever'), 1153 args) 1154 except ValueError, arg: 1155 self.base.usage() 1156 print >> sys.stderr, (_("\n\n%s: %s option requires an argument") % 1157 ('Command line error', arg)) 1158 sys.exit(1) 1159 return self.parse_args(args=args)[0]
1160 1161 @staticmethod
1162 - def _splitArg(seq):
1163 """ Split all strings in seq, at "," and whitespace. 1164 Returns a new list. """ 1165 ret = [] 1166 for arg in seq: 1167 ret.extend(arg.replace(",", " ").split()) 1168 return ret
1169
1170 - def setupYumConfig(self, args=None):
1171 # Now parse the command line for real 1172 if not args: 1173 (opts, cmds) = self.parse_args() 1174 else: 1175 (opts, cmds) = self.parse_args(args=args) 1176 1177 # Let the plugins know what happened on the command line 1178 self.base.plugins.setCmdLine(opts, cmds) 1179 1180 try: 1181 # config file is parsed and moving us forward 1182 # set some things in it. 1183 1184 # Handle remaining options 1185 if opts.assumeyes: 1186 self.base.conf.assumeyes =1 1187 1188 # Instead of going cache-only for a non-root user, try to use a 1189 # user writable cachedir. If that fails fall back to cache-only. 1190 if opts.cacheonly: 1191 self.base.conf.cache = 1 1192 elif not self.base.setCacheDir(): 1193 self.base.conf.cache = 1 1194 1195 if opts.obsoletes: 1196 self.base.conf.obsoletes = 1 1197 1198 if opts.installroot: 1199 self.base.conf.installroot = opts.installroot 1200 1201 if opts.skipbroken: 1202 self.base.conf.skip_broken = True 1203 1204 if opts.showdupesfromrepos: 1205 self.base.conf.showdupesfromrepos = True 1206 1207 if opts.color not in (None, 'auto', 'always', 'never', 1208 'tty', 'if-tty', 'yes', 'no', 'on', 'off'): 1209 raise ValueError, _("--color takes one of: auto, always, never") 1210 elif opts.color is None: 1211 if self.base.conf.color != 'auto': 1212 self.base.term.reinit(color=self.base.conf.color) 1213 else: 1214 _remap = {'tty' : 'auto', 'if-tty' : 'auto', 1215 '1' : 'always', 'true' : 'always', 1216 'yes' : 'always', 'on' : 'always', 1217 '0' : 'always', 'false' : 'always', 1218 'no' : 'never', 'off' : 'never'} 1219 opts.color = _remap.get(opts.color, opts.color) 1220 if opts.color != 'auto': 1221 self.base.term.reinit(color=opts.color) 1222 1223 if opts.disableexcludes: 1224 disable_excludes = self._splitArg(opts.disableexcludes) 1225 else: 1226 disable_excludes = [] 1227 self.base.conf.disable_excludes = disable_excludes 1228 1229 for exclude in self._splitArg(opts.exclude): 1230 try: 1231 excludelist = self.base.conf.exclude 1232 excludelist.append(exclude) 1233 self.base.conf.exclude = excludelist 1234 except yum.Errors.ConfigError, e: 1235 self.logger.critical(e) 1236 self.base.usage() 1237 sys.exit(1) 1238 1239 if opts.rpmverbosity is not None: 1240 self.base.conf.rpmverbosity = opts.rpmverbosity 1241 1242 # setup the progress bars/callbacks 1243 self.base.setupProgressCallbacks() 1244 # setup the callbacks to import gpg pubkeys and confirm them 1245 self.base.setupKeyImportCallbacks() 1246 1247 # Process repo enables and disables in order 1248 for opt, repoexp in opts.repos: 1249 try: 1250 if opt == '--enablerepo': 1251 self.base.repos.enableRepo(repoexp) 1252 elif opt == '--disablerepo': 1253 self.base.repos.disableRepo(repoexp) 1254 except yum.Errors.ConfigError, e: 1255 self.logger.critical(e) 1256 self.base.usage() 1257 sys.exit(1) 1258 1259 # make sure the added repos are setup. 1260 if len(opts.repos) > 0: 1261 self.base._getRepos(doSetup=True) 1262 1263 # Disable all gpg key checking, if requested. 1264 if opts.nogpgcheck: 1265 self.base.conf.gpgcheck = False 1266 self.base.conf.repo_gpgcheck = False 1267 for repo in self.base.repos.listEnabled(): 1268 repo.gpgcheck = False 1269 repo.repo_gpgcheck = False 1270 1271 except ValueError, e: 1272 self.logger.critical(_('Options Error: %s'), e) 1273 self.base.usage() 1274 sys.exit(1) 1275 1276 return opts, cmds
1277
1278 - def getRoot(self,opts):
1279 # If the conf file is inside the installroot - use that. 1280 # otherwise look for it in the normal root 1281 if opts.installroot: 1282 if os.access(opts.installroot+'/'+opts.conffile, os.R_OK): 1283 opts.conffile = opts.installroot+'/'+opts.conffile 1284 elif opts.conffile == '/etc/yum/yum.conf': 1285 # check if /installroot/etc/yum.conf exists. 1286 if os.access(opts.installroot+'/etc/yum.conf', os.R_OK): 1287 opts.conffile = opts.installroot+'/etc/yum.conf' 1288 root=opts.installroot 1289 else: 1290 root = '/' 1291 return root
1292
1293 - def _wrapOptParseUsage(self, opt, value, parser, *args, **kwargs):
1294 self.base.usage() 1295 self.exit()
1296
1297 - def _addYumBasicOptions(self):
1298 def repo_optcb(optobj, opt, value, parser): 1299 '''Callback for the enablerepo and disablerepo option. 1300 1301 Combines the values given for these options while preserving order 1302 from command line. 1303 ''' 1304 dest = eval('parser.values.%s' % optobj.dest) 1305 dest.append((opt, value))
1306 1307 if self._utils: 1308 group = OptionGroup(self, "Yum Base Options") 1309 self.add_option_group(group) 1310 else: 1311 group = self 1312 1313 # Note that we can't use the default action="help" because of the 1314 # fact that print_help() unconditionally does .encode() ... which is 1315 # bad on unicode input. 1316 group.conflict_handler = "resolve" 1317 group.add_option("-h", "--help", action="callback", 1318 callback=self._wrapOptParseUsage, 1319 help=_("show this help message and exit")) 1320 group.conflict_handler = "error" 1321 1322 group.add_option("-t", "--tolerant", action="store_true", 1323 help=_("be tolerant of errors")) 1324 group.add_option("-C", "--cacheonly", dest="cacheonly", 1325 action="store_true", 1326 help=_("run entirely from system cache, don't update cache")) 1327 group.add_option("-c", "--config", dest="conffile", 1328 default='/etc/yum/yum.conf', 1329 help=_("config file location"), metavar='[config file]') 1330 group.add_option("-R", "--randomwait", dest="sleeptime", type='int', 1331 default=None, 1332 help=_("maximum command wait time"), metavar='[minutes]') 1333 group.add_option("-d", "--debuglevel", dest="debuglevel", default=None, 1334 help=_("debugging output level"), type='int', 1335 metavar='[debug level]') 1336 group.add_option("--showduplicates", dest="showdupesfromrepos", 1337 action="store_true", 1338 help=_("show duplicates, in repos, in list/search commands")) 1339 group.add_option("-e", "--errorlevel", dest="errorlevel", default=None, 1340 help=_("error output level"), type='int', 1341 metavar='[error level]') 1342 group.add_option("", "--rpmverbosity", default=None, 1343 help=_("debugging output level for rpm"), 1344 metavar='[debug level name]') 1345 group.add_option("-q", "--quiet", dest="quiet", action="store_true", 1346 help=_("quiet operation")) 1347 group.add_option("-v", "--verbose", dest="verbose", action="store_true", 1348 help=_("verbose operation")) 1349 group.add_option("-y", "--assumeyes", dest="assumeyes", 1350 action="store_true", help=_("answer yes for all questions")) 1351 group.add_option("--version", action="store_true", 1352 help=_("show Yum version and exit")) 1353 group.add_option("--installroot", help=_("set install root"), 1354 metavar='[path]') 1355 group.add_option("--enablerepo", action='callback', 1356 type='string', callback=repo_optcb, dest='repos', default=[], 1357 help=_("enable one or more repositories (wildcards allowed)"), 1358 metavar='[repo]') 1359 group.add_option("--disablerepo", action='callback', 1360 type='string', callback=repo_optcb, dest='repos', default=[], 1361 help=_("disable one or more repositories (wildcards allowed)"), 1362 metavar='[repo]') 1363 group.add_option("-x", "--exclude", default=[], action="append", 1364 help=_("exclude package(s) by name or glob"), metavar='[package]') 1365 group.add_option("", "--disableexcludes", default=[], action="append", 1366 help=_("disable exclude from main, for a repo or for everything"), 1367 metavar='[repo]') 1368 group.add_option("--obsoletes", action="store_true", 1369 help=_("enable obsoletes processing during updates")) 1370 group.add_option("--noplugins", action="store_true", 1371 help=_("disable Yum plugins")) 1372 group.add_option("--nogpgcheck", action="store_true", 1373 help=_("disable gpg signature checking")) 1374 group.add_option("", "--disableplugin", dest="disableplugins", default=[], 1375 action="append", help=_("disable plugins by name"), 1376 metavar='[plugin]') 1377 group.add_option("", "--enableplugin", dest="enableplugins", default=[], 1378 action="append", help=_("enable plugins by name"), 1379 metavar='[plugin]') 1380 group.add_option("--skip-broken", action="store_true", dest="skipbroken", 1381 help=_("skip packages with depsolving problems")) 1382 group.add_option("", "--color", dest="color", default=None, 1383 help=_("control whether color is used")) 1384 group.add_option("", "--releasever", dest="releasever", default=None, 1385 help=_("set value of $releasever in yum config and repo files"))
1386
1387 1388 1389 -def _filtercmdline(novalopts, valopts, args):
1390 '''Keep only specific options from the command line argument list 1391 1392 This function allows us to peek at specific command line options when using 1393 the optparse module. This is useful when some options affect what other 1394 options should be available. 1395 1396 @param novalopts: A sequence of options to keep that don't take an argument. 1397 @param valopts: A sequence of options to keep that take a single argument. 1398 @param args: The command line arguments to parse (as per sys.argv[:1] 1399 @return: A list of strings containing the filtered version of args. 1400 1401 Will raise ValueError if there was a problem parsing the command line. 1402 ''' 1403 out = [] 1404 args = list(args) # Make a copy because this func is destructive 1405 1406 while len(args) > 0: 1407 a = args.pop(0) 1408 if '=' in a: 1409 opt, _ = a.split('=', 1) 1410 if opt in valopts: 1411 out.append(a) 1412 1413 elif a in novalopts: 1414 out.append(a) 1415 1416 elif a in valopts: 1417 if len(args) < 1: 1418 raise ValueError, a 1419 next = args.pop(0) 1420 if next[0] == '-': 1421 raise ValueError, a 1422 1423 out.extend([a, next]) 1424 1425 else: 1426 # Check for single letter options that take a value, where the 1427 # value is right up against the option 1428 for opt in valopts: 1429 if len(opt) == 2 and a.startswith(opt): 1430 out.append(a) 1431 1432 return out
1433