Esempio n. 1
0
    def _file_conflict_is_permitted_rpm411(self, left, right, filename):
        # In rpm 4.12+ the rpmfilesCompare() function is exposed nicely as the
        # rpm.files.matches Python method. In earlier rpm versions there is
        # nothing equivalent in the Python bindings, although we can use ctypes
        # to poke around and call the older rpmfiCompare() C API directly...
        librpm = ctypes.CDLL('librpm.so.3')
        _rpm = ctypes.CDLL(
            os.path.join(os.path.dirname(rpm.__file__), '_rpm.so'))

        class rpmfi_s(ctypes.Structure):
            pass

        librpm.rpmfiCompare.argtypes = [
            ctypes.POINTER(rpmfi_s),
            ctypes.POINTER(rpmfi_s)
        ]
        librpm.rpmfiCompare.restype = ctypes.c_int
        _rpm.fiFromFi.argtypes = [ctypes.py_object]
        _rpm.fiFromFi.restype = ctypes.POINTER(rpmfi_s)

        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_fi = rpm.fi(left_hdr)
        try:
            while left_fi.FN() != filename:
                left_fi.next()
        except StopIteration:
            raise KeyError('Entry %s not found in %s' % (filename, left))
        right_fi = rpm.fi(right_hdr)
        try:
            while right_fi.FN() != filename:
                right_fi.next()
        except StopIteration:
            raise KeyError('Entry %s not found in %s' % (filename, right))
        if librpm.rpmfiCompare(_rpm.fiFromFi(left_fi),
                               _rpm.fiFromFi(right_fi)) == 0:
            logger.debug(
                'Conflict on %s between %s and %s permitted because files match',
                filename, left, right)
            return True
        if left_fi.FColor() != right_fi.FColor():
            logger.debug(
                'Conflict on %s between %s and %s permitted because colors differ',
                filename, left, right)
            return True
        return False
Esempio n. 2
0
	def execute(self, _context, _self_node, _input_node, output_parent):
		NSMAP = {
			None: SWID_XMLNS,
			'sha256': 'http://www.w3.org/2001/04/xmlenc#sha256',
			'md5': 'http://www.w3.org/2001/04/xmldsig-more#md5',
			'n8060': 'http://csrc.nist.gov/ns/swid/2015-extensions/1.0',
			'payload-generated-42': XMLNS,
		}

		output = []
		last_dir = None
		for f in fi(self.rpm_header):
			append_to = None

			name = f[0]
			location = None
			m = re.search(r'^(.*/)(.+)$', name)
			if m is not None:
				location = m.group(1)
				name = m.group(2)

				while location is not None and last_dir is not None:
					last_dir_path = last_dir.get('fullname') + '/'
					if location.startswith(last_dir_path):
						location = location[len(last_dir_path):]
						append_to = last_dir
						break
					last_dir = last_dir.getparent()

			if S_ISDIR(f[2]):
				e = etree.Element("Directory", nsmap=NSMAP)
				last_dir = e
			else:
				e = etree.Element("File", size=str(f[1]), nsmap=NSMAP)

			e.set("fullname", f[0])
			e.set("name", name)
			if location:
				location = re.sub(r'^(.+)/$', r'\g<1>', location)
				e.set("location", location)
			if f[12]:
				if len(f[12]) == 64 and f[12] != "0" * 64:
					e.set("{%s}hash" % NSMAP['sha256'], f[12])
				if len(f[12]) == 32 and f[12] != "0" * 32:
					e.set("{%s}hash" % NSMAP['md5'], f[12])
			if not S_ISDIR(f[2]):
				if (f[4] & (RPMFILE_CONFIG | RPMFILE_GHOST)) \
					or (f[9] & RPMVERIFY_FILEDIGEST) == 0 \
					or (f[9] & RPMVERIFY_FILESIZE) == 0:
					e.set("{%s}mutable" % NSMAP['n8060'], "true")
				if not (f[4] & (RPMFILE_DOC | RPMFILE_MISSINGOK | RPMFILE_GHOST | RPMFILE_LICENSE | RPMFILE_README)):
					e.set("key", "true")

			if append_to is None:
				append_to = output
			append_to.append(e)
		self._cleanup_fullname(output)
		for e in output:
			output_parent.append(e)
Esempio n. 3
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
Esempio n. 5
0
		def package_files(self, pkg_name):
			"""
			Returns list of files provided by package
			See also: http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch04s02s03.html
			"""
			if self._is_installed(pkg_name):
				ts = rpm.TransactionSet()
				mi = ts.dbMatch("name", pkg_name)
				fi = rpm.fi(next(mi))
				return [f[0] for f in fi]

			# Tracer will not find uninstalled applications
			return []
Esempio n. 6
0
		def package_files(self, pkg_name):
			"""
			Returns list of files provided by package
			See also: http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch04s02s03.html
			"""
			if self._is_installed(pkg_name):
				ts = rpm.TransactionSet()
				mi = ts.dbMatch("name", pkg_name)
				fi = rpm.fi(next(mi))
				return [f[0] for f in fi]

			# Tracer will not find uninstalled applications
			return []
Esempio n. 7
0
    def _file_conflict_is_permitted_rpm411(self, left, right, filename):
        # In rpm 4.12+ the rpmfilesCompare() function is exposed nicely as the 
        # rpm.files.matches Python method. In earlier rpm versions there is 
        # nothing equivalent in the Python bindings, although we can use ctypes 
        # to poke around and call the older rpmfiCompare() C API directly...
        librpm = ctypes.CDLL('librpm.so.3')
        _rpm = ctypes.CDLL(os.path.join(os.path.dirname(rpm.__file__), '_rpm.so'))
        class rpmfi_s(ctypes.Structure): pass
        librpm.rpmfiCompare.argtypes = [ctypes.POINTER(rpmfi_s), ctypes.POINTER(rpmfi_s)]
        librpm.rpmfiCompare.restype = ctypes.c_int
        _rpm.fiFromFi.argtypes = [ctypes.py_object]
        _rpm.fiFromFi.restype = ctypes.POINTER(rpmfi_s)

        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_fi = rpm.fi(left_hdr)
        try:
            while left_fi.FN() != filename:
                left_fi.next()
        except StopIteration:
            raise KeyError('Entry %s not found in %s' % (filename, left))
        right_fi = rpm.fi(right_hdr)
        try:
            while right_fi.FN() != filename:
                right_fi.next()
        except StopIteration:
            raise KeyError('Entry %s not found in %s' % (filename, right))
        if librpm.rpmfiCompare(_rpm.fiFromFi(left_fi), _rpm.fiFromFi(right_fi)) == 0:
            logger.debug('Conflict on %s between %s and %s permitted because files match',
                    filename, left, right)
            return True
        if left_fi.FColor() != right_fi.FColor():
            logger.debug('Conflict on %s between %s and %s permitted because colors differ',
                    filename, left, right)
            return True
        return False
Esempio n. 8
0
    def get_list_of_config(package):
        """Get all files marked as config in package

        :param package: RPM Header of package
        :type package: rpm.hdr
        :return: Strings list of files marked as config in package
        :rtype: list

        """
        files = rpm.fi(package) # pylint: disable=no-member
        result = []
        for rpm_file in files:
            if rpm_file[4] & rpm.RPMFILE_CONFIG: # pylint: disable=no-member
                result.append(rpm_file[0])
        return result
Esempio n. 9
0
    def get_list_of_config(package):
        """Get all files marked as config in package

        :param package: RPM Header of package
        :type package: rpm.hdr
        :return: Strings list of files marked as config in package
        :rtype: list

        """
        files = rpm.fi(package)  # pylint: disable=no-member
        result = []
        for rpm_file in files:
            if rpm_file[4] & rpm.RPMFILE_CONFIG:  # pylint: disable=no-member
                result.append(rpm_file[0])
        return result
Esempio n. 10
0
    def get_list_of_config(self, package):
        """Get all files marked as config in package

        :param package: RPM Header of package
        :type package: rpm.hdr
        :return: Strings list of files marked as config in package
        :rtype: list

        """
        files = rpm.fi(package)  # pylint: disable=no-member
        result = []
        for rpm_file in files:
            if rpm_file[4] & rpm.RPMFILE_CONFIG:  # pylint: disable=no-member
                file_name = rpm_file[0]
                if self.root:
                    file_name = os.path.normpath(self.root + file_name)
                result.append(file_name)
        return result