Beispiel #1
0
    def _file_conflict_is_permitted(self, left, right, filename):
        """
        Returns True if rpm would allow both the given packages to share 
        ownership of the given filename.
        """
        if not hasattr(rpm, 'files'):
            return self._file_conflict_is_permitted_rpm411(
                left, right, filename)

        ts = rpm.TransactionSet()
        ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)

        left_hdr = ts.hdrFromFdno(open(left.lookup_location()[0], 'rb'))
        right_hdr = ts.hdrFromFdno(open(self.download_package(right), 'rb'))
        left_files = rpm.files(left_hdr)
        right_files = rpm.files(right_hdr)
        if left_files[filename].matches(right_files[filename]):
            logger.debug(
                'Conflict on %s between %s and %s permitted because files match',
                filename, left, right)
            return True
        if left_files[filename].color != right_files[filename].color:
            logger.debug(
                'Conflict on %s between %s and %s permitted because colors differ',
                filename, left, right)
            return True
        return False
Beispiel #2
0
def test_conflict_is_ignored_if_file_colors_are_different(request, dir_server):
    # This is part of RPM's multilib support. If two packages own the same file
    # but the file color is different in each, the preferred color wins (and
    # there is no conflict). This lets both .i386 and .x86_64 packages own
    # /bin/bash while installing only the .x86_64 version.
    p2 = rpmfluff.SimpleRpmBuild('a', '0.1', '1', ['i386', 'x86_64'])
    p2.add_simple_compilation(installPath='usr/bin/thing')
    baserepo = rpmfluff.YumRepoBuild([p2])
    baserepo.make('i386', 'x86_64')
    dir_server.basepath = baserepo.repoDir

    p1 = rpmfluff.SimpleRpmBuild('a', '0.2', '1', ['i386', 'x86_64'])
    p1.add_simple_compilation(installPath='usr/bin/thing')
    p1.make()

    def cleanUp():
        shutil.rmtree(baserepo.repoDir)
        shutil.rmtree(p2.get_base_dir())
        shutil.rmtree(p1.get_base_dir())

    request.addfinalizer(cleanUp)

    # Make sure we really have different files with different colors
    # (this was surprisingly hard to get right)
    rpmheader_32 = p1.get_built_rpm_header('i386')
    rpmheader_64 = p1.get_built_rpm_header('x86_64')
    if hasattr(rpm, 'files'):  # rpm 4.12+
        assert 1 == rpm.files(rpmheader_32)['/usr/bin/thing'].color
        assert 2 == rpm.files(rpmheader_64)['/usr/bin/thing'].color
    else:  # sad old rpm < 4.12
        fi_32 = rpm.fi(rpmheader_32)
        while fi_32.FN() != '/usr/bin/thing':
            fi_32.next()
        assert fi_32.FColor() == 1
        fi_64 = rpm.fi(rpmheader_64)
        while fi_64.FN() != '/usr/bin/thing':
            fi_64.next()
        assert fi_64.FColor() == 2

    exitcode, out, err = run_rpmdeplint([
        'rpmdeplint', 'check-conflicts',
        '--repo=base,{}'.format(dir_server.url),
        p1.get_built_rpm('i386')
    ])
    assert exitcode == 0
def test_conflict_is_ignored_if_file_colors_are_different(request, dir_server):
    # This is part of RPM's multilib support. If two packages own the same file 
    # but the file color is different in each, the preferred color wins (and 
    # there is no conflict). This lets both .i386 and .x86_64 packages own 
    # /bin/bash while installing only the .x86_64 version.
    p2 = rpmfluff.SimpleRpmBuild('a', '0.1', '1', ['i386', 'x86_64'])
    p2.add_simple_compilation(installPath='usr/bin/thing')
    baserepo = rpmfluff.YumRepoBuild([p2])
    baserepo.make('i386', 'x86_64')
    dir_server.basepath = baserepo.repoDir

    p1 = rpmfluff.SimpleRpmBuild('a', '0.2', '1', ['i386', 'x86_64'])
    p1.add_simple_compilation(installPath='usr/bin/thing')
    p1.make()

    def cleanUp():
        shutil.rmtree(baserepo.repoDir)
        shutil.rmtree(p2.get_base_dir())
        shutil.rmtree(p1.get_base_dir())
    request.addfinalizer(cleanUp)

    # Make sure we really have different files with different colors
    # (this was surprisingly hard to get right)
    rpmheader_32 = p1.get_built_rpm_header('i386')
    rpmheader_64 = p1.get_built_rpm_header('x86_64')
    if hasattr(rpm, 'files'): # rpm 4.12+
        assert 1 == rpm.files(rpmheader_32)['/usr/bin/thing'].color
        assert 2 == rpm.files(rpmheader_64)['/usr/bin/thing'].color
    else: # sad old rpm < 4.12
        fi_32 = rpm.fi(rpmheader_32)
        while fi_32.FN() != '/usr/bin/thing':
            fi_32.next()
        assert fi_32.FColor() == 1
        fi_64 = rpm.fi(rpmheader_64)
        while fi_64.FN() != '/usr/bin/thing':
            fi_64.next()
        assert fi_64.FColor() == 2

    exitcode, out, err = run_rpmdeplint(['rpmdeplint', 'check-conflicts',
                                         '--repo=base,{}'.format(dir_server.url),
                                         p1.get_built_rpm('i386')])
    assert exitcode == 0
Beispiel #4
0
    def _file_conflict_is_permitted(self, left, right, filename):
        """
        Returns True if rpm would allow both the given packages to share 
        ownership of the given filename.
        """
        if not hasattr(rpm, 'files'):
            return self._file_conflict_is_permitted_rpm411(left, right, filename)

        ts = rpm.TransactionSet()
        ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)

        left_hdr = ts.hdrFromFdno(open(left.lookup_location()[0], 'rb'))
        right_hdr = ts.hdrFromFdno(open(self.download_package(right), 'rb'))
        left_files = rpm.files(left_hdr)
        right_files = rpm.files(right_hdr)
        if left_files[filename].matches(right_files[filename]):
            logger.debug('Conflict on %s between %s and %s permitted because files match',
                    filename, left, right)
            return True
        if left_files[filename].color != right_files[filename].color:
            logger.debug('Conflict on %s between %s and %s permitted because colors differ',
                    filename, left, right)
            return True
        return False
Beispiel #5
0
    def _check_rpm(self, repo, rpm_dir, rpm_file, test_name):
        """Check the contents of the rpm against the expected test results
        """
        ts = rpm.TransactionSet()
        fd = os.open(os.path.join(rpm_dir, rpm_file), os.O_RDONLY)
        hdr = ts.hdrFromFdno(fd)
        os.close(fd)

        self.assertEqual(hdr[rpm.RPMTAG_NAME].decode("UTF-8"), repo["rpmname"])
        self.assertEqual(hdr[rpm.RPMTAG_VERSION].decode("UTF-8"), repo["rpmversion"])
        self.assertEqual(hdr[rpm.RPMTAG_RELEASE].decode("UTF-8"), repo["rpmrelease"])
        self.assertEqual(hdr[rpm.RPMTAG_URL].decode("UTF-8"), repo["repo"])

        files = sorted(f.name for f in rpm.files(hdr) if stat.S_ISREG(f.mode))
        self.assertEqual(files, [os.path.join(repo["destination"], f) for f in self.test_results[test_name]])
Beispiel #6
0
 def read_rpm(filename):
     rpm.addMacro("_dbpath", os.path.join(dirname(__file__), "fake_pkg_db"))
     rpm.addMacro("_topdir", dirname(__file__))
     ts = rpm.TransactionSet(
         ".", rpm.RPMVSF_MASK_NODIGESTS | rpm.RPMVSF_MASK_NOSIGNATURES)
     fd = rpm.fd.open(filename)
     header = ts.hdrFromFdno(fd)
     # hdr[rpm.RPMTAG_NAME] = "test_rpm"
     # fo = os.fdopen(fd, "w+")
     # hdr.write(fd)
     print(header[rpm.RPMTAG_NAME])
     files = rpm.files(header)
     payload = rpm.fd.open(fd, flags=header["payloadcompressor"])
     archive = files.archive(payload, write=False)
     for t in archive:
         if t.fflags & rpm.RPMFILE_SPECFILE:
             od = os.open(t.name, os.O_RDWR | os.O_CREAT)
             archive.readto(od)
         print(t.name)
Beispiel #7
0
def spec_from_srpm(srpm_path):
    ts = rpm.ts()
    fd = rpm.fd.open(srpm_path)
    try:
        hdr = ts.hdrFromFdno(fd)
        if not hdr.isSource():
            raise ValueError('Not an SRPM: {}'.format(srpm_path))
        files = rpm.files(hdr)
        payload = rpm.fd.open(fd,
                              flags=bytes(hdr['PAYLOADCOMPRESSOR']).decode())
        try:
            archive = files.archive(payload)
            for f in archive:
                if f.fflags & rpm.RPMFILE_SPECFILE:
                    return archive.read()
        finally:
            rpm.fd.close(payload)
    finally:
        rpm.fd.close(fd)
    raise ValueError('No spec file found in SRPM: {}'.format(srpm_path))
Beispiel #8
0
    def _check_rpm(self, repo, rpm_dir, rpm_file, test_name):
        """Check the contents of the rpm against the expected test results
        """
        ts = rpm.TransactionSet()
        fd = os.open(os.path.join(rpm_dir, rpm_file), os.O_RDONLY)
        hdr = ts.hdrFromFdno(fd)
        os.close(fd)

        self.assertEqual(hdr[rpm.RPMTAG_NAME], repo["rpmname"])
        self.assertEqual(hdr[rpm.RPMTAG_VERSION], repo["rpmversion"])
        self.assertEqual(hdr[rpm.RPMTAG_RELEASE], repo["rpmrelease"])
        self.assertEqual(hdr[rpm.RPMTAG_URL], repo["repo"])

        files = sorted(f.name for f in rpm.files(hdr) if stat.S_ISREG(f.mode))
        self.assertEqual(files, [
            os.path.join(repo["destination"], f)
            for f in self.test_results[test_name]
        ])

        # / should never be included in the rpm, doing so conflicts with the filesystem package
        self.assertFalse(any(True for f in files if f == "/"))