Esempio n. 1
0
 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))
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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)
Esempio n. 5
0
    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)
Esempio n. 6
0
    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
Esempio n. 7
0
    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)
Esempio n. 8
0
    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)
Esempio n. 9
0
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
Esempio n. 10
0
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
Esempio n. 11
0
 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")
Esempio n. 13
0
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'&lt;',
                                  b'<').replace(b'&gt;',
                                                b'>').replace(b'&amp;', 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
Esempio n. 14
0
File: fetch.py Progetto: jayvdb/osc
    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)
Esempio n. 15
0
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'&lt;', b'<').replace(b'&gt;' , b'>').replace(b'&amp;', 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
Esempio n. 16
0
File: fetch.py Progetto: lnussel/osc
    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)