source: yum/trunk/yummain.py@ 6

Last change on this file since 6 was 2, checked in by Yuri Dario, 15 years ago

Initial import for vendor code.

  • Property svn:eol-style set to native
File size: 7.7 KB
Line 
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
17"""
18Entrance point for the yum command line interface.
19"""
20
21import os
22import os.path
23import sys
24import logging
25import time
26
27from yum import Errors
28from yum import plugins
29from yum import logginglevels
30from yum import _
31from yum.i18n import to_unicode, utf8_width
32import yum.misc
33import cli
34from utils import suppress_keyboard_interrupt_message, show_lock_owner
35
36def main(args):
37 """This does all the real work"""
38
39 yum.misc.setup_locale(override_time=True)
40
41 def exUserCancel():
42 logger.critical(_('\n\nExiting on user cancel'))
43 if unlock(): return 200
44 return 1
45
46 def exIOError(e):
47 if e.errno == 32:
48 logger.critical(_('\n\nExiting on Broken Pipe'))
49 else:
50 logger.critical(_('\n\n%s') % str(e))
51 if unlock(): return 200
52 return 1
53
54 def exPluginExit(e):
55 '''Called when a plugin raises PluginYumExit.
56
57 Log the plugin's exit message if one was supplied.
58 ''' # ' xemacs hack
59 exitmsg = str(e)
60 if exitmsg:
61 logger.warn('\n\n%s', exitmsg)
62 if unlock(): return 200
63 return 1
64
65 def exFatal(e):
66 logger.critical('\n\n%s', to_unicode(e.value))
67 if unlock(): return 200
68 return 1
69
70 def unlock():
71 try:
72 base.closeRpmDB()
73 base.doUnlock()
74 except Errors.LockError, e:
75 return 200
76 return 0
77
78
79 logger = logging.getLogger("yum.main")
80 verbose_logger = logging.getLogger("yum.verbose.main")
81
82 # our core object for the cli
83 base = cli.YumBaseCli()
84
85 # do our cli parsing and config file setup
86 # also sanity check the things being passed on the cli
87 try:
88 base.getOptionsConfig(args)
89 except plugins.PluginYumExit, e:
90 return exPluginExit(e)
91 except Errors.YumBaseError, e:
92 return exFatal(e)
93
94 lockerr = ""
95 while True:
96 try:
97 base.doLock()
98 except Errors.LockError, e:
99 if "%s" %(e.msg,) != lockerr:
100 lockerr = "%s" %(e.msg,)
101 logger.critical(lockerr)
102 logger.critical(_("Another app is currently holding the yum lock; waiting for it to exit..."))
103 show_lock_owner(e.pid, logger)
104 time.sleep(2)
105 else:
106 break
107
108 try:
109 result, resultmsgs = base.doCommands()
110 except plugins.PluginYumExit, e:
111 return exPluginExit(e)
112 except Errors.YumBaseError, e:
113 result = 1
114 resultmsgs = [unicode(e)]
115 except KeyboardInterrupt:
116 return exUserCancel()
117 except IOError, e:
118 return exIOError(e)
119
120 # Act on the command/shell result
121 if result == 0:
122 # Normal exit
123 for msg in resultmsgs:
124 verbose_logger.log(logginglevels.INFO_2, '%s', msg)
125 if unlock(): return 200
126 return 0
127 elif result == 1:
128 # Fatal error
129 for msg in resultmsgs:
130 logger.critical(_('Error: %s'), msg)
131 if unlock(): return 200
132 return 1
133 elif result == 2:
134 # Continue on
135 pass
136 elif result == 100:
137 if unlock(): return 200
138 return 100
139 else:
140 logger.critical(_('Unknown Error(s): Exit Code: %d:'), result)
141 for msg in resultmsgs:
142 logger.critical(msg)
143 if unlock(): return 200
144 return 3
145
146 # Depsolve stage
147 verbose_logger.log(logginglevels.INFO_2, _('Resolving Dependencies'))
148
149 try:
150 (result, resultmsgs) = base.buildTransaction()
151 except plugins.PluginYumExit, e:
152 return exPluginExit(e)
153 except Errors.YumBaseError, e:
154 result = 1
155 resultmsgs = [unicode(e)]
156 except KeyboardInterrupt:
157 return exUserCancel()
158 except IOError, e:
159 return exIOError(e)
160
161 # Act on the depsolve result
162 if result == 0:
163 # Normal exit
164 if unlock(): return 200
165 return 0
166 elif result == 1:
167 # Fatal error
168 for msg in resultmsgs:
169 prefix = _('Error: %s')
170 prefix2nd = (' ' * (utf8_width(prefix) - 2))
171 logger.critical(prefix, msg.replace('\n', '\n' + prefix2nd))
172 if not base.conf.skip_broken:
173 verbose_logger.info(_(" You could try using --skip-broken to work around the problem"))
174 if not base._rpmdb_warn_checks(out=verbose_logger.info, warn=False):
175 verbose_logger.info(_(" You could try running: rpm -Va --nofiles --nodigest"))
176 if unlock(): return 200
177 return 1
178 elif result == 2:
179 # Continue on
180 pass
181 else:
182 logger.critical(_('Unknown Error(s): Exit Code: %d:'), result)
183 for msg in resultmsgs:
184 logger.critical(msg)
185 if unlock(): return 200
186 return 3
187
188 verbose_logger.log(logginglevels.INFO_2, _('\nDependencies Resolved'))
189
190 # Run the transaction
191 try:
192 return_code = base.doTransaction()
193 except plugins.PluginYumExit, e:
194 return exPluginExit(e)
195 except Errors.YumBaseError, e:
196 return exFatal(e)
197 except KeyboardInterrupt:
198 return exUserCancel()
199 except IOError, e:
200 return exIOError(e)
201
202 # rpm_check_debug failed.
203 if type(return_code) == type((0,)) and len(return_code) == 2:
204 (result, resultmsgs) = return_code
205 for msg in resultmsgs:
206 logger.critical("%s", msg)
207 if not base._rpmdb_warn_checks(out=verbose_logger.info, warn=False):
208 verbose_logger.info(_(" You could try running: rpm -Va --nofiles --nodigest"))
209 return_code = result
210 else:
211 verbose_logger.log(logginglevels.INFO_2, _('Complete!'))
212
213 if unlock(): return 200
214 return return_code
215
216def hotshot(func, *args, **kwargs):
217 import hotshot.stats
218 fn = os.path.expanduser("~/yum.prof")
219 prof = hotshot.Profile(fn)
220 rc = prof.runcall(func, *args, **kwargs)
221 prof.close()
222 print_stats(hotshot.stats.load(fn))
223 return rc
224
225def cprof(func, *args, **kwargs):
226 import cProfile, pstats
227 fn = os.path.expanduser("~/yum.prof")
228 prof = cProfile.Profile()
229 rc = prof.runcall(func, *args, **kwargs)
230 prof.dump_stats(fn)
231 print_stats(pstats.Stats(fn))
232 return rc
233
234def print_stats(stats):
235 stats.strip_dirs()
236 stats.sort_stats('time', 'calls')
237 stats.print_stats(20)
238 stats.sort_stats('cumulative')
239 stats.print_stats(40)
240
241def user_main(args, exit_code=False):
242 """ This calls one of the multiple main() functions based on env. vars """
243 errcode = None
244 if 'YUM_PROF' in os.environ:
245 if os.environ['YUM_PROF'] == 'cprof':
246 errcode = cprof(main, args)
247 if os.environ['YUM_PROF'] == 'hotshot':
248 errcode = hotshot(main, args)
249 if 'YUM_PDB' in os.environ:
250 import pdb
251 pdb.run(main(args))
252
253 if errcode is None:
254 errcode = main(args)
255 if exit_code:
256 sys.exit(errcode)
257 return errcode
258
259suppress_keyboard_interrupt_message()
260
261if __name__ == "__main__":
262 try:
263 user_main(sys.argv[1:], exit_code=True)
264 except KeyboardInterrupt, e:
265 print >> sys.stderr, _("\n\nExiting on user cancel.")
266 sys.exit(1)
Note: See TracBrowser for help on using the repository browser.