1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 """
19 Classes for subcommands of the yum command line interface.
20 """
21
22 import os
23 import cli
24 from yum import logginglevels
25 from yum import _
26 from yum import misc
27 import yum.Errors
28 import operator
29 import locale
30 import fnmatch
31 import time
32 from yum.i18n import utf8_width, utf8_width_fill, to_unicode
33
34 import yum.config
37 """
38 Verify that the program is being run by the root user.
39
40 @param base: a YumBase object.
41 """
42 if base.conf.uid != 0:
43 base.logger.critical(_('You need to be root to perform this command.'))
44 raise cli.CliError
45
47 if not base.gpgKeyCheck():
48 for repo in base.repos.listEnabled():
49 if (repo.gpgcheck or repo.repo_gpgcheck) and repo.gpgkey == '':
50 msg = _("""
51 You have enabled checking of packages via GPG keys. This is a good thing.
52 However, you do not have any GPG public keys installed. You need to download
53 the keys for packages you wish to install and install them.
54 You can do that by running the command:
55 rpm --import public.gpg.key
56
57
58 Alternatively you can specify the url to the key you would like to use
59 for a repository in the 'gpgkey' option in a repository section and yum
60 will install it for you.
61
62 For more information contact your distribution or package provider.
63 """)
64 base.logger.critical(msg)
65 raise cli.CliError
66
68 if len(extcmds) == 0:
69 base.logger.critical(
70 _('Error: Need to pass a list of pkgs to %s') % basecmd)
71 base.usage()
72 raise cli.CliError
73
79
81 if len(extcmds) == 0:
82 base.logger.critical(_('Error: Need a group or list of groups'))
83 base.usage()
84 raise cli.CliError
85
87 VALID_ARGS = ('headers', 'packages', 'metadata', 'dbcache', 'plugins',
88 'expire-cache', 'rpmdb', 'all')
89
90 if len(extcmds) == 0:
91 base.logger.critical(_('Error: clean requires an option: %s') % (
92 ", ".join(VALID_ARGS)))
93
94 for cmd in extcmds:
95 if cmd not in VALID_ARGS:
96 base.logger.critical(_('Error: invalid clean argument: %r') % cmd)
97 base.usage()
98 raise cli.CliError
99
101 """
102 Verify that the arguments given to 'yum shell' are valid.
103
104 yum shell can be given either no args, or exactly one argument,
105 which is the name of a file. If these are not met,
106 raise cli.CliError.
107 """
108 if len(extcmds) == 0:
109 base.verbose_logger.debug(_("No argument to shell"))
110 elif len(extcmds) == 1:
111 base.verbose_logger.debug(_("Filename passed to shell: %s"),
112 extcmds[0])
113 if not os.path.isfile(extcmds[0]):
114 base.logger.critical(
115 _("File %s given as argument to shell does not exist."),
116 extcmds[0])
117 base.usage()
118 raise cli.CliError
119 else:
120 base.logger.critical(
121 _("Error: more than one file given as argument to shell."))
122 base.usage()
123 raise cli.CliError
124
126
128 self.done_command_once = False
129
134
137
139 """
140 @return: A usage string for the command, including arguments.
141 """
142 raise NotImplementedError
143
145 """
146 @return: A one line summary of what the command does.
147 """
148 raise NotImplementedError
149
150 - def doCheck(self, base, basecmd, extcmds):
152
153 - def doCommand(self, base, basecmd, extcmds):
154 """
155 @return: (exit_code, [ errors ]) where exit_code is:
156 0 = we're done, exit
157 1 = we've errored, exit with error string
158 2 = we've got work yet to do, onto the next stage
159 """
160 return 0, [_('Nothing to do')]
161
162 - def needTs(self, base, basecmd, extcmds):
164
168
170 return _("PACKAGE...")
171
173 return _("Install a package or packages on your system")
174
175 - def doCheck(self, base, basecmd, extcmds):
179
180 - def doCommand(self, base, basecmd, extcmds):
186
190
192 return _("[PACKAGE...]")
193
195 return _("Update a package or packages on your system")
196
197 - def doCheck(self, base, basecmd, extcmds):
200
201 - def doCommand(self, base, basecmd, extcmds):
207
209 """ Get the length of each pkg's column. Add that to data.
210 This "knows" about simpleList and printVer. """
211 na = len(pkg.name) + 1 + len(pkg.arch) + len(indent)
212 ver = len(pkg.version) + 1 + len(pkg.release)
213 rid = len(pkg.ui_from_repo)
214 if pkg.epoch != '0':
215 ver += len(pkg.epoch) + 1
216 for (d, v) in (('na', na), ('ver', ver), ('rid', rid)):
217 data[d].setdefault(v, 0)
218 data[d][v] += 1
219
221 """ Work out the dynamic size of the columns to pass to fmtColumns. """
222 data = {'na' : {}, 'ver' : {}, 'rid' : {}}
223 for lst in (ypl.installed, ypl.available, ypl.extras,
224 ypl.updates, ypl.recent):
225 for pkg in lst:
226 _add_pkg_simple_list_lens(data, pkg)
227 if len(ypl.obsoletes) > 0:
228 for (npkg, opkg) in ypl.obsoletesTuples:
229 _add_pkg_simple_list_lens(data, npkg)
230 _add_pkg_simple_list_lens(data, opkg, indent=" " * 4)
231
232 data = [data['na'], data['ver'], data['rid']]
233 columns = base.calcColumns(data, remainder_column=1)
234 return (-columns[0], -columns[1], -columns[2])
235
239
241 return "[PACKAGE|all|installed|updates|extras|obsoletes|recent]"
242
244 return _("Display details about a package or group of packages")
245
246 - def doCommand(self, base, basecmd, extcmds):
247 try:
248 highlight = base.term.MODE['bold']
249 ypl = base.returnPkgLists(extcmds, installed_available=highlight)
250 except yum.Errors.YumBaseError, e:
251 return 1, [str(e)]
252 else:
253 update_pkgs = {}
254 inst_pkgs = {}
255 local_pkgs = {}
256
257 columns = None
258 if basecmd == 'list':
259
260 columns = _list_cmd_calc_columns(base, ypl)
261
262 if highlight and ypl.installed:
263
264
265
266 for pkg in (ypl.hidden_available +
267 ypl.reinstall_available +
268 ypl.old_available):
269 key = (pkg.name, pkg.arch)
270 if key not in update_pkgs or pkg.verGT(update_pkgs[key]):
271 update_pkgs[key] = pkg
272
273 if highlight and ypl.available:
274
275
276
277 for pkg in ypl.hidden_installed:
278 key = (pkg.name, pkg.arch)
279 if key not in inst_pkgs or pkg.verGT(inst_pkgs[key]):
280 inst_pkgs[key] = pkg
281
282 if highlight and ypl.updates:
283
284 for po in sorted(ypl.updates):
285 if po.repo.id != 'installed' and po.verifyLocalPkg():
286 local_pkgs[(po.name, po.arch)] = po
287
288
289 clio = base.conf.color_list_installed_older
290 clin = base.conf.color_list_installed_newer
291 clir = base.conf.color_list_installed_reinstall
292 clie = base.conf.color_list_installed_extra
293 rip = base.listPkgs(ypl.installed, _('Installed Packages'), basecmd,
294 highlight_na=update_pkgs, columns=columns,
295 highlight_modes={'>' : clio, '<' : clin,
296 '=' : clir, 'not in' : clie})
297 clau = base.conf.color_list_available_upgrade
298 clad = base.conf.color_list_available_downgrade
299 clar = base.conf.color_list_available_reinstall
300 clai = base.conf.color_list_available_install
301 rap = base.listPkgs(ypl.available, _('Available Packages'), basecmd,
302 highlight_na=inst_pkgs, columns=columns,
303 highlight_modes={'<' : clau, '>' : clad,
304 '=' : clar, 'not in' : clai})
305 rep = base.listPkgs(ypl.extras, _('Extra Packages'), basecmd,
306 columns=columns)
307 cul = base.conf.color_update_local
308 cur = base.conf.color_update_remote
309 rup = base.listPkgs(ypl.updates, _('Updated Packages'), basecmd,
310 highlight_na=local_pkgs, columns=columns,
311 highlight_modes={'=' : cul, 'not in' : cur})
312
313
314 if len(ypl.obsoletes) > 0 and basecmd == 'list':
315
316 rop = [0, '']
317 print _('Obsoleting Packages')
318
319 for obtup in sorted(ypl.obsoletesTuples,
320 key=operator.itemgetter(0)):
321 base.updatesObsoletesList(obtup, 'obsoletes',
322 columns=columns)
323 else:
324 rop = base.listPkgs(ypl.obsoletes, _('Obsoleting Packages'),
325 basecmd, columns=columns)
326 rrap = base.listPkgs(ypl.recent, _('Recently Added Packages'),
327 basecmd, columns=columns)
328
329
330
331 if len(extcmds) and \
332 rrap[0] and rop[0] and rup[0] and rep[0] and rap[0] and rip[0]:
333 return 1, [_('No matching Packages to list')]
334 return 0, []
335
336 - def needTs(self, base, basecmd, extcmds):
337 if len(extcmds) and extcmds[0] == 'installed':
338 return False
339
340 return True
341
345
347 return _("List a package or groups of packages")
348
351
353 return ['erase', 'remove']
354
357
359 return _("Remove a package or packages from your system")
360
361 - def doCheck(self, base, basecmd, extcmds):
364
365 - def doCommand(self, base, basecmd, extcmds):
371
372 - def needTs(self, base, basecmd, extcmds):
374
377
379 - def doCommand(self, base, basecmd, extcmds):
389
394
397
399 return _("List available package groups")
400
401 - def doCommand(self, base, basecmd, extcmds):
404
405 - def needTs(self, base, basecmd, extcmds):
407
410 return ['groupinstall', 'groupupdate']
411
414
416 return _("Install the packages in a group on your system")
417
418 - def doCheck(self, base, basecmd, extcmds):
422
423 - def doCommand(self, base, basecmd, extcmds):
429
432 return ['groupremove', 'grouperase']
433
436
438 return _("Remove the packages in a group from your system")
439
440 - def doCheck(self, base, basecmd, extcmds):
443
444 - def doCommand(self, base, basecmd, extcmds):
450
451 - def needTs(self, base, basecmd, extcmds):
453
456
460
463
465 return _("Display details about a package group")
466
467 - def doCheck(self, base, basecmd, extcmds):
469
470 - def doCommand(self, base, basecmd, extcmds):
476
477 - def needTs(self, base, basecmd, extcmds):
479
481
484
487
489 return _("Generate the metadata cache")
490
491 - def doCheck(self, base, basecmd, extcmds):
493
494 - def doCommand(self, base, basecmd, extcmds):
518
519 - def needTs(self, base, basecmd, extcmds):
521
523
526
528 return "[headers|packages|metadata|dbcache|plugins|expire-cache|all]"
529
531 return _("Remove cached data")
532
533 - def doCheck(self, base, basecmd, extcmds):
535
536 - def doCommand(self, base, basecmd, extcmds):
539
540 - def needTs(self, base, basecmd, extcmds):
542
545 return ['provides', 'whatprovides']
546
549
551 return _("Find what package provides the given value")
552
553 - def doCheck(self, base, basecmd, extcmds):
555
556 - def doCommand(self, base, basecmd, extcmds):
562
565 return ['check-update']
566
568 return "[PACKAGE...]"
569
571 return _("Check for available package updates")
572
573 - def doCommand(self, base, basecmd, extcmds):
574 base.extcmds.insert(0, 'updates')
575 result = 0
576 try:
577 ypl = base.returnPkgLists(extcmds)
578 if (base.conf.obsoletes or
579 base.verbose_logger.isEnabledFor(logginglevels.DEBUG_3)):
580 typl = base.returnPkgLists(['obsoletes'])
581 ypl.obsoletes = typl.obsoletes
582 ypl.obsoletesTuples = typl.obsoletesTuples
583
584 columns = _list_cmd_calc_columns(base, ypl)
585 if len(ypl.updates) > 0:
586 local_pkgs = {}
587 highlight = base.term.MODE['bold']
588 if highlight:
589
590 for po in sorted(ypl.updates):
591 if po.repo.id != 'installed' and po.verifyLocalPkg():
592 local_pkgs[(po.name, po.arch)] = po
593
594 cul = base.conf.color_update_local
595 cur = base.conf.color_update_remote
596 base.listPkgs(ypl.updates, '', outputType='list',
597 highlight_na=local_pkgs, columns=columns,
598 highlight_modes={'=' : cul, 'not in' : cur})
599 result = 100
600 if len(ypl.obsoletes) > 0:
601 print _('Obsoleting Packages')
602
603 for obtup in sorted(ypl.obsoletesTuples,
604 key=operator.itemgetter(0)):
605 base.updatesObsoletesList(obtup, 'obsoletes',
606 columns=columns)
607 result = 100
608 except yum.Errors.YumBaseError, e:
609 return 1, [str(e)]
610 else:
611 return result, []
612
616
619
621 return _("Search package details for the given string")
622
623 - def doCheck(self, base, basecmd, extcmds):
625
626 - def doCommand(self, base, basecmd, extcmds):
632
633 - def needTs(self, base, basecmd, extcmds):
635
639
642
644 return _("Update packages taking obsoletes into account")
645
646 - def doCheck(self, base, basecmd, extcmds):
649
650 - def doCommand(self, base, basecmd, extcmds):
657
660 return ['localinstall', 'localupdate']
661
664
666 return _("Install a local RPM")
667
668 - def doCheck(self, base, basecmd, extcmds):
672
673 - def doCommand(self, base, basecmd, extcmds):
681
682 - def needTs(self, base, basecmd, extcmds):
684
687 return ['resolvedep']
688
691
693 return _("Determine which package provides the given dependency")
694
695 - def doCommand(self, base, basecmd, extcmds):
701
705
708
710 return _("Run an interactive yum shell")
711
712 - def doCheck(self, base, basecmd, extcmds):
714
715 - def doCommand(self, base, basecmd, extcmds):
721
722 - def needTs(self, base, basecmd, extcmds):
724
729
732
734 return _("List a package's dependencies")
735
736 - def doCheck(self, base, basecmd, extcmds):
738
739 - def doCommand(self, base, basecmd, extcmds):
745
748
751
753 return '[all|enabled|disabled]'
754
756 return _('Display the configured software repositories')
757
758 - def doCommand(self, base, basecmd, extcmds):
764
765 def _repo_match(repo, patterns):
766 rid = repo.id.lower()
767 rnm = repo.name.lower()
768 for pat in patterns:
769 if fnmatch.fnmatch(rid, pat):
770 return True
771 if fnmatch.fnmatch(rnm, pat):
772 return True
773 return False
774
775 def _num2ui_num(num):
776 return to_unicode(locale.format("%d", num, True))
777
778 if len(extcmds) >= 1 and extcmds[0] in ('all', 'disabled', 'enabled'):
779 arg = extcmds[0]
780 extcmds = extcmds[1:]
781 else:
782 arg = 'enabled'
783 extcmds = map(lambda x: x.lower(), extcmds)
784
785 verbose = base.verbose_logger.isEnabledFor(logginglevels.DEBUG_3)
786 if arg != 'disabled' or extcmds:
787 try:
788
789 base.repos.populateSack()
790 base.pkgSack
791 except yum.Errors.RepoError:
792 if verbose:
793 raise
794
795 repos = base.repos.repos.values()
796 repos.sort()
797 enabled_repos = base.repos.listEnabled()
798 on_ehibeg = base.term.FG_COLOR['green'] + base.term.MODE['bold']
799 on_dhibeg = base.term.FG_COLOR['red']
800 on_hiend = base.term.MODE['normal']
801 tot_num = 0
802 cols = []
803 for repo in repos:
804 if len(extcmds) and not _repo_match(repo, extcmds):
805 continue
806 (ehibeg, dhibeg, hiend) = '', '', ''
807 ui_enabled = ''
808 ui_endis_wid = 0
809 ui_num = ""
810 ui_excludes_num = ''
811 force_show = False
812 if arg == 'all' or repo.id in extcmds or repo.name in extcmds:
813 force_show = True
814 (ehibeg, dhibeg, hiend) = (on_ehibeg, on_dhibeg, on_hiend)
815 if repo in enabled_repos:
816 enabled = True
817 if arg == 'enabled':
818 force_show = False
819 elif arg == 'disabled' and not force_show:
820 continue
821 if force_show or verbose:
822 ui_enabled = ehibeg + _('enabled') + hiend
823 ui_endis_wid = utf8_width(_('enabled'))
824 if not verbose:
825 ui_enabled += ": "
826 ui_endis_wid += 2
827 if verbose:
828 ui_size = _repo_size(repo)
829
830 if arg != 'disabled' or verbose:
831 if verbose or base.conf.exclude or repo.exclude:
832 num = len(repo.sack.simplePkgList())
833 else:
834 num = len(repo.sack)
835 ui_num = _num2ui_num(num)
836 excludes = repo.sack._excludes
837 excludes = len([pid for r,pid in excludes if r == repo])
838 if excludes:
839 ui_excludes_num = _num2ui_num(excludes)
840 if not verbose:
841 ui_num += "+%s" % ui_excludes_num
842 tot_num += num
843 else:
844 enabled = False
845 if arg == 'disabled':
846 force_show = False
847 elif arg == 'enabled' and not force_show:
848 continue
849 ui_enabled = dhibeg + _('disabled') + hiend
850 ui_endis_wid = utf8_width(_('disabled'))
851
852 if True:
853 if not verbose:
854 rid = str(repo)
855 if enabled and repo.metalink:
856 mdts = repo.metalink_data.repomd.timestamp
857 if mdts > repo.repoXML.timestamp:
858 rid = '*' + rid
859 cols.append((rid, repo.name,
860 (ui_enabled, ui_endis_wid), ui_num))
861 else:
862 if enabled:
863 md = repo.repoXML
864 else:
865 md = None
866 out = [base.fmtKeyValFill(_("Repo-id : "), repo),
867 base.fmtKeyValFill(_("Repo-name : "), repo.name)]
868
869 if force_show or extcmds:
870 out += [base.fmtKeyValFill(_("Repo-status : "),
871 ui_enabled)]
872 if md and md.revision is not None:
873 out += [base.fmtKeyValFill(_("Repo-revision: "),
874 md.revision)]
875 if md and md.tags['content']:
876 tags = md.tags['content']
877 out += [base.fmtKeyValFill(_("Repo-tags : "),
878 ", ".join(sorted(tags)))]
879
880 if md and md.tags['distro']:
881 for distro in sorted(md.tags['distro']):
882 tags = md.tags['distro'][distro]
883 out += [base.fmtKeyValFill(_("Repo-distro-tags: "),
884 "[%s]: %s" % (distro,
885 ", ".join(sorted(tags))))]
886
887 if md:
888 out += [base.fmtKeyValFill(_("Repo-updated : "),
889 time.ctime(md.timestamp)),
890 base.fmtKeyValFill(_("Repo-pkgs : "),ui_num),
891 base.fmtKeyValFill(_("Repo-size : "),ui_size)]
892
893 if hasattr(repo, '_orig_baseurl'):
894 baseurls = repo._orig_baseurl
895 else:
896 baseurls = repo.baseurl
897 if baseurls:
898 out += [base.fmtKeyValFill(_("Repo-baseurl : "),
899 ", ".join(baseurls))]
900
901 if enabled:
902
903
904 repo.urls
905 if repo.metalink:
906 out += [base.fmtKeyValFill(_("Repo-metalink: "),
907 repo.metalink)]
908 if enabled:
909 ts = repo.metalink_data.repomd.timestamp
910 out += [base.fmtKeyValFill(_(" Updated : "),
911 time.ctime(ts))]
912 elif repo.mirrorlist:
913 out += [base.fmtKeyValFill(_("Repo-mirrors : "),
914 repo.mirrorlist)]
915
916 if not os.path.exists(repo.metadata_cookie):
917 last = _("Unknown")
918 else:
919 last = os.stat(repo.metadata_cookie).st_mtime
920 last = time.ctime(last)
921
922 if repo.metadata_expire <= -1:
923 num = _("Never (last: %s)") % last
924 elif not repo.metadata_expire:
925 num = _("Instant (last: %s)") % last
926 else:
927 num = _num2ui_num(repo.metadata_expire)
928 num = _("%s second(s) (last: %s)") % (num, last)
929
930 out += [base.fmtKeyValFill(_("Repo-expire : "), num)]
931
932 if repo.exclude:
933 out += [base.fmtKeyValFill(_("Repo-exclude : "),
934 ", ".join(repo.exclude))]
935
936 if repo.includepkgs:
937 out += [base.fmtKeyValFill(_("Repo-include : "),
938 ", ".join(repo.includepkgs))]
939
940 if ui_excludes_num:
941 out += [base.fmtKeyValFill(_("Repo-excluded: "),
942 ui_excludes_num)]
943
944 base.verbose_logger.log(logginglevels.DEBUG_3,
945 "%s\n",
946 "\n".join(map(misc.to_unicode, out)))
947
948 if not verbose and cols:
949
950
951 id_len = utf8_width(_('repo id'))
952 nm_len = 0
953 st_len = 0
954 ui_len = 0
955
956 for (rid, rname, (ui_enabled, ui_endis_wid), ui_num) in cols:
957 if id_len < utf8_width(rid):
958 id_len = utf8_width(rid)
959 if nm_len < utf8_width(rname):
960 nm_len = utf8_width(rname)
961 if st_len < (ui_endis_wid + len(ui_num)):
962 st_len = (ui_endis_wid + len(ui_num))
963
964 if ui_len < len(ui_num):
965 ui_len = len(ui_num)
966 if arg == 'disabled':
967 left = base.term.columns - (id_len + 1)
968 elif utf8_width(_('status')) > st_len:
969 left = base.term.columns - (id_len + utf8_width(_('status')) +2)
970 else:
971 left = base.term.columns - (id_len + st_len + 2)
972
973 if left < nm_len:
974 nm_len = left
975 else:
976 left -= nm_len
977 id_len += left / 2
978 nm_len += left - (left / 2)
979
980 txt_rid = utf8_width_fill(_('repo id'), id_len)
981 txt_rnam = utf8_width_fill(_('repo name'), nm_len, nm_len)
982 if arg == 'disabled':
983 base.verbose_logger.log(logginglevels.INFO_2,"%s %s",
984 txt_rid, txt_rnam)
985 else:
986 base.verbose_logger.log(logginglevels.INFO_2,"%s %s %s",
987 txt_rid, txt_rnam, _('status'))
988 for (rid, rname, (ui_enabled, ui_endis_wid), ui_num) in cols:
989 if arg == 'disabled':
990 base.verbose_logger.log(logginglevels.INFO_2, "%s %s",
991 utf8_width_fill(rid, id_len),
992 utf8_width_fill(rname, nm_len,
993 nm_len))
994 continue
995
996 if ui_num:
997 ui_num = utf8_width_fill(ui_num, ui_len, left=False)
998 base.verbose_logger.log(logginglevels.INFO_2, "%s %s %s%s",
999 utf8_width_fill(rid, id_len),
1000 utf8_width_fill(rname, nm_len, nm_len),
1001 ui_enabled, ui_num)
1002
1003 return 0, ['repolist: ' +to_unicode(locale.format("%d", tot_num, True))]
1004
1005 - def needTs(self, base, basecmd, extcmds):
1007
1010
1013
1016
1018 return _("Display a helpful usage message")
1019
1020 - def doCheck(self, base, basecmd, extcmds):
1027
1028 @staticmethod
1030 canonical_name = command.getNames()[0]
1031
1032
1033
1034
1035 try:
1036 usage = command.getUsage()
1037 except (AttributeError, NotImplementedError):
1038 usage = None
1039 try:
1040 summary = command.getSummary()
1041 except (AttributeError, NotImplementedError):
1042 summary = None
1043
1044
1045 help_output = ""
1046 if usage is not None:
1047 help_output += "%s %s" % (canonical_name, usage)
1048 if summary is not None:
1049 help_output += "\n\n%s" % summary
1050
1051 if usage is None and summary is None:
1052 help_output = _("No help available for %s") % canonical_name
1053
1054 command_names = command.getNames()
1055 if len(command_names) > 1:
1056 if len(command_names) > 2:
1057 help_output += _("\n\naliases: ")
1058 else:
1059 help_output += _("\n\nalias: ")
1060 help_output += ', '.join(command.getNames()[1:])
1061
1062 return help_output
1063
1064 - def doCommand(self, base, basecmd, extcmds):
1070
1071 - def needTs(self, base, basecmd, extcmds):
1073
1076 return ['reinstall']
1077
1080
1081 - def doCheck(self, base, basecmd, extcmds):
1085
1086 - def doCommand(self, base, basecmd, extcmds):
1093
1095 return _("reinstall a package")
1096
1097 - def needTs(self, base, basecmd, extcmds):
1099
1102 return ['downgrade']
1103
1106
1107 - def doCheck(self, base, basecmd, extcmds):
1111
1112 - def doCommand(self, base, basecmd, extcmds):
1118
1120 return _("downgrade a package")
1121
1122 - def needTs(self, base, basecmd, extcmds):
1124
1129
1131 return "[all|installed|available]"
1132
1134 return _("Display a version for the machine and/or available repos.")
1135
1136 - def doCommand(self, base, basecmd, extcmds):
1137 vcmd = 'installed'
1138 if extcmds:
1139 vcmd = extcmds[0]
1140
1141 def _append_repos(cols, repo_data):
1142 for repoid in sorted(repo_data):
1143 cur = repo_data[repoid]
1144 ncols = []
1145 last_rev = None
1146 for rev in sorted(cur):
1147 if rev is None:
1148 continue
1149 last_rev = cur[rev]
1150 ncols.append((" %s/%s" % (repoid, rev), str(cur[rev])))
1151 if None in cur and (not last_rev or cur[None] != last_rev):
1152 cols.append((" %s" % repoid, str(cur[None])))
1153 cols.extend(ncols)
1154
1155 verbose = base.verbose_logger.isEnabledFor(logginglevels.DEBUG_3)
1156 groups = {}
1157 if vcmd in ('nogroups', 'nogroups-installed', 'nogroups-available',
1158 'nogroups-all'):
1159 gconf = []
1160 if vcmd == 'nogroups':
1161 vcmd = 'installed'
1162 else:
1163 vcmd = vcmd[len('nogroups-'):]
1164 else:
1165 gconf = yum.config.readVersionGroupsConfig()
1166
1167 for group in gconf:
1168 groups[group] = set(gconf[group].pkglist)
1169 if gconf[group].run_with_packages:
1170 groups[group].update(base.run_with_package_names)
1171
1172 if vcmd == 'grouplist':
1173 print _(" Yum version groups:")
1174 for group in sorted(groups):
1175 print " ", group
1176
1177 return 0, ['version grouplist']
1178
1179 if vcmd == 'groupinfo':
1180 for group in groups:
1181 if group not in extcmds[1:]:
1182 continue
1183 print _(" Group :"), group
1184 print _(" Packages:")
1185 if not verbose:
1186 for pkgname in sorted(groups[group]):
1187 print " ", pkgname
1188 else:
1189 data = {'envra' : {}, 'rid' : {}}
1190 pkg_names = groups[group]
1191 pkg_names2pkgs = base._group_names2aipkgs(pkg_names)
1192 base._calcDataPkgColumns(data, pkg_names, pkg_names2pkgs)
1193 data = [data['envra'], data['rid']]
1194 columns = base.calcColumns(data)
1195 columns = (-columns[0], -columns[1])
1196 base._displayPkgsFromNames(pkg_names, True, pkg_names2pkgs,
1197 columns=columns)
1198
1199 return 0, ['version groupinfo']
1200
1201 rel = base.conf.yumvar['releasever']
1202 ba = base.conf.yumvar['basearch']
1203 cols = []
1204 if vcmd in ('installed', 'all', 'group-installed', 'group-all'):
1205 try:
1206 data = base.rpmdb.simpleVersion(not verbose, groups=groups)
1207 lastdbv = base.history.last()
1208 if lastdbv is not None:
1209 lastdbv = lastdbv.end_rpmdbversion
1210 if lastdbv is None or data[0] != lastdbv:
1211 base._rpmdb_warn_checks(warn=lastdbv is not None)
1212 if vcmd not in ('group-installed', 'group-all'):
1213 cols.append(("%s %s/%s" % (_("Installed:"), rel, ba),
1214 str(data[0])))
1215 _append_repos(cols, data[1])
1216 if groups:
1217 for grp in sorted(data[2]):
1218 cols.append(("%s %s" % (_("Group-Installed:"), grp),
1219 str(data[2][grp])))
1220 _append_repos(cols, data[3][grp])
1221 except yum.Errors.YumBaseError, e:
1222 return 1, [str(e)]
1223 if vcmd in ('available', 'all', 'group-available', 'group-all'):
1224 try:
1225 data = base.pkgSack.simpleVersion(not verbose, groups=groups)
1226 if vcmd not in ('group-available', 'group-all'):
1227 cols.append(("%s %s/%s" % (_("Available:"), rel, ba),
1228 str(data[0])))
1229 if verbose:
1230 _append_repos(cols, data[1])
1231 if groups:
1232 for grp in sorted(data[2]):
1233 cols.append(("%s %s" % (_("Group-Available:"), grp),
1234 str(data[2][grp])))
1235 if verbose:
1236 _append_repos(cols, data[3][grp])
1237 except yum.Errors.YumBaseError, e:
1238 return 1, [str(e)]
1239
1240 data = {'rid' : {}, 'ver' : {}}
1241 for (rid, ver) in cols:
1242 for (d, v) in (('rid', len(rid)), ('ver', len(ver))):
1243 data[d].setdefault(v, 0)
1244 data[d][v] += 1
1245 data = [data['rid'], data['ver']]
1246 columns = base.calcColumns(data)
1247 columns = (-columns[0], columns[1])
1248
1249 for line in cols:
1250 print base.fmtColumns(zip(line, columns))
1251
1252 return 0, ['version']
1253
1254 - def needTs(self, base, basecmd, extcmds):
1255 vcmd = 'installed'
1256 if extcmds:
1257 vcmd = extcmds[0]
1258 verbose = base.verbose_logger.isEnabledFor(logginglevels.DEBUG_3)
1259 if vcmd == 'groupinfo' and verbose:
1260 return True
1261 return vcmd in ('available', 'all', 'group-available', 'group-all')
1262
1263
1264 -class HistoryCommand(YumCommand):
1265 - def getNames(self):
1267
1268 - def getUsage(self):
1269 return "[info|list|summary|redo|undo|new]"
1270
1271 - def getSummary(self):
1272 return _("Display, or use, the transaction history")
1273
1274 - def _hcmd_redo(self, base, extcmds):
1275 old = base._history_get_transaction(extcmds)
1276 if old is None:
1277 return 1, ['Failed history redo']
1278 tm = time.ctime(old.beg_timestamp)
1279 print "Repeating transaction %u, from %s" % (old.tid, tm)
1280 base.historyInfoCmdPkgsAltered(old)
1281 if base.history_redo(old):
1282 return 2, ["Repeating transaction %u" % (old.tid,)]
1283
1284 - def _hcmd_undo(self, base, extcmds):
1285 old = base._history_get_transaction(extcmds)
1286 if old is None:
1287 return 1, ['Failed history undo']
1288 tm = time.ctime(old.beg_timestamp)
1289 print "Undoing transaction %u, from %s" % (old.tid, tm)
1290 base.historyInfoCmdPkgsAltered(old)
1291 if base.history_undo(old):
1292 return 2, ["Undoing transaction %u" % (old.tid,)]
1293
1294 - def _hcmd_new(self, base, extcmds):
1296
1297 - def doCheck(self, base, basecmd, extcmds):
1298 cmds = ('list', 'info', 'summary', 'repeat', 'redo', 'undo', 'new')
1299 if extcmds and extcmds[0] not in cmds:
1300 base.logger.critical(_('Invalid history sub-command, use: %s.'),
1301 ", ".join(cmds))
1302 raise cli.CliError
1303 if extcmds and extcmds[0] in ('repeat', 'redo', 'undo', 'new'):
1304 checkRootUID(base)
1305 checkGPGKey(base)
1306
1307 - def doCommand(self, base, basecmd, extcmds):
1308 vcmd = 'list'
1309 if extcmds:
1310 vcmd = extcmds[0]
1311
1312 if False: pass
1313 elif vcmd == 'list':
1314 ret = base.historyListCmd(extcmds)
1315 elif vcmd == 'info':
1316 ret = base.historyInfoCmd(extcmds)
1317 elif vcmd == 'summary':
1318 ret = base.historySummaryCmd(extcmds)
1319 elif vcmd == 'undo':
1320 ret = self._hcmd_undo(base, extcmds)
1321 elif vcmd in ('redo', 'repeat'):
1322 ret = self._hcmd_redo(base, extcmds)
1323 elif vcmd == 'new':
1324 ret = self._hcmd_new(base, extcmds)
1325
1326 if ret is None:
1327 return 0, ['history %s' % (vcmd,)]
1328 return ret
1329
1330 - def needTs(self, base, basecmd, extcmds):
1331 vcmd = 'list'
1332 if extcmds:
1333 vcmd = extcmds[0]
1334 return vcmd in ('repeat', 'redo', 'undo')
1335
1339 return ['check', 'check-rpmdb']
1340
1342 return "[dependencies|duplicates|all]"
1343
1345 return _("Check for problems in the rpmdb")
1346
1347 - def doCommand(self, base, basecmd, extcmds):
1348 chkcmd = 'all'
1349 if extcmds:
1350 chkcmd = extcmds[0]
1351
1352 def _out(x):
1353 print x
1354
1355 rc = 0
1356 if base._rpmdb_warn_checks(_out, False, chkcmd):
1357 rc = 1
1358 return rc, ['%s %s' % (basecmd, chkcmd)]
1359
1360 - def needTs(self, base, basecmd, extcmds):
1362