summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorTom Zanussi <tom.zanussi@linux.intel.com>2014-08-03 18:25:52 -0500
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-08-11 10:53:09 +0100
commit93a60f7e99268fd66db12f30b237862500294266 (patch)
tree46fcc88c7b55c0f135952d0583444c4fed982079 /scripts
parentac2d312f8167f13adda3cc17b0f638c6e23d9bce (diff)
downloadpoky-93a60f7e99268fd66db12f30b237862500294266.tar.gz
wic: Remove rpmmisc
wic doesn't use it, so remove it. (From OE-Core rev: a49b39ddf18b1b058c0a892e1a7450239eea66ce) Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/lib/mic/utils/rpmmisc.py600
1 files changed, 0 insertions, 600 deletions
diff --git a/scripts/lib/mic/utils/rpmmisc.py b/scripts/lib/mic/utils/rpmmisc.py
deleted file mode 100644
index af15763e18..0000000000
--- a/scripts/lib/mic/utils/rpmmisc.py
+++ /dev/null
@@ -1,600 +0,0 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2008, 2009, 2010, 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import sys
20import re
21import rpm
22
23from mic import msger
24from mic.utils.errors import CreatorError
25from mic.utils.proxy import get_proxy_for
26from mic.utils import runner
27
28
29class RPMInstallCallback:
30 """ Command line callback class for callbacks from the RPM library.
31 """
32
33 def __init__(self, ts, output=1):
34 self.output = output
35 self.callbackfilehandles = {}
36 self.total_actions = 0
37 self.total_installed = 0
38 self.installed_pkg_names = []
39 self.total_removed = 0
40 self.mark = "+"
41 self.marks = 40
42 self.lastmsg = None
43 self.tsInfo = None # this needs to be set for anything else to work
44 self.ts = ts
45 self.filelog = False
46 self.logString = []
47 self.headmsg = "Installing"
48
49 def _dopkgtup(self, hdr):
50 tmpepoch = hdr['epoch']
51 if tmpepoch is None: epoch = '0'
52 else: epoch = str(tmpepoch)
53
54 return (hdr['name'], hdr['arch'], epoch, hdr['version'], hdr['release'])
55
56 def _makeHandle(self, hdr):
57 handle = '%s:%s.%s-%s-%s' % (hdr['epoch'], hdr['name'], hdr['version'],
58 hdr['release'], hdr['arch'])
59
60 return handle
61
62 def _localprint(self, msg):
63 if self.output:
64 msger.info(msg)
65
66 def _makefmt(self, percent, progress = True):
67 l = len(str(self.total_actions))
68 size = "%s.%s" % (l, l)
69 fmt_done = "[%" + size + "s/%" + size + "s]"
70 done = fmt_done % (self.total_installed + self.total_removed,
71 self.total_actions)
72 marks = self.marks - (2 * l)
73 width = "%s.%s" % (marks, marks)
74 fmt_bar = "%-" + width + "s"
75 if progress:
76 bar = fmt_bar % (self.mark * int(marks * (percent / 100.0)), )
77 fmt = "\r %-10.10s: %-20.20s " + bar + " " + done
78 else:
79 bar = fmt_bar % (self.mark * marks, )
80 fmt = " %-10.10s: %-20.20s " + bar + " " + done
81 return fmt
82
83 def _logPkgString(self, hdr):
84 """return nice representation of the package for the log"""
85 (n,a,e,v,r) = self._dopkgtup(hdr)
86 if e == '0':
87 pkg = '%s.%s %s-%s' % (n, a, v, r)
88 else:
89 pkg = '%s.%s %s:%s-%s' % (n, a, e, v, r)
90
91 return pkg
92
93 def callback(self, what, bytes, total, h, user):
94 if what == rpm.RPMCALLBACK_TRANS_START:
95 if bytes == 6:
96 self.total_actions = total
97
98 elif what == rpm.RPMCALLBACK_TRANS_PROGRESS:
99 pass
100
101 elif what == rpm.RPMCALLBACK_TRANS_STOP:
102 pass
103
104 elif what == rpm.RPMCALLBACK_INST_OPEN_FILE:
105 self.lastmsg = None
106 hdr = None
107 if h is not None:
108 try:
109 hdr, rpmloc = h
110 except:
111 rpmloc = h
112 hdr = readRpmHeader(self.ts, h)
113
114 handle = self._makeHandle(hdr)
115 fd = os.open(rpmloc, os.O_RDONLY)
116 self.callbackfilehandles[handle]=fd
117 if hdr['name'] not in self.installed_pkg_names:
118 self.installed_pkg_names.append(hdr['name'])
119 self.total_installed += 1
120 return fd
121 else:
122 self._localprint("No header - huh?")
123
124 elif what == rpm.RPMCALLBACK_INST_CLOSE_FILE:
125 hdr = None
126 if h is not None:
127 try:
128 hdr, rpmloc = h
129 except:
130 rpmloc = h
131 hdr = readRpmHeader(self.ts, h)
132
133 handle = self._makeHandle(hdr)
134 os.close(self.callbackfilehandles[handle])
135 fd = 0
136
137 # log stuff
138 #pkgtup = self._dopkgtup(hdr)
139 self.logString.append(self._logPkgString(hdr))
140
141 elif what == rpm.RPMCALLBACK_INST_PROGRESS:
142 if h is not None:
143 percent = (self.total_installed*100L)/self.total_actions
144 if total > 0:
145 try:
146 hdr, rpmloc = h
147 except:
148 rpmloc = h
149
150 m = re.match("(.*)-(\d+.*)-(\d+\.\d+)\.(.+)\.rpm", os.path.basename(rpmloc))
151 if m:
152 pkgname = m.group(1)
153 else:
154 pkgname = os.path.basename(rpmloc)
155 if self.output:
156 fmt = self._makefmt(percent)
157 msg = fmt % (self.headmsg, pkgname)
158 if msg != self.lastmsg:
159 self.lastmsg = msg
160
161 msger.info(msg)
162
163 if self.total_installed == self.total_actions:
164 msger.raw('')
165 msger.verbose('\n'.join(self.logString))
166
167 elif what == rpm.RPMCALLBACK_UNINST_START:
168 pass
169
170 elif what == rpm.RPMCALLBACK_UNINST_PROGRESS:
171 pass
172
173 elif what == rpm.RPMCALLBACK_UNINST_STOP:
174 self.total_removed += 1
175
176 elif what == rpm.RPMCALLBACK_REPACKAGE_START:
177 pass
178
179 elif what == rpm.RPMCALLBACK_REPACKAGE_STOP:
180 pass
181
182 elif what == rpm.RPMCALLBACK_REPACKAGE_PROGRESS:
183 pass
184
185def readRpmHeader(ts, filename):
186 """ Read an rpm header. """
187
188 fd = os.open(filename, os.O_RDONLY)
189 h = ts.hdrFromFdno(fd)
190 os.close(fd)
191 return h
192
193def splitFilename(filename):
194 """ Pass in a standard style rpm fullname
195
196 Return a name, version, release, epoch, arch, e.g.::
197 foo-1.0-1.i386.rpm returns foo, 1.0, 1, i386
198 1:bar-9-123a.ia64.rpm returns bar, 9, 123a, 1, ia64
199 """
200
201 if filename[-4:] == '.rpm':
202 filename = filename[:-4]
203
204 archIndex = filename.rfind('.')
205 arch = filename[archIndex+1:]
206
207 relIndex = filename[:archIndex].rfind('-')
208 rel = filename[relIndex+1:archIndex]
209
210 verIndex = filename[:relIndex].rfind('-')
211 ver = filename[verIndex+1:relIndex]
212
213 epochIndex = filename.find(':')
214 if epochIndex == -1:
215 epoch = ''
216 else:
217 epoch = filename[:epochIndex]
218
219 name = filename[epochIndex + 1:verIndex]
220 return name, ver, rel, epoch, arch
221
222def getCanonX86Arch(arch):
223 #
224 if arch == "i586":
225 f = open("/proc/cpuinfo", "r")
226 lines = f.readlines()
227 f.close()
228 for line in lines:
229 if line.startswith("model name") and line.find("Geode(TM)") != -1:
230 return "geode"
231 return arch
232 # only athlon vs i686 isn't handled with uname currently
233 if arch != "i686":
234 return arch
235
236 # if we're i686 and AuthenticAMD, then we should be an athlon
237 f = open("/proc/cpuinfo", "r")
238 lines = f.readlines()
239 f.close()
240 for line in lines:
241 if line.startswith("vendor") and line.find("AuthenticAMD") != -1:
242 return "athlon"
243 # i686 doesn't guarantee cmov, but we depend on it
244 elif line.startswith("flags") and line.find("cmov") == -1:
245 return "i586"
246
247 return arch
248
249def getCanonX86_64Arch(arch):
250 if arch != "x86_64":
251 return arch
252
253 vendor = None
254 f = open("/proc/cpuinfo", "r")
255 lines = f.readlines()
256 f.close()
257 for line in lines:
258 if line.startswith("vendor_id"):
259 vendor = line.split(':')[1]
260 break
261 if vendor is None:
262 return arch
263
264 if vendor.find("Authentic AMD") != -1 or vendor.find("AuthenticAMD") != -1:
265 return "amd64"
266 if vendor.find("GenuineIntel") != -1:
267 return "ia32e"
268 return arch
269
270def getCanonArch():
271 arch = os.uname()[4]
272
273 if (len(arch) == 4 and arch[0] == "i" and arch[2:4] == "86"):
274 return getCanonX86Arch(arch)
275
276 if arch == "x86_64":
277 return getCanonX86_64Arch(arch)
278
279 return arch
280
281# Copy from libsatsolver:poolarch.c, with cleanup
282archPolicies = {
283 "x86_64": "x86_64:i686:i586:i486:i386",
284 "i686": "i686:i586:i486:i386",
285 "i586": "i586:i486:i386",
286 "ia64": "ia64:i686:i586:i486:i386",
287 "armv7tnhl": "armv7tnhl:armv7thl:armv7nhl:armv7hl",
288 "armv7thl": "armv7thl:armv7hl",
289 "armv7nhl": "armv7nhl:armv7hl",
290 "armv7hl": "armv7hl",
291 "armv7l": "armv7l:armv6l:armv5tejl:armv5tel:armv5l:armv4tl:armv4l:armv3l",
292 "armv6l": "armv6l:armv5tejl:armv5tel:armv5l:armv4tl:armv4l:armv3l",
293 "armv5tejl": "armv5tejl:armv5tel:armv5l:armv4tl:armv4l:armv3l",
294 "armv5tel": "armv5tel:armv5l:armv4tl:armv4l:armv3l",
295 "armv5l": "armv5l:armv4tl:armv4l:armv3l",
296}
297
298# dict mapping arch -> ( multicompat, best personality, biarch personality )
299multilibArches = {
300 "x86_64": ( "athlon", "x86_64", "athlon" ),
301}
302
303# from yumUtils.py
304arches = {
305 # ia32
306 "athlon": "i686",
307 "i686": "i586",
308 "geode": "i586",
309 "i586": "i486",
310 "i486": "i386",
311 "i386": "noarch",
312
313 # amd64
314 "x86_64": "athlon",
315 "amd64": "x86_64",
316 "ia32e": "x86_64",
317
318 # arm
319 "armv7tnhl": "armv7nhl",
320 "armv7nhl": "armv7hl",
321 "armv7hl": "noarch",
322 "armv7l": "armv6l",
323 "armv6l": "armv5tejl",
324 "armv5tejl": "armv5tel",
325 "armv5tel": "noarch",
326
327 #itanium
328 "ia64": "noarch",
329}
330
331def isMultiLibArch(arch=None):
332 """returns true if arch is a multilib arch, false if not"""
333 if arch is None:
334 arch = getCanonArch()
335
336 if not arches.has_key(arch): # or we could check if it is noarch
337 return False
338
339 if multilibArches.has_key(arch):
340 return True
341
342 if multilibArches.has_key(arches[arch]):
343 return True
344
345 return False
346
347def getBaseArch():
348 myarch = getCanonArch()
349 if not arches.has_key(myarch):
350 return myarch
351
352 if isMultiLibArch(arch=myarch):
353 if multilibArches.has_key(myarch):
354 return myarch
355 else:
356 return arches[myarch]
357
358 if arches.has_key(myarch):
359 basearch = myarch
360 value = arches[basearch]
361 while value != 'noarch':
362 basearch = value
363 value = arches[basearch]
364
365 return basearch
366
367def checkRpmIntegrity(bin_rpm, package):
368 return runner.quiet([bin_rpm, "-K", "--nosignature", package])
369
370def checkSig(ts, package):
371 """ Takes a transaction set and a package, check it's sigs,
372 return 0 if they are all fine
373 return 1 if the gpg key can't be found
374 return 2 if the header is in someway damaged
375 return 3 if the key is not trusted
376 return 4 if the pkg is not gpg or pgp signed
377 """
378
379 value = 0
380 currentflags = ts.setVSFlags(0)
381 fdno = os.open(package, os.O_RDONLY)
382 try:
383 hdr = ts.hdrFromFdno(fdno)
384
385 except rpm.error, e:
386 if str(e) == "public key not availaiable":
387 value = 1
388 if str(e) == "public key not available":
389 value = 1
390 if str(e) == "public key not trusted":
391 value = 3
392 if str(e) == "error reading package header":
393 value = 2
394 else:
395 error, siginfo = getSigInfo(hdr)
396 if error == 101:
397 os.close(fdno)
398 del hdr
399 value = 4
400 else:
401 del hdr
402
403 try:
404 os.close(fdno)
405 except OSError:
406 pass
407
408 ts.setVSFlags(currentflags) # put things back like they were before
409 return value
410
411def getSigInfo(hdr):
412 """ checks signature from an hdr hand back signature information and/or
413 an error code
414 """
415
416 import locale
417 locale.setlocale(locale.LC_ALL, 'C')
418
419 string = '%|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|'
420 siginfo = hdr.sprintf(string)
421 if siginfo != '(none)':
422 error = 0
423 sigtype, sigdate, sigid = siginfo.split(',')
424 else:
425 error = 101
426 sigtype = 'MD5'
427 sigdate = 'None'
428 sigid = 'None'
429
430 infotuple = (sigtype, sigdate, sigid)
431 return error, infotuple
432
433def checkRepositoryEULA(name, repo):
434 """ This function is to check the EULA file if provided.
435 return True: no EULA or accepted
436 return False: user declined the EULA
437 """
438
439 import tempfile
440 import shutil
441 import urlparse
442 import urllib2 as u2
443 import httplib
444 from mic.utils.errors import CreatorError
445
446 def _check_and_download_url(u2opener, url, savepath):
447 try:
448 if u2opener:
449 f = u2opener.open(url)
450 else:
451 f = u2.urlopen(url)
452 except u2.HTTPError, httperror:
453 if httperror.code in (404, 503):
454 return None
455 else:
456 raise CreatorError(httperror)
457 except OSError, oserr:
458 if oserr.errno == 2:
459 return None
460 else:
461 raise CreatorError(oserr)
462 except IOError, oserr:
463 if hasattr(oserr, "reason") and oserr.reason.errno == 2:
464 return None
465 else:
466 raise CreatorError(oserr)
467 except u2.URLError, err:
468 raise CreatorError(err)
469 except httplib.HTTPException, e:
470 raise CreatorError(e)
471
472 # save to file
473 licf = open(savepath, "w")
474 licf.write(f.read())
475 licf.close()
476 f.close()
477
478 return savepath
479
480 def _pager_file(savepath):
481
482 if os.path.splitext(savepath)[1].upper() in ('.HTM', '.HTML'):
483 pagers = ('w3m', 'links', 'lynx', 'less', 'more')
484 else:
485 pagers = ('less', 'more')
486
487 file_showed = False
488 for pager in pagers:
489 cmd = "%s %s" % (pager, savepath)
490 try:
491 os.system(cmd)
492 except OSError:
493 continue
494 else:
495 file_showed = True
496 break
497
498 if not file_showed:
499 f = open(savepath)
500 msger.raw(f.read())
501 f.close()
502 msger.pause()
503
504 # when proxy needed, make urllib2 follow it
505 proxy = repo.proxy
506 proxy_username = repo.proxy_username
507 proxy_password = repo.proxy_password
508
509 if not proxy:
510 proxy = get_proxy_for(repo.baseurl[0])
511
512 handlers = []
513 auth_handler = u2.HTTPBasicAuthHandler(u2.HTTPPasswordMgrWithDefaultRealm())
514 u2opener = None
515 if proxy:
516 if proxy_username:
517 proxy_netloc = urlparse.urlsplit(proxy).netloc
518 if proxy_password:
519 proxy_url = 'http://%s:%s@%s' % (proxy_username, proxy_password, proxy_netloc)
520 else:
521 proxy_url = 'http://%s@%s' % (proxy_username, proxy_netloc)
522 else:
523 proxy_url = proxy
524
525 proxy_support = u2.ProxyHandler({'http': proxy_url,
526 'https': proxy_url,
527 'ftp': proxy_url})
528 handlers.append(proxy_support)
529
530 # download all remote files to one temp dir
531 baseurl = None
532 repo_lic_dir = tempfile.mkdtemp(prefix = 'repolic')
533
534 for url in repo.baseurl:
535 tmphandlers = handlers[:]
536
537 (scheme, host, path, parm, query, frag) = urlparse.urlparse(url.rstrip('/') + '/')
538 if scheme not in ("http", "https", "ftp", "ftps", "file"):
539 raise CreatorError("Error: invalid url %s" % url)
540
541 if '@' in host:
542 try:
543 user_pass, host = host.split('@', 1)
544 if ':' in user_pass:
545 user, password = user_pass.split(':', 1)
546 except ValueError, e:
547 raise CreatorError('Bad URL: %s' % url)
548
549 msger.verbose("adding HTTP auth: %s, XXXXXXXX" %(user))
550 auth_handler.add_password(None, host, user, password)
551 tmphandlers.append(auth_handler)
552 url = scheme + "://" + host + path + parm + query + frag
553
554 if tmphandlers:
555 u2opener = u2.build_opener(*tmphandlers)
556
557 # try to download
558 repo_eula_url = urlparse.urljoin(url, "LICENSE.txt")
559 repo_eula_path = _check_and_download_url(
560 u2opener,
561 repo_eula_url,
562 os.path.join(repo_lic_dir, repo.id + '_LICENSE.txt'))
563 if repo_eula_path:
564 # found
565 baseurl = url
566 break
567
568 if not baseurl:
569 shutil.rmtree(repo_lic_dir) #cleanup
570 return True
571
572 # show the license file
573 msger.info('For the software packages in this yum repo:')
574 msger.info(' %s: %s' % (name, baseurl))
575 msger.info('There is an "End User License Agreement" file that need to be checked.')
576 msger.info('Please read the terms and conditions outlined in it and answer the followed qustions.')
577 msger.pause()
578
579 _pager_file(repo_eula_path)
580
581 # Asking for the "Accept/Decline"
582 if not msger.ask('Would you agree to the terms and conditions outlined in the above End User License Agreement?'):
583 msger.warning('Will not install pkgs from this repo.')
584 shutil.rmtree(repo_lic_dir) #cleanup
585 return False
586
587 # try to find support_info.html for extra infomation
588 repo_info_url = urlparse.urljoin(baseurl, "support_info.html")
589 repo_info_path = _check_and_download_url(
590 u2opener,
591 repo_info_url,
592 os.path.join(repo_lic_dir, repo.id + '_support_info.html'))
593 if repo_info_path:
594 msger.info('There is one more file in the repo for additional support information, please read it')
595 msger.pause()
596 _pager_file(repo_info_path)
597
598 #cleanup
599 shutil.rmtree(repo_lic_dir)
600 return True