def canonname(self): if self.is_nosrc(): arch = 'nosrc' elif self.is_src(): arch = 'src' else: arch = self.arch() return RpmQuery.filename(decode_it(self.name()), None, decode_it(self.version()), decode_it(self.release()), decode_it(arch))
def testDecodeIt(self): bytes_obj = b'Test the decoding' string_obj = 'Test the decoding' out = decode_it(bytes_obj) self.assertEqual(out, string_obj) out = decode_it(string_obj) self.assertEqual(out, string_obj)
def rpmvercmp(ver1, ver2): """ implementation of RPM's version comparison algorithm (as described in lib/rpmvercmp.c) """ if ver1 == ver2: return 0 res = 0 ver1 = decode_it(ver1) ver2 = decode_it(ver2) while res == 0: # remove all leading non alphanumeric or tilde chars ver1 = re.sub('^[^a-zA-Z0-9~]*', '', ver1) ver2 = re.sub('^[^a-zA-Z0-9~]*', '', ver2) if ver1.startswith('~') or ver2.startswith('~'): if not ver1.startswith('~'): return 1 elif not ver2.startswith('~'): return -1 ver1 = ver1[1:] ver2 = ver2[1:] continue if not (len(ver1) and len(ver2)): break # check if we have a digits segment mo1 = re.match('(\d+)', ver1) mo2 = re.match('(\d+)', ver2) numeric = True if mo1 is None: mo1 = re.match('([a-zA-Z]+)', ver1) mo2 = re.match('([a-zA-Z]+)', ver2) numeric = False # check for different types: alpha and numeric if mo2 is None: if numeric: return 1 return -1 seg1 = mo1.group(0) ver1 = ver1[mo1.end(0):] seg2 = mo2.group(1) ver2 = ver2[mo2.end(1):] if numeric: # remove leading zeros seg1 = re.sub('^0+', '', seg1) seg2 = re.sub('^0+', '', seg2) # longer digit segment wins - if both have the same length # a simple ascii compare decides res = len(seg1) - len(seg2) or cmp(seg1, seg2) else: res = cmp(seg1, seg2) if res > 0: return 1 elif res < 0: return -1 return cmp(ver1, ver2)
def testDecodeIt(self): bytes_obj = b'Test the decoding' string_obj = 'Test the decoding' out = decode_it(bytes_obj) self.assertEqual(out, string_obj) out = decode_it(string_obj) self.assertEqual(out, string_obj)
def rpmvercmp(ver1, ver2): """ implementation of RPM's version comparison algorithm (as described in lib/rpmvercmp.c) """ if ver1 == ver2: return 0 res = 0 ver1 = decode_it(ver1) ver2 = decode_it(ver2) while res == 0: # remove all leading non alphanumeric or tilde chars ver1 = re.sub('^[^a-zA-Z0-9~]*', '', ver1) ver2 = re.sub('^[^a-zA-Z0-9~]*', '', ver2) if ver1.startswith('~') or ver2.startswith('~'): if not ver1.startswith('~'): return 1 elif not ver2.startswith('~'): return -1 ver1 = ver1[1:] ver2 = ver2[1:] continue if not (len(ver1) and len(ver2)): break # check if we have a digits segment mo1 = re.match('(\d+)', ver1) mo2 = re.match('(\d+)', ver2) numeric = True if mo1 is None: mo1 = re.match('([a-zA-Z]+)', ver1) mo2 = re.match('([a-zA-Z]+)', ver2) numeric = False # check for different types: alpha and numeric if mo2 is None: if numeric: return 1 return -1 seg1 = mo1.group(0) ver1 = ver1[mo1.end(0):] seg2 = mo2.group(1) ver2 = ver2[mo2.end(1):] if numeric: # remove leading zeros seg1 = re.sub('^0+', '', seg1) seg2 = re.sub('^0+', '', seg2) # longer digit segment wins - if both have the same length # a simple ascii compare decides res = len(seg1) - len(seg2) or cmp(seg1, seg2) else: res = cmp(seg1, seg2) if res > 0: return 1 elif res < 0: return -1 return cmp(ver1, ver2)
def evr(self): evr = decode_it(self.version()) if self.release(): evr += "-" + decode_it(self.release()) epoch = self.epoch() if epoch is not None and epoch != 0: evr = epoch + ":" + evr return evr
def __setitem__(self, name, query): if decode_it(name) != decode_it(query.name()): raise ValueError("key '%s' does not match " "package query name '%s'" % (name, query.name())) architecture = decode_it(query.arch()) if (architecture in [self.wanted_architecture, 'noarch', 'all', 'any'] or self.wanted_architecture in self.architectureMap.get( architecture, [])): current_query = self.get(name) # if current query does not exist or is older than this new query if current_query is None or current_query.vercmp(query) <= 0: super(PackageQueries, self).__setitem__(name, query)
def move_package(self, tmpfile, destdir, pac_obj=None): import shutil canonname = None if pac_obj and pac_obj.name.startswith('container:'): canonname = pac_obj.canonname if canonname is None: pkgq = packagequery.PackageQuery.query(tmpfile, extra_rpmtags=(1044, 1051, 1052)) if pkgq: canonname = pkgq.canonname() else: if pac_obj is None: print('Unsupported file type: ', tmpfile, file=sys.stderr) sys.exit(1) canonname = pac_obj.binary decoded_canonname = decode_it(canonname) if b'/' in canonname or '/' in decoded_canonname: raise oscerr.OscIOError(None, 'canonname contains a slash') fullfilename = os.path.join(destdir, decoded_canonname) if pac_obj is not None: pac_obj.canonname = canonname pac_obj.fullfilename = fullfilename shutil.move(tmpfile, fullfilename) os.chmod(fullfilename, 0o644)
def source_file_load(apiurl, project, package, filename, revision=None): query = {'expand': 1} if revision: query['rev'] = revision url = makeurl(apiurl, ['source', project, package, filename], query) try: return decode_it(http_GET(url).read()) except HTTPError: return None
def source_file_load(apiurl, project, package, filename, revision=None): query = {'expand': 1} if revision: query['rev'] = revision url = makeurl(apiurl, ['source', project, package, filename], query) try: return decode_it(http_GET(url).read()) except HTTPError: return None
def do_prjresults(self, subcmd, opts, *args): project = args[0] apiurl = self.get_api_url() kwargs = {} kwargs['wait'] = True last = None for results in get_package_results(apiurl, project, package=None, **kwargs): last = results print(decode_it(results)) if last and is_package_results_success(last): return return 3
def virtually_accept_delete(self, request_id, package): self.api.add_review(request_id, by_group=self.api.cdelreq_review, msg='Request accepted. Cleanup in progress - DO NOT REVOKE!') filelist = self.api.get_filelist_for_package(pkgname=package, project=self.api.project, expand='1', extension='spec') pkgs = self.api.extract_specfile_short(filelist) # Disable build and wipes the binary to the package and the sub-package for pkg in pkgs: meta = decode_it(b''.join(show_package_meta(self.api.apiurl, self.api.project, pkg))) # Update package meta to disable build self.api.create_package_container(self.api.project, pkg, meta=meta, disable_build=True) wipebinaries(self.api.apiurl, self.api.project, package=pkg, repo=self.api.cmain_repo) # Remove package from Rings if self.api.ring_packages.get(pkg): delete_package(self.api.apiurl, self.api.ring_packages.get(pkg), pkg, force=True, msg="Cleanup package in Rings")
def run(prg, argv=None): try: try: if '--debugger' in sys.argv: pdb.set_trace() # here we actually run the program: return prg.main(argv) except: # look for an option in the prg.options object and in the config # dict print stack trace, if desired if getattr(prg.options, 'traceback', None) or getattr(prg.conf, 'config', {}).get('traceback', None) or \ getattr(prg.options, 'post_mortem', None) or getattr(prg.conf, 'config', {}).get('post_mortem', None): traceback.print_exc(file=sys.stderr) # we could use http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52215 # enter the debugger, if desired if getattr(prg.options, 'post_mortem', None) or getattr( prg.conf, 'config', {}).get('post_mortem', None): if sys.stdout.isatty() and not hasattr(sys, 'ps1'): pdb.post_mortem(sys.exc_info()[2]) else: print('sys.stdout is not a tty. Not jumping into pdb.', file=sys.stderr) raise except oscerr.SignalInterrupt: print('killed!', file=sys.stderr) except KeyboardInterrupt: print('interrupted!', file=sys.stderr) return 130 except oscerr.UserAbort: print('aborted.', file=sys.stderr) except oscerr.APIError as e: print('BuildService API error:', e.msg, file=sys.stderr) except oscerr.LinkExpandError as e: print('Link "%s/%s" cannot be expanded:\n' % (e.prj, e.pac), e.msg, file=sys.stderr) print('Use "osc repairlink" to fix merge conflicts.\n', file=sys.stderr) except oscerr.WorkingCopyWrongVersion as e: print(e, file=sys.stderr) except oscerr.NoWorkingCopy as e: print(e, file=sys.stderr) if os.path.isdir('.git'): print("Current directory looks like git.", file=sys.stderr) if os.path.isdir('.hg'): print("Current directory looks like mercurial.", file=sys.stderr) if os.path.isdir('.svn'): print("Current directory looks like svn.", file=sys.stderr) if os.path.isdir('CVS'): print("Current directory looks like cvs.", file=sys.stderr) except HTTPError as e: print('Server returned an error:', e, file=sys.stderr) if hasattr(e, 'osc_msg'): print(e.osc_msg, file=sys.stderr) try: body = e.read() except AttributeError: body = '' if getattr(prg.options, 'debug', None) or \ getattr(prg.conf, 'config', {}).get('debug', None): print(e.hdrs, file=sys.stderr) print(body, file=sys.stderr) if e.code in [400, 403, 404, 500]: if b'<summary>' in body: msg = body.split(b'<summary>')[1] msg = msg.split(b'</summary>')[0] msg = msg.replace(b'<', b'<').replace(b'>', b'>').replace(b'&', b'&') print(decode_it(msg), file=sys.stderr) if e.code >= 500 and e.code <= 599: print('\nRequest: %s' % e.filename) print('Headers:') for h, v in e.hdrs.items(): if h != 'Set-Cookie': print("%s: %s" % (h, v)) except BadStatusLine as e: print('Server returned an invalid response:', e, file=sys.stderr) print(e.line, file=sys.stderr) except HTTPException as e: print(e, file=sys.stderr) except URLError as e: print('Failed to reach a server:\n', e.reason, file=sys.stderr) except IOError as e: # ignore broken pipe if e.errno != errno.EPIPE: raise except OSError as e: if e.errno != errno.ENOENT: raise print(e, file=sys.stderr) except (oscerr.ConfigError, oscerr.NoConfigfile) as e: print(e.msg, file=sys.stderr) except oscerr.OscIOError as e: print(e.msg, file=sys.stderr) if getattr(prg.options, 'debug', None) or \ getattr(prg.conf, 'config', {}).get('debug', None): print(e.e, file=sys.stderr) except (oscerr.WrongOptions, oscerr.WrongArgs) as e: print(e, file=sys.stderr) return 2 except oscerr.ExtRuntimeError as e: print(e.file + ':', e.msg, file=sys.stderr) except oscerr.ServiceRuntimeError as e: print(e.msg, file=sys.stderr) except oscerr.WorkingCopyOutdated as e: print(e, file=sys.stderr) except (oscerr.PackageExists, oscerr.PackageMissing, oscerr.WorkingCopyInconsistent) as e: print(e.msg, file=sys.stderr) except oscerr.PackageInternalError as e: print('a package internal error occured\n' \ 'please file a bug and attach your current package working copy ' \ 'and the following traceback to it:', file=sys.stderr) print(e.msg, file=sys.stderr) traceback.print_exc(file=sys.stderr) except oscerr.PackageError as e: print(e.msg, file=sys.stderr) except PackageError as e: print('%s:' % e.fname, e.msg, file=sys.stderr) except RPMError as e: print(e, file=sys.stderr) except SSLError as e: if 'tlsv1' in str(e): print('The python on this system does not support TLSv1.2', file=sys.stderr) print("SSL Error:", e, file=sys.stderr) except SSLVerificationError as e: print("Certificate Verification Error:", e, file=sys.stderr) except NoSecureSSLError as e: print(e, file=sys.stderr) except CpioError as e: print(e, file=sys.stderr) except oscerr.OscBaseError as e: print('*** Error:', e, file=sys.stderr) return 1
def __download_cpio_archive(self, apiurl, project, repo, arch, package, **pkgs): if not pkgs: return query = ['binary=%s' % quote_plus(i) for i in pkgs] query.append('view=cpio') try: url = makeurl(apiurl, ['build', project, repo, arch, package], query=query) sys.stdout.write("preparing download ...\r") sys.stdout.flush() with tempfile.NamedTemporaryFile( prefix='osc_build_cpio') as tmparchive: self.gr.urlgrab(url, filename=tmparchive.name, text='fetching packages for \'%s\'' % project) archive = cpio.CpioRead(tmparchive.name) archive.read() for hdr in archive: # XXX: we won't have an .errors file because we're using # getbinarylist instead of the public/... route # (which is routed to getbinaries) # getbinaries does not support kiwi builds if hdr.filename == '.errors': archive.copyin_file(hdr.filename) raise oscerr.APIError('CPIO archive is incomplete ' '(see .errors file)') if package == '_repository': n = re.sub(b'\.pkg\.tar\..z$', b'.arch', hdr.filename) if n.startswith(b'container:'): n = re.sub(b'\.tar\..z$', b'.tar', hdr.filename) pac = pkgs[decode_it(n.rsplit(b'.', 1)[0])] pac.canonname = hdr.filename else: pac = pkgs[decode_it(n.rsplit(b'.', 1)[0])] else: # this is a kiwi product pac = pkgs[decode_it(hdr.filename)] # Extract a single file from the cpio archive try: fd, tmpfile = tempfile.mkstemp(prefix='osc_build_file') archive.copyin_file(hdr.filename, os.path.dirname(tmpfile), os.path.basename(tmpfile)) self.move_package(tmpfile, pac.localdir, pac) finally: os.close(fd) if os.path.exists(tmpfile): os.unlink(tmpfile) for pac in pkgs.values(): if not os.path.isfile(pac.fullfilename): raise oscerr.APIError('failed to fetch file \'%s\': ' 'missing in CPIO archive' % pac.repofilename) except HTTPError as e: if e.code != 414: raise # query str was too large keys = list(pkgs.keys()) if len(keys) == 1: raise oscerr.APIError('unable to fetch cpio archive: ' 'server always returns code 414') n = int(len(pkgs) / 2) new_pkgs = dict([(k, pkgs[k]) for k in keys[:n]]) self.__download_cpio_archive(apiurl, project, repo, arch, package, **new_pkgs) new_pkgs = dict([(k, pkgs[k]) for k in keys[n:]]) self.__download_cpio_archive(apiurl, project, repo, arch, package, **new_pkgs)
def run(prg, argv=None): try: try: if '--debugger' in sys.argv: pdb.set_trace() # here we actually run the program: return prg.main(argv) except: # look for an option in the prg.options object and in the config # dict print stack trace, if desired if getattr(prg.options, 'traceback', None) or getattr(prg.conf, 'config', {}).get('traceback', None) or \ getattr(prg.options, 'post_mortem', None) or getattr(prg.conf, 'config', {}).get('post_mortem', None): traceback.print_exc(file=sys.stderr) # we could use http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52215 # enter the debugger, if desired if getattr(prg.options, 'post_mortem', None) or getattr(prg.conf, 'config', {}).get('post_mortem', None): if sys.stdout.isatty() and not hasattr(sys, 'ps1'): pdb.post_mortem(sys.exc_info()[2]) else: print('sys.stdout is not a tty. Not jumping into pdb.', file=sys.stderr) raise except oscerr.SignalInterrupt: print('killed!', file=sys.stderr) except KeyboardInterrupt: print('interrupted!', file=sys.stderr) return 130 except oscerr.UserAbort: print('aborted.', file=sys.stderr) except oscerr.APIError as e: print('BuildService API error:', e.msg, file=sys.stderr) except oscerr.LinkExpandError as e: print('Link "%s/%s" cannot be expanded:\n' % (e.prj, e.pac), e.msg, file=sys.stderr) print('Use "osc repairlink" to fix merge conflicts.\n', file=sys.stderr) except oscerr.WorkingCopyWrongVersion as e: print(e, file=sys.stderr) except oscerr.NoWorkingCopy as e: print(e, file=sys.stderr) if os.path.isdir('.git'): print("Current directory looks like git.", file=sys.stderr) if os.path.isdir('.hg'): print("Current directory looks like mercurial.", file=sys.stderr) if os.path.isdir('.svn'): print("Current directory looks like svn.", file=sys.stderr) if os.path.isdir('CVS'): print("Current directory looks like cvs.", file=sys.stderr) except HTTPError as e: print('Server returned an error:', e, file=sys.stderr) if hasattr(e, 'osc_msg'): print(e.osc_msg, file=sys.stderr) try: body = e.read() except AttributeError: body = '' if getattr(prg.options, 'debug', None) or \ getattr(prg.conf, 'config', {}).get('debug', None): print(e.hdrs, file=sys.stderr) print(body, file=sys.stderr) if e.code in [400, 403, 404, 500]: if b'<summary>' in body: msg = body.split(b'<summary>')[1] msg = msg.split(b'</summary>')[0] msg = msg.replace(b'<', b'<').replace(b'>' , b'>').replace(b'&', b'&') print(decode_it(msg), file=sys.stderr) if e.code >= 500 and e.code <= 599: print('\nRequest: %s' % e.filename) print('Headers:') for h, v in e.hdrs.items(): if h != 'Set-Cookie': print("%s: %s" % (h, v)) except BadStatusLine as e: print('Server returned an invalid response:', e, file=sys.stderr) print(e.line, file=sys.stderr) except HTTPException as e: print(e, file=sys.stderr) except URLError as e: print('Failed to reach a server:\n', e.reason, file=sys.stderr) except IOError as e: # ignore broken pipe if e.errno != errno.EPIPE: raise except OSError as e: if e.errno != errno.ENOENT: raise print(e, file=sys.stderr) except (oscerr.ConfigError, oscerr.NoConfigfile) as e: print(e.msg, file=sys.stderr) except oscerr.OscIOError as e: print(e.msg, file=sys.stderr) if getattr(prg.options, 'debug', None) or \ getattr(prg.conf, 'config', {}).get('debug', None): print(e.e, file=sys.stderr) except (oscerr.WrongOptions, oscerr.WrongArgs) as e: print(e, file=sys.stderr) return 2 except oscerr.ExtRuntimeError as e: print(e.file + ':', e.msg, file=sys.stderr) except oscerr.ServiceRuntimeError as e: print(e.msg, file=sys.stderr) except oscerr.WorkingCopyOutdated as e: print(e, file=sys.stderr) except (oscerr.PackageExists, oscerr.PackageMissing, oscerr.WorkingCopyInconsistent) as e: print(e.msg, file=sys.stderr) except oscerr.PackageInternalError as e: print('a package internal error occured\n' \ 'please file a bug and attach your current package working copy ' \ 'and the following traceback to it:', file=sys.stderr) print(e.msg, file=sys.stderr) traceback.print_exc(file=sys.stderr) except oscerr.PackageError as e: print(e.msg, file=sys.stderr) except PackageError as e: print('%s:' % e.fname, e.msg, file=sys.stderr) except RPMError as e: print(e, file=sys.stderr) except SSLError as e: print("SSL Error:", e, file=sys.stderr) except SSLVerificationError as e: print("Certificate Verification Error:", e, file=sys.stderr) except NoSecureSSLError as e: print(e, file=sys.stderr) except CpioError as e: print(e, file=sys.stderr) except oscerr.OscBaseError as e: print('*** Error:', e, file=sys.stderr) return 1
def __download_cpio_archive(self, apiurl, project, repo, arch, package, **pkgs): if not pkgs: return query = ['binary=%s' % quote_plus(i) for i in pkgs] query.append('view=cpio') try: url = makeurl(apiurl, ['build', project, repo, arch, package], query=query) sys.stdout.write("preparing download ...\r") sys.stdout.flush() with tempfile.NamedTemporaryFile(prefix='osc_build_cpio') as tmparchive: self.gr.urlgrab(url, filename=tmparchive.name, text='fetching packages for \'%s\'' % project) archive = cpio.CpioRead(tmparchive.name) archive.read() for hdr in archive: # XXX: we won't have an .errors file because we're using # getbinarylist instead of the public/... route # (which is routed to getbinaries) # getbinaries does not support kiwi builds if hdr.filename == '.errors': archive.copyin_file(hdr.filename) raise oscerr.APIError('CPIO archive is incomplete ' '(see .errors file)') if package == '_repository': n = re.sub(b'\.pkg\.tar\..z$', b'.arch', hdr.filename) if n.startswith(b'container:'): n = re.sub(b'\.tar\..z$', b'.tar', hdr.filename) pac = pkgs[decode_it(n.rsplit(b'.', 1)[0])] pac.canonname = hdr.filename else: pac = pkgs[decode_it(n.rsplit(b'.', 1)[0])] else: # this is a kiwi product pac = pkgs[decode_it(hdr.filename)] # Extract a single file from the cpio archive try: fd, tmpfile = tempfile.mkstemp(prefix='osc_build_file') archive.copyin_file(hdr.filename, os.path.dirname(tmpfile), os.path.basename(tmpfile)) self.move_package(tmpfile, pac.localdir, pac) finally: os.close(fd) if os.path.exists(tmpfile): os.unlink(tmpfile) for pac in pkgs.values(): if not os.path.isfile(pac.fullfilename): raise oscerr.APIError('failed to fetch file \'%s\': ' 'missing in CPIO archive' % pac.repofilename) except HTTPError as e: if e.code != 414: raise # query str was too large keys = list(pkgs.keys()) if len(keys) == 1: raise oscerr.APIError('unable to fetch cpio archive: ' 'server always returns code 414') n = int(len(pkgs) / 2) new_pkgs = dict([(k, pkgs[k]) for k in keys[:n]]) self.__download_cpio_archive(apiurl, project, repo, arch, package, **new_pkgs) new_pkgs = dict([(k, pkgs[k]) for k in keys[n:]]) self.__download_cpio_archive(apiurl, project, repo, arch, package, **new_pkgs)