Exemplo n.º 1
0
def update_spec(spec_file, commit_hash, archive_name, packager, email, reader):
    ''' Update the release tag and changelog of the specified spec file
    to work with the specified commit_hash.
    '''
    LOG.debug('Update spec file: %s', spec_file)
    release = '%s%s%s' % (date.today().strftime('%Y%m%d'), reader.short,
                          commit_hash)
    output = []
    version = None
    rpm.spec(spec_file)
    with open(spec_file) as stream:
        for row in stream:
            row = row.rstrip()
            if row.startswith('Version:'):
                version = row.split('Version:')[1].strip()
            if row.startswith('Release:'):
                if commit_hash in row:
                    raise DgrocException('Spec already up to date')
                LOG.debug('Release line before: %s', row)
                rel_num = row.split('ase:')[1].strip().split('%{?dist')[0]
                rel_list = rel_num.split('.')
                if reader.short in rel_list[-1]:
                    rel_list = rel_list[:-1]
                if rel_list[-1].isdigit():
                    rel_list[-1] = str(int(rel_list[-1]) + 1)
                rel_num = '.'.join(rel_list)
                LOG.debug('Release number: %s', rel_num)
                row = 'Release:        %s.%s%%{?dist}' % (rel_num, release)
                LOG.debug('Release line after: %s', row)
            if row.startswith('Source0:'):
                row = 'Source0:        %s' % (archive_name)
                LOG.debug('Source0 line after: %s', row)
            if row.startswith('%changelog'):
                output.append(row)
                output.append(
                    rpm.expandMacro(
                        '* %s %s <%s> - %s-%s.%s' %
                        (date.today().strftime('%a %b %d %Y'), packager, email,
                         version, rel_num, release)))
                output.append('- Update to %s: %s' %
                              (reader.short, commit_hash))
                row = ''
            output.append(row)

    with open(spec_file, 'w') as stream:
        for row in output:
            stream.write(row + '\n')

    LOG.info('Spec file updated: %s', spec_file)
Exemplo n.º 2
0
    def main(self):
        """ The main function."""
        parser = setup_parser()
        args = parser.parse_args()
        if not args.test:
            bzurl = 'https://bugzilla.redhat.com'
        else:
            bzurl = 'https://partner-bugzilla.redhat.com'

        self.bzclient = RHBugzilla3(url="%s/xmlrpc.cgi" % bzurl)
        self.srpmfile = os.path.expanduser(args.srpmfile)
        self.specfile = os.path.expanduser(args.specfile)
        self.spec = rpm.spec(self.specfile)
        if not args.no_build:
            (output_build,
             returncode) = self.do_scratch_build(target=args.koji_target)
            if returncode != 0:
                raise FedoraCreateReviewError(
                    'Something happened while trying to build this package on koji: \n %s'
                    % output_build)
        self.info['summary'] = self.retrieve_summary()
        self.info['description'] = self.retrieve_description()
        self.info['name'] = self.retrieve_name()
        self.find_existing_reviews()
        (output_upload, returncode) = self.upload_files()
        if returncode != 0:
            raise FedoraCreateReviewError(
                'Something happened while uploading the files:\n %s' %
                output_upload)
        self.fill_urls()
        bug = self.create_review_request(args.rename_request)
        if not args.no_build:
            self.add_comment_build(output_build, bug)
        print 'Review created at: %s/show_bug.cgi?id=%s' % (bzurl, bug.id)
        print bug
Exemplo n.º 3
0
    def _update_data(self):
        """
        Function updates data from given SPEC file

        :return: 
        """
        # Load rpm information
        try:
            self.spc = rpm.spec(self.path)
        except ValueError:
            raise RebaseHelperError("Problem with parsing SPEC file '%s'" %
                                    self.path)
        self.sources = self._get_spec_sources_list(self.spc)
        self.prep_section = self.spc.prep
        # HEADER of SPEC file
        self.hdr = self.spc.sourceHeader
        self.rpm_sections = self._split_sections()
        # determine the extra_version
        logger.debug("Updating the extra version")
        _, self.extra_version, separator = SpecFile.extract_version_from_archive_name(
            self.get_archive(), self._get_raw_source_string(0))
        self.set_extra_version_separator(separator)

        self.patches = self._get_initial_patches_list()
        self.macros = MacroHelper.dump()

        # TODO: don't call this at all in SPEC file methods
        if self.download:
            self.download_remote_sources()
    def main(self):
        """ The main function."""
        parser = setup_parser()
        args = parser.parse_args()
        if not args.test:
            bzurl = 'https://bugzilla.redhat.com'
        else:
            bzurl = 'https://partner-bugzilla.redhat.com'

        self.bzclient = RHBugzilla3(url="%s/xmlrpc.cgi" % bzurl)
        self.srpmfile = os.path.expanduser(args.srpmfile)
        self.specfile = os.path.expanduser(args.specfile)
        self.spec = rpm.spec(self.specfile)
        if not args.no_build:
            (output_build, returncode) = self.do_scratch_build(
                target=args.koji_target)
            if returncode != 0:
                raise FedoraCreateReviewError(
                    'Something happened while trying to build this package on koji: \n %s' % output_build)
        self.info['summary'] = self.retrieve_summary()
        self.info['description'] = self.retrieve_description()
        self.info['name'] = self.retrieve_name()
        self.find_existing_reviews()
        (output_upload, returncode) = self.upload_files()
        if returncode != 0:
            raise FedoraCreateReviewError(
                    'Something happened while uploading the files:\n %s' % output_upload)
        self.fill_urls()
        bug = self.create_review_request(args.rename_request)
        if not args.no_build:
            self.add_comment_build(output_build, bug)
        print 'Review created at: %s/show_bug.cgi?id=%s' % (bzurl,
                                                            bug.id)
        print bug
Exemplo n.º 5
0
def get_source0_url_from_rpmspec(rpmspec):
    """
    Parse given rpm spec and return (source0's url, source0).

    It may throw ValuError("can't parse specfile"), etc.

    :param rpmspec: Path to the RPM SPEC file
    :return: (URL_of_source0, source0_basename)
    """
    spec = rpm.spec(rpmspec)

    # looks rpmSourceFlags_e in <rpm/rpmspec.h>:
    is_source = lambda t: t[-1] == 1 << 0

    src0 = [s for s in spec.sources if is_source(s)][0][0]
    assert src0, "SOURCE0 should not be empty!"

    # 1. Try SOURCE0:
    if re.match(r"^(ftp|http|https)://", src0):
        logging.debug("URL=" + src0)
        url_src0 = (src0, os.path.basename(src0))
    else:
        # 2. Try URL + basename(src0):
        base_url = spec.sourceHeader["URL"]
        assert base_url, "URL should not be empty!"
        url_src0 = (os.path.join(base_url, src0), src0)

    logging.debug("URL=%s, src0=%s" % url_src0)
    return url_src0
Exemplo n.º 6
0
    def _update_data(self):
        """
        Function updates data from given SPEC file

        :return: 
        """
        # Load rpm information
        try:
            self.spc = rpm.spec(self.path)
        except ValueError:
            raise RebaseHelperError("Problem with parsing SPEC file '%s'" % self.path)
        self.prep_section = self.spc.prep
        # HEADER of SPEC file
        self.hdr = self.spc.sourceHeader

        # All source file mentioned in SPEC file Source[0-9]*
        self.rpm_sections = self._split_sections()
        # determine the extra_version
        logger.debug("Updating the extra version")
        self.sources, self.tar_sources = self._get_initial_sources_list()

        _, self.extra_version, separator = SpecFile.extract_version_from_archive_name(
            self.get_archive(),
            self._get_raw_source_string(0))
        self.set_extra_version_separator(separator)

        self.patches = self._get_initial_patches_list()
        self.macros = MacroHelper.dump()
Exemplo n.º 7
0
 def _copy_startup_scripts(self, spec_filename):
     common_init_content = utils.load_template("packaging",
                                               "common.init")[1]
     for src in rpm.spec(spec_filename).sources:
         script = sh.basename(src[0])
         if not (script.endswith(".init")):
             continue
         target_filename = sh.joinpths(self.rpm_sources_dir, script)
         if sh.isfile(target_filename):
             continue
         bin_name = utils.strip_prefix_suffix(script, "openstack-", ".init")
         if bin_name == "quantum-server":
             daemon_args = ("'--config-file=/etc/quantum/plugin.ini"
                            " --config-file=/etc/quantum/quantum.conf'")
         elif bin_name == "quantum-l3-agent":
             daemon_args = ("'--config-file=/etc/quantum/l3_agent.ini"
                            " --config-file=/etc/quantum/quantum.conf'")
         elif bin_name == "quantum-dhcp-agent":
             daemon_args = ("'--config-file=/etc/quantum/dhcp_agent.ini"
                            " --config-file=/etc/quantum/quantum.conf'")
         else:
             daemon_args = ""
         params = {
             "bin": bin_name,
             "package": bin_name.split("-", 1)[0],
             "daemon_args": daemon_args,
         }
         sh.write_file(target_filename,
                       utils.expand_template(common_init_content, params))
Exemplo n.º 8
0
def parse_spec(spec_file):
    """Simple wrapper around rpm.spec that catches errors printed to stdout
    :param spec_file: spec file name
    :returns: rpm.spec object instance
    :raises: ValueError in case parsing failed
    """

    with NamedTemporaryFile(mode="w+") as tmplog:
        # rpm will print errors to stdout if logfile is not set
        rpm.setLogFile(tmplog)

        try:
            rpm.spec(spec_file)
        except ValueError as exc:
            # re-raise errors with rpm output appended to message
            raise ValueError(str(exc) + open(tmplog.name, 'r').read())
Exemplo n.º 9
0
def get_source0_url_from_rpmspec(rpmspec):
    """
    Parse given rpm spec and return (source0's url, source0).

    It may throw ValuError("can't parse specfile"), etc.

    :param rpmspec: Path to the RPM SPEC file
    :return: (URL_of_source0, source0_basename)
    """
    spec = rpm.spec(rpmspec)

    # looks rpmSourceFlags_e in <rpm/rpmspec.h>:
    is_source = lambda t: t[-1] == 1 << 0

    src0 = [s for s in spec.sources if is_source(s)][0][0]
    assert src0, "SOURCE0 should not be empty!"

    # 1. Try SOURCE0:
    if re.match(r"^(ftp|http|https)://", src0):
        logging.debug("URL=" + src0)
        url_src0 = (src0, os.path.basename(src0))
    else:
        # 2. Try URL + basename(src0):
        base_url = spec.sourceHeader["URL"]
        assert base_url, "URL should not be empty!"
        url_src0 = (os.path.join(base_url, src0), src0)

    logging.debug("URL=%s, src0=%s" % url_src0)
    return url_src0
Exemplo n.º 10
0
    def build_rpm(self):
        package_name = "".join(
            random.choice(string.ascii_lowercase) for _ in range(12))

        # Fill template
        spec_data = self.DEFAULT_SPEC_DATA
        spec_data["name"] = package_name
        spec_data["files"] = f"/{package_name}.bin"

        # Create spec
        rendered = self.template.render(**spec_data)
        tmp_spec_path = os.path.join(self.tmp_dir, "SPECS",
                                     f"{package_name}.spec")
        with open(tmp_spec_path, "w") as tmp_spec:
            tmp_spec.write(rendered)

        # Create build dirs
        build_root = rpm.expandMacro("%{buildroot}")
        if not os.path.exists(build_root):
            os.makedirs(build_root)

        # Writing binary file
        tmp_bin_path = os.path.join(build_root, f"{package_name}.bin")
        with open(tmp_bin_path, "wb") as tmp_bin:
            tmp_bin.write(os.urandom(1024 * 1024))  # size in bytes

        # Generating rpm
        build_amount = rpm.RPMBUILD_PACKAGEBINARY | rpm.RPMBUILD_RMBUILD | rpm.RPMBUILD_CLEAN
        sp = rpm.spec(specfile=tmp_spec_path)
        sp._doBuild(ts=self.ts, buildAmount=build_amount)
Exemplo n.º 11
0
def prepare_spec(spec, version, release, prefix, patches):
    """Modify spec according our needs.
    :param str spec: Path to RPM spec
    :param str version: Version
    :param str release: Release
    :param str prefix: Archive prefix
    :param rgo.git.PatchesAction patches: What to do with patches
    :return: Patches RPM spec
    :rtype: str
    """
    import rpm
    rpmspec = rpm.spec(spec)

    # TODO: currently we don't support multiple sources
    if len([x
            for _, _, x in rpmspec.sources if x == rpm.RPMBUILD_ISSOURCE]) > 1:
        raise NotImplementedError

    with open(spec, "r") as specfile:
        _spec = specfile.readlines()

    out = []
    patch_tag_re = re.compile(r"^Patch\d+:")
    source_tag_re = re.compile(r"^Source(\d*):")
    patch_apply_re = re.compile(r"^%patch\d+")
    for line in _spec:
        line = line.rstrip()
        if line.startswith("Version:"):
            line = "Version: {!s}".format(version)
        elif line.startswith("Release:"):
            line = "Release: {!s}%{{?dist}}".format(release)
        elif line.startswith("Patch"):
            match = patch_tag_re.match(line)
            if match and patches == PatchesAction.drop:
                continue
        elif line.startswith("Source"):
            match = source_tag_re.match(line)
            if match:
                archive = "{!s}.tar.xz".format(prefix)
                if not match.group(1):
                    line = "Source: {!s}".format(archive)
                else:
                    line = "Source{:d}: {!s}".format(int(match.group(1)),
                                                     archive)
        elif line.startswith(("%setup", "%autosetup")):
            line = "{!s} -n {!s}".format(line, prefix)
        elif line.startswith("%patch"):
            match = patch_apply_re.match(line)
            if match and patches == PatchesAction.drop:
                continue
        elif line.startswith("%autopatch"):
            if patches == PatchesAction.drop:
                continue
        elif line == "%changelog":
            # Wipe out changelog
            break
        out.append(line)

    return "\n".join(out)
Exemplo n.º 12
0
Arquivo: dgroc.py Projeto: tblah/dgroc
def update_spec(spec_file, commit_hash, archive_name, packager, email, reader):
    ''' Update the release tag and changelog of the specified spec file
    to work with the specified commit_hash.
    '''
    LOG.debug('Update spec file: %s', spec_file)
    release = '%s%s%s' % (date.today().strftime('%Y%m%d'), reader.short, commit_hash)
    output = []
    version = None
    rpm.spec(spec_file)
    with open(spec_file) as stream:
        for row in stream:
            row = row.rstrip()
            if row.startswith('Version:'):
                version = row.split('Version:')[1].strip()
            if row.startswith('Release:'):
                if commit_hash in row:
                    raise DgrocException('Spec already up to date')
                LOG.debug('Release line before: %s', row)
                rel_num = row.split('ase:')[1].strip().split('%{?dist')[0]
                rel_list = rel_num.split('.')
                if reader.short in rel_list[-1]:
                    rel_list = rel_list[:-1]
                if rel_list[-1].isdigit():
                    rel_list[-1] = str(int(rel_list[-1])+1)
                rel_num = '.'.join(rel_list)
                LOG.debug('Release number: %s', rel_num)
                row = 'Release:        %s.%s%%{?dist}' % (rel_num, release)
                LOG.debug('Release line after: %s', row)
            if row.startswith('Source0:'):
                row = 'Source0:        %s' % (archive_name)
                LOG.debug('Source0 line after: %s', row)
            if row.startswith('%changelog'):
                output.append(row)
                output.append(rpm.expandMacro('* %s %s <%s> - %s-%s.%s' % (
                    date.today().strftime('%a %b %d %Y'), packager, email,
                    version, rel_num, release)
                ))
                output.append('- Update to %s: %s' % (reader.short, commit_hash))
                row = ''
            output.append(row)

    with open(spec_file, 'w') as stream:
        for row in output:
            stream.write(row + '\n')

    LOG.info('Spec file updated: %s', spec_file)
Exemplo n.º 13
0
 def parse_spec(cls, path, flags=None):
     with open(path, 'rb') as orig:
         with tempfile.NamedTemporaryFile() as tmp:
             # remove BuildArch to workaround rpm bug
             tmp.write(b''.join(l for l in orig.readlines() if not l.startswith(b'BuildArch')))
             tmp.flush()
             capturer = None
             try:
                 with ConsoleHelper.Capturer(stderr=True) as capturer:
                     result = rpm.spec(tmp.name, flags) if flags is not None else rpm.spec(tmp.name)
             except ValueError as e:
                 output = capturer.stderr.strip().split('\n') if capturer else []
                 if len(output) == 1:
                     output = output[0]
                 raise RebaseHelperError('Failed to parse SPEC file{0}'.format(
                     ': ' + str(output) if output else '')) from e
             return result
Exemplo n.º 14
0
 def rpmspec(self):
     if not self._rpmspec:
         rpm.addMacro('_sourcedir',
                      os.path.dirname(os.path.realpath(self.fn)))
         try:
             self._rpmspec = rpm.spec(self.fn)
         except ValueError, e:
             raise Exception("Error parsing spec: {0}".format(e))
Exemplo n.º 15
0
 def parse_spec(cls, path, flags=None):
     with open(path, 'rb') as orig:
         with tempfile.NamedTemporaryFile() as tmp:
             # remove BuildArch to workaround rpm bug
             tmp.write(b''.join([
                 l for l in orig.readlines()
                 if not l.startswith(b'BuildArch')
             ]))
             tmp.flush()
             with ConsoleHelper.Capturer(stderr=True) as capturer:
                 result = rpm.spec(
                     tmp.name, flags) if flags is not None else rpm.spec(
                         tmp.name)
             for line in capturer.stderr.split('\n'):
                 if line:
                     logger.verbose('rpm: %s', line)
             return result
Exemplo n.º 16
0
 def rpmspec(self):
     if not self._rpmspec:
         rpm.addMacro('_sourcedir',
                      os.path.dirname(os.path.realpath(self.fn)))
         try:
             self._rpmspec = rpm.spec(self.fn)
         except ValueError, e:
             raise Exception("Error parsing spec: {0}".format(e))
Exemplo n.º 17
0
 def _spec_deps(self, spec_fn):
     try:
         spec = rpm.spec(spec_fn)
     except ValueError as e:
         msg = _("Failed to open: '%s', not a valid spec file.") % spec_fn
         raise dnf.exceptions.Error(msg)
     for dep in rpm.ds(spec.sourceHeader, 'requires'):
         reldep_str = self._rpm_dep2reldep_str(dep)
         self.base.install(reldep_str)
Exemplo n.º 18
0
 def load_rpmspec(self):
     if not RPM_AVAILABLE:
         raise exception.RpmModuleNotAvailable()
     rpm.addMacro('_sourcedir', os.path.dirname(os.path.realpath(self.fn)))
     try:
         self._rpmspec = rpm.spec(self.fn)
     except ValueError as e:
         raise exception.SpecFileParseError(spec_fn=self.fn,
                                            error=e.args[0])
Exemplo n.º 19
0
    def __init__(self, filename):
        #
        # Workaround for https://github.com/rpm-software-management/rpm/pull/1067
        # See also http://lists.rpm.org/pipermail/rpm-list/2020-February/002012.html
        #
        rpm.reloadConfig()

        self._spec = rpm.spec(filename)
        self._filename = filename
Exemplo n.º 20
0
def prepare_spec(spec, version, release, prefix, patches):
    """Modify spec according our needs.
    :param str spec: Path to RPM spec
    :param str version: Version
    :param str release: Release
    :param str prefix: Archive prefix
    :param rgo.git.PatchesAction patches: What to do with patches
    :return: Patches RPM spec
    :rtype: str
    """
    import rpm
    rpmspec = rpm.spec(spec)

    # TODO: currently we don't support multiple sources
    if len([x for _, _, x in rpmspec.sources if x == rpm.RPMBUILD_ISSOURCE]) > 1:
        raise NotImplementedError

    with open(spec, "r") as specfile:
        _spec = specfile.readlines()

    out = []
    patch_tag_re = re.compile(r"^Patch\d+:")
    source_tag_re = re.compile(r"^Source(\d*):")
    patch_apply_re = re.compile(r"^%patch\d+")
    for line in _spec:
        line = line.rstrip()
        if line.startswith("Version:"):
            line = "Version: {!s}".format(version)
        elif line.startswith("Release:"):
            line = "Release: {!s}%{{?dist}}".format(release)
        elif line.startswith("Patch"):
            match = patch_tag_re.match(line)
            if match and patches == PatchesAction.drop:
                continue
        elif line.startswith("Source"):
            match = source_tag_re.match(line)
            if match:
                archive = "{!s}.tar.xz".format(prefix)
                if not match.group(1):
                    line = "Source: {!s}".format(archive)
                else:
                    line = "Source{:d}: {!s}".format(int(match.group(1)), archive)
        elif line.startswith(("%setup", "%autosetup")):
            line = "{!s} -n {!s}".format(line, prefix)
        elif line.startswith("%patch"):
            match = patch_apply_re.match(line)
            if match and patches == PatchesAction.drop:
                continue
        elif line.startswith("%autopatch"):
            if patches == PatchesAction.drop:
                continue
        elif line == "%changelog":
            # Wipe out changelog
            break
        out.append(line)

    return "\n".join(out)
Exemplo n.º 21
0
 def rpmspec(self):
     if not self._rpmspec:
         if not RPM_AVAILABLE:
             raise exception.RpmModuleNotAvailable()
         rpm.addMacro("_sourcedir", os.path.dirname(os.path.realpath(self.fn)))
         try:
             self._rpmspec = rpm.spec(self.fn)
         except ValueError, e:
             raise exception.SpecFileParseError(spec_fn=self.fn, error=e.args[0])
Exemplo n.º 22
0
def get_package_info(path_to_spec):
    spec = rpm.spec(path_to_spec)
    hdr = spec.sourceHeader
    # need to process spec for requires
    # http://lists.rpm.org/pipermail/rpm-list/2011-September/000992.html
    ret = {}
    for field in ["name", "version", "release", "license", "summary", "url", "changelogtext"]:
        ret[field] = hdr[field]

    return ret
Exemplo n.º 23
0
    def installSpecDeps(self, spec_file):
        try:
            spec=rpm.spec(spec_file).sourceHeader.dsFromHeader()
            self.uid_manager.becomeUser(0, 0)
            for i in range(len(spec)):
                requirement_name = spec[i][2:]
                self.buildroot.pkg_manager.install(requirement_name, check=True)

        finally:
            self.uid_manager.restorePrivs()
Exemplo n.º 24
0
 def __init__(self, path, sources_location='', download=True):
     self.path = path
     self.download = download
     self.sources_location = sources_location
     #  Read the content of the whole SPEC file
     self._read_spec_content()
     # Load rpm information
     self.spc = rpm.spec(self.path)
     self.patches = self._get_initial_patches_list()
     self._update_data()
Exemplo n.º 25
0
def get_version_from_spec(spec_file):
    """
    Return the version from the spec
    :param spec_file: The path to a spec file
    :type spec_file: str
    :return: Version field
    :rtype: str
    """
    # Get the dep name & version
    spec = rpm.spec(spec_file)
    return spec.sourceHeader[rpm.RPMTAG_VERSION]
Exemplo n.º 26
0
    def _update_data(self):

        """
        Function updates data from given SPEC file
        :return:
        """
        # Load rpm information
        self.spc = rpm.spec(self.path)
        self.prep_section = rpm.spec(self.path).prep
        # HEADER of SPEC file
        self.hdr = self.spc.sourceHeader

        # All source file mentioned in SPEC file Source[0-9]*
        self.rpm_sections = self._split_sections()
        # determine the extra_version
        logger.debug("Updating the extra version")
        self.sources, self.tar_sources = self._get_initial_sources_list()
        self.extra_version = SpecFile.extract_version_from_archive_name(self.get_archive(),
                                                                        self._get_raw_source_string(0))[1]
        self.patches = self._get_initial_patches_list()
Exemplo n.º 27
0
def get_version_from_spec(spec_file):
    """
    Return the version from the spec
    :param spec_file: The path to a spec file
    :type spec_file: str
    :return: Version field
    :rtype: str
    """
    # Get the dep name & version
    spec = rpm.spec(spec_file)
    return spec.sourceHeader[rpm.RPMTAG_VERSION]
Exemplo n.º 28
0
    def installSpecDeps(self, spec_file):
        try:
            # pylint: disable=no-member
            spec = rpm.spec(spec_file).sourceHeader.dsFromHeader()
            self.uid_manager.becomeUser(0, 0)
            for i in range(len(spec)): # pylint: disable=consider-using-enumerate
                requirement_name = spec[i][2:]
                self.buildroot.pkg_manager.install(requirement_name, check=True)

        finally:
            self.uid_manager.restorePrivs()
Exemplo n.º 29
0
 def __init__(self, path, sources_location='', download=True):
     self.path = path
     self.download = download
     self.sources_location = sources_location
     #  Read the content of the whole SPEC file
     rpm.addMacro("_sourcedir", self.sources_location)
     self._read_spec_content()
     # Load rpm information
     self.spc = rpm.spec(self.path)
     self.patches = self._get_initial_patches_list()
     self.set_extra_version_separator('')
     self._update_data()
Exemplo n.º 30
0
 def _spec_deps(self, spec_fn):
     try:
         spec = rpm.spec(spec_fn)
     except ValueError:
         msg = _("Failed to open: '%s', not a valid spec file.") % spec_fn
         raise dnf.exceptions.Error(msg)
     for dep in rpm.ds(spec.sourceHeader, 'requires'):
         reldep_str = self._rpm_dep2reldep_str(dep)
         try:
             self.base.install(reldep_str)
         except dnf.exceptions.MarkingError:
             msg = _("No matching package to install: '%s'") % reldep_str
             raise dnf.exceptions.Error(msg)
Exemplo n.º 31
0
    def _spec_deps(self, spec_fn):
        try:
            spec = rpm.spec(spec_fn)
        except ValueError:
            msg = _("Failed to open: '%s', not a valid spec file.") % spec_fn
            raise dnf.exceptions.Error(msg)
        done = True
        for dep in rpm.ds(spec.sourceHeader, 'requires'):
            reldep_str = self._rpm_dep2reldep_str(dep)
            done &= self._install(reldep_str)

        if not done:
            err = _("Not all dependencies satisfied")
            raise dnf.exceptions.Error(err)
Exemplo n.º 32
0
    def parse_spec(self):
        version = 0
        if not os.path.exists(self.spec_filename):
            print_fail("No spec file")
            return False

        # open spec file
        try:
            spec = rpm.spec(self.spec_filename)
            self.version = spec.sourceHeader["version"]
        except ValueError as e:
            print_fail("Can't parse spec file")
            return False
        return True
Exemplo n.º 33
0
def get_release_from_spec(spec_file):
    """
    Return the release from a spec file
    :param spec_file: The path to a spec file
    :type spec_file: str
    :return: Release field without the dist macro
    :rtype: str
    """
    # Get the dep name & version
    spec = rpm.spec(spec_file)
    release = spec.sourceHeader[rpm.RPMTAG_RELEASE]
    # split the dist from the end of the nvr
    release = release[:release.rfind('.')]
    return release
Exemplo n.º 34
0
def get_package_nvr_from_spec(spec_file):
    """
    Return a list of the NVR required for a given spec file
    :param spec_file: The path to a spec file
    :type spec_file: str
    :return: list of nevra that should be built for that spec file
    :rtype: str
    """
    # Get the dep name & version
    spec = rpm.spec(spec_file)
    package_nvr = spec.sourceHeader[rpm.RPMTAG_NVR]
    # split the dist from the end of the nvr
    package_nvr = package_nvr[:package_nvr.rfind('.')]
    return package_nvr
Exemplo n.º 35
0
def get_package_nvr_from_spec(spec_file):
    """
    Return a list of the NVR required for a given spec file
    :param spec_file: The path to a spec file
    :type spec_file: str
    :return: list of nevra that should be built for that spec file
    :rtype: str
    """
    # Get the dep name & version
    spec = rpm.spec(spec_file)
    package_nvr = spec.sourceHeader[rpm.RPMTAG_NVR]
    # split the dist from the end of the nvr
    package_nvr = package_nvr[:package_nvr.rfind('.')]
    return package_nvr
Exemplo n.º 36
0
    def _spec_deps(self, spec_fn):
        try:
            spec = rpm.spec(spec_fn)
        except ValueError:
            msg = _("Failed to open: '%s', not a valid spec file.") % spec_fn
            raise dnf.exceptions.Error(msg)
        done = True
        for dep in rpm.ds(spec.sourceHeader, 'requires'):
            reldep_str = self._rpm_dep2reldep_str(dep)
            done &= self._install(reldep_str)

        if not done:
            err = _("Not all dependencies satisfied")
            raise dnf.exceptions.Error(err)
Exemplo n.º 37
0
def get_release_from_spec(spec_file):
    """
    Return the release from a spec file
    :param spec_file: The path to a spec file
    :type spec_file: str
    :return: Release field without the dist macro
    :rtype: str
    """
    # Get the dep name & version
    spec = rpm.spec(spec_file)
    release = spec.sourceHeader[rpm.RPMTAG_RELEASE]
    # split the dist from the end of the nvr
    release = release[:release.rfind('.')]
    return release
Exemplo n.º 38
0
def get_obs_version(self, project, package="erlang", filename=None):
    if filename is None:
        filename = "{}.spec".format(package)

    with tempfile.NamedTemporaryFile() as temp_file:
        target_filename = temp_file.name

        core.get_source_file(conf.config['apiurl'], project, package, filename,
                             target_filename)
        s = rpm.spec(target_filename)
        obs_version = s.sourceHeader[rpm.RPMTAG_VERSION].decode("ascii")

        major, *_ = obs_version.split(".")

        return obs_version, major
Exemplo n.º 39
0
def getSRPMHead(spec):
    """
    Get the begining of an srpm file name based on a rpm spec

    :type spec: str
    :param spec: Spec file to parse
    """

    spec_obj = rpm.spec(spec)
    spec_headers = spec_obj.packages[0].header
    head = "{0}-{1}".format(
            spec_headers.format("%{name}"),
            spec_headers.format("%{version}")
            )
    return head
Exemplo n.º 40
0
 def _copy_startup_scripts(self, spec_filename):
     common_init_content = utils.load_template("packaging",
                                               "common.init")[1]
     for src in rpm.spec(spec_filename).sources:
         script = sh.basename(src[0])
         if not (script.endswith(".init")):
             continue
         target_filename = sh.joinpths(self.rpm_sources_dir, script)
         if sh.isfile(target_filename):
             continue
         bin_name = utils.strip_prefix_suffix(script, "openstack-", ".init")
         params = {
             "bin": bin_name,
             "package": bin_name.split("-", 1)[0],
         }
         sh.write_file(target_filename,
                       utils.expand_template(common_init_content, params))
Exemplo n.º 41
0
def get_pkg_tag(tag, path=os.path.curdir, subpkg=None):
    topdir = getpkgtopdir(path)
    speclist = glob.glob(os.path.join(topdir, "SPECS", "*.spec"))
    if not speclist:
        raise Error("no spec files found")
    specfile = speclist[0]

    pkg = rpm.spec(specfile)
    if subpkg is None:
        header = pkg.sourceHeader
    elif isinstance(subpkg, int):
        header = pkg.packages(subpkg)
    else:
        raise Error("Subpkg must be the index number of a package,"\
                "or None for source package")

    if isinstance(header[tag], bytes):
        return header[tag].decode("utf8")
    else:
        return header[tag]
Exemplo n.º 42
0
def parse_spec(spec_file, keep_config=False):
    """Simple wrapper around rpm.spec that catches errors printed to stdout
    :param spec_file: spec file name
    :param keep_config: If set to True, does not call rpm.reloadConfig()
        This can be used to preserve the internal rpm state with any custom
        macros or definitions.
    :returns: rpm.spec object instance
    :raises: ValueError in case parsing failed
    """
    if not keep_config:
        rpm.reloadConfig()

    with NamedTemporaryFile(mode="w+") as tmplog:
        # rpm will print errors to stdout if logfile is not set
        rpm.setLogFile(tmplog)

        try:
            spec = rpm.spec(spec_file)
        except ValueError as exc:
            # re-raise errors with rpm output appended to message
            raise ValueError(str(exc) + open(tmplog.name, 'r').read())
        return spec
    def _make_srpm(self, tmpdir, distgit, patches_action):
        """
        Build SRPM.
        :param str tmpdir: Dir where to create the new srpm
        :param str distgit: Distgit repository if specified used for Specfile and pathes
        :param PatchesAction patches_action: What to do with patches
        :return: Path to the built srpm
        :rtype: str
        """
        workdir = os.path.join(tmpdir, self.name)
        os.mkdir(workdir)

        spec_name = distgit.spec_path or "{!s}.spec".format(self.name)

        # extract spec file from specified branch and save it in temporary location
        original_spec_path = os.path.join(workdir, "original.spec")
        with open(original_spec_path, "w") as f_spec:
            subprocess.run(["git", "cat-file", "-p", "{}:{}".format(distgit.ref, spec_name)],
                           cwd=distgit.cwd, check=True, stdout=f_spec)

        original_rpmspec = rpm.spec(original_spec_path)

        spec_name = original_rpmspec.sourceHeader["Name"]
        if isinstance(spec_name, bytes):
            spec_name = spec_name.decode("utf-8")

        spec_version = original_rpmspec.sourceHeader["Version"]
        if isinstance(spec_version, bytes):
            spec_version = spec_version.decode("utf-8")

        final_spec_path = os.path.join(workdir, "{!s}.spec".format(spec_name))

        # PREPARE SPECFILE AND ARCHIVE
        if self.git:
            version, release = self.git.describe(self.name, spec_version=spec_version, version_from=self.version_from)

            # Prepare nvr
            nvr = "{!s}-{!s}-{!s}".format(self.name, version, release)

            # Prepare archive from git (compressed tarball)
            archive = os.path.join(workdir, "{!s}.tar.xz".format(nvr))
            LOGGER.debug("Preparing archive %r", archive)
            proc = subprocess.run(["git", "archive", "--prefix={!s}/".format(nvr),
                                   "--format=tar", self.git.ref],
                                  cwd=self.git.cwd, check=True,
                                  stdout=subprocess.PIPE)
            with open(archive, "w") as f_archive:
                subprocess.run(["xz", "-z", "--threads=0", "-"],
                               check=True, input=proc.stdout, stdout=f_archive)

            # Prepare new spec
            with open(final_spec_path, "w") as specfile:
                prepared = "{!s}\n{!s}".format(
                    utils.prepare_spec(original_spec_path, version, release, nvr, patches_action),
                    utils.generate_changelog(self.git.timestamp, version, release, self.git.get_rpm_changelog()))
                specfile.write(prepared)
        else:
            # If no git specified use distgit for both specfile and source code.
            # We could simply copy specifile like this:
            # shutil.copy2(original_spec_path, final_spec_path)
            # but getting the source code (tarball) is not so simple.
            raise NotImplementedError("Getting a tarball from distgit is not implemented")

        # PREPARE SPECFILE PATCHES
        if patches_action == PatchesAction.keep:
            _sources = []
            for src, _, src_type in rpm.spec(final_spec_path).sources:
                if src_type == rpm.RPMBUILD_ISPATCH:
                    _sources.append(src)

            if _sources and not distgit:
                raise NotImplementedError("Patches are applied in upstream")
            else:
                # Copy sources/patches from distgit
                for source in _sources:
                    shutil.copy2(os.path.join(distgit.cwd, distgit.patches_dir, source),
                                 os.path.join(workdir, source))

        # RPMBUILD SRPM
        try:
            result = subprocess.run(["rpmbuild", "-bs", final_spec_path, "--nodeps",
                                     "--define", "_topdir {!s}".format(workdir),
                                     "--define", "_sourcedir {!s}".format(workdir)],
                                    check=True, universal_newlines=True,
                                    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as err:
            LOGGER.critical("Failed to build (no)source RPM:\n%s", err.output)
            raise
        else:
            LOGGER.debug(result.stdout)

        srpms_dir = os.path.join(workdir, "SRPMS")
        srpms = [f for f in os.listdir(srpms_dir) if SRPM_RE.search(f)]
        assert len(srpms) == 1, "We expect 1 .(no)src.rpm, but we found: {!r}".format(srpms)
        srpm_path = os.path.join(srpms_dir, srpms[0])

        # CLEAN UP WORKDIR
        name_prefix = ""
        if hasattr(distgit, 'chroots'):
            name_prefix = "-".join(distgit.chroots) + "-"

        final_moved_out_srpm = os.path.join(tmpdir, name_prefix + srpms[0])
        shutil.move(srpm_path, final_moved_out_srpm)
        LOGGER.info("Built (no)source RPM: %r from %r", final_moved_out_srpm, distgit.ref_info())
        shutil.rmtree(workdir)

        return final_moved_out_srpm
Exemplo n.º 44
0
import sys
import rpm
import optparse
import subprocess

parser = optparse.OptionParser()
parser.add_option('-d',
                  '--directory',
                  help='Target directory',
                  default='/tmp/sources')

options, args = parser.parse_args()

if not os.path.isdir(options.directory):
    os.makedirs(options.directory)

for specfile in args:
    try:
        spec = rpm.spec(specfile)
    except ValueError as e:
        print(str(e))
    sources = spec.sources
    for source in sources:
        filename_or_url = source[0]
        if '://' not in filename_or_url:
            continue
        command = ('wget', '-q', '-P', options.directory, '-c',
                   filename_or_url)
        print(' '.join(command))
        subprocess.call(command)
Exemplo n.º 45
0
def parse_spec(specFile, cacheFile='.repocache.json'):
    '''Parse the Spec file contents.

    Args:
        specFile: A string of spec file path.

    Returns:
        Return the list contains the Spec file name and content. If the file
        is not found, it returns false.
    '''

    if os.path.exists(cacheFile):
        if 'repocache' not in globals().keys():
            echo('green', 'info:',
                 ' Load cache from {} file.'.format(cacheFile))
            with open(cacheFile, 'r') as f:
                global repocache
                repocache = json.loads(f.read())
        return specFile, repocache[specFile]

    items = lambda t, c: re.findall('%s:\s+(.*)' % t, c)
    split_str = lambda l: [re.split('[\s,=|>=|<=]+', i) for i in l]
    flat = lambda L: sum(map(flat, L), []) if isinstance(L, list) else [L]
    remove_ver = lambda l: [i for i in l if not re.match('^[0-9]', i)]
    decode = lambda v: v.decode() if v else v

    if os.path.exists(specFile) and specFile.endswith('.spec'):
        rpm_info = {}
        subpkgs, reqpkgs = [], []
        spec = rpm.spec(specFile)
        hdr = spec.sourceHeader

        reqlist = [decode(i) for i in hdr[rpm.RPMTAG_REQUIRES]]
        content = getoutput('/bin/rpmspec -P {}'.format(specFile))
        content = content[:content.index('%changelog')]

        # subpackages
        name = decode(hdr[rpm.RPMTAG_NAME])
        subpkgs.append(name)
        if re.search('%package', content):
            for i in re.findall('%package\s*(.+)', content):
                if i.startswith('-n'):
                    subpkgs.append(re.match('-n\s*(.*)', i).group(1))
                else:
                    subpkgs.append('{}-{}'.format(name, i))

        provpkgs = remove_ver(flat(split_str(items('Provides',
                                                   content)))) + subpkgs

        # parse buildrequires
        for i in reqlist:
            if re.match('.*\((.*)\)', i):
                reqpkgs.append(query_package(i)[0].name)
            else:
                reqpkgs.append(i)

        rpm_info = {
            "name": decode(hdr[rpm.RPMTAG_NAME]),
            "epoch": hdr[rpm.RPMTAG_EPOCHNUM],
            "version": decode(hdr[rpm.RPMTAG_VERSION]),
            "release": decode(hdr[rpm.RPMTAG_RELEASE]),
            "vendor": decode(hdr[rpm.RPMTAG_VENDOR]),
            "summary": decode(hdr[rpm.RPMTAG_SUMMARY]),
            "packager": decode(hdr[rpm.RPMTAG_PACKAGER]),
            "group": decode(hdr[rpm.RPMTAG_GROUP]),
            "license": decode(hdr[rpm.RPMTAG_LICENSE]),
            "url": decode(hdr[rpm.RPMTAG_URL]),
            "description": decode(hdr[rpm.RPMTAG_DESCRIPTION]),
            "sources": spec.sources,
            "patchs": [decode(i) for i in hdr[rpm.RPMTAG_PATCH]],
            "build_archs": [decode(i) for i in hdr[rpm.RPMTAG_BUILDARCHS]],
            "exclusive_archs":
            [decode(i) for i in hdr[rpm.RPMTAG_EXCLUSIVEARCH]],
            #"build_requires": [i.DNEVR()[2:] for i in rpm.ds(hdr, 'requires')],
            "build_requires": sorted(list(set(reqpkgs))),
            "requires":
            remove_ver(flat(split_str(items('\nRequires', content)))),
            "recommends":
            remove_ver(flat(split_str(items('Recommends', content)))),
            "supplements": [decode(i) for i in hdr[rpm.RPMTAG_SUPPLEMENTS]],
            "suggests": [decode(i) for i in hdr[rpm.RPMTAG_SUGGESTS]],
            "enhances": [decode(i) for i in hdr[rpm.RPMTAG_ENHANCES]],
            "provides": sorted(list(set(provpkgs))),
            "obsoletes":
            remove_ver(flat(split_str(items('Obsoletes', content)))),
            "conflicts":
            remove_ver(flat(split_str(items('Conflicts', content))))
        }

        return specFile, rpm_info
    return False
Exemplo n.º 46
0
def getSpecSummary(spec):
    return rpm.spec(spec).packages[0].headers.format("%{summary}")
Exemplo n.º 47
0
def scanspec2(specfile, specdir):
	spec = os.path.join(specdir, specfile)
	try:
		parsedspec = rpm.spec(spec)
	except Exception, e:
		return None
Exemplo n.º 48
0
#!/usr/bin/python

import rpm

spec = rpm.spec("rdma-core.spec")
print '%s' % (getattr(spec, "build"),)
Exemplo n.º 49
0
"""
A simple script downloading sources from specfiles
"""
import os
import sys
import rpm
import optparse
import subprocess

parser = optparse.OptionParser()
parser.add_option('-d', '--directory', help='Target directory', default='/tmp/sources')

options, args = parser.parse_args()

if not os.path.isdir(options.directory):
    os.makedirs(options.directory)

for specfile in args:
    try:
        spec = rpm.spec(specfile)
    except ValueError as e:
        print(str(e))
    sources = spec.sources
    for source in sources:
        filename_or_url = source[0]
        if '://' not in filename_or_url:
            continue
        command = ('wget', '-q', '-P', options.directory, '-c', filename_or_url) 
        print(' '.join(command))
        subprocess.call(command)
Exemplo n.º 50
0
def scanspec2(specfile, specdir):
    spec = os.path.join(specdir, specfile)
    try:
        parsedspec = rpm.spec(spec)
    except Exception, e:
        return None
Exemplo n.º 51
0
 def _get_rpmspec(self, spec_path):
     with silence(sys.stderr):
         spec = rpm.spec(spec_path)
     return spec
Exemplo n.º 52
0
    def make_srpm(self, cwd):
        """
        Build SRPM.

        :param str cwd: Working directory (for spec, sources)
        """
        assert self.cloned
        import rpm
        if self.distgit:
            spec = os.path.join(self.distgit.cwd, "{!s}.spec".format(self.name))
            patches = self.distgit.patches
        else:
            spec = os.path.join(self.git.cwd, self.git.spec_path or "{!s}.spec".format(self.name))
            patches = PatchesAction.keep

        rpmspec = rpm.spec(spec)
        _spec_path = os.path.join(cwd,
                                  "{!s}.spec".format(rpmspec.sourceHeader["Name"].decode("utf-8")))
        if self.git:
            # Get version and release
            version, release = self.git.describe(self.name)

            # If spec is located in upstream it's possible that version can be changed
            # which means we also should align it here
            if not self.distgit:
                _version = rpmspec.sourceHeader["Version"].decode("utf-8")
                LOGGER.debug("Version in upstream spec file: %r", _version)
                if rpm.labelCompare((None, _version, None), (None, version, None)) == 1:
                    # Version in spec > than from git tags
                    LOGGER.debug("Setting version from upstream spec file")
                    version = _version
                    # FIXME: Add prefix 0. to indicate that it was not released yet
                    # There are no reliable way to get in which commit version was set
                    # except iterating over commits
                    release = "0.{!s}".format(release)

            # Prepare archive
            if release == "1":
                # tagged version, no need to add useless numbers
                nvr = "{!s}-{!s}".format(self.name, version)
            else:
                nvr = "{!s}-{!s}-{!s}".format(self.name, version, release)
            archive = os.path.join(cwd, "{!s}.tar.xz".format(nvr))
            LOGGER.debug("Preparing archive %r", archive)
            proc = subprocess.run(["git", "archive", "--prefix={!s}/".format(nvr),
                                   "--format=tar", self.git.ref],
                                  cwd=self.git.cwd, check=True,
                                  stdout=subprocess.PIPE)
            with open(archive, "w") as f_archive:
                subprocess.run(["xz", "-z", "--threads=0", "-"],
                               check=True, input=proc.stdout, stdout=f_archive)

            # Prepare new spec
            with open(_spec_path, "w") as specfile:
                prepared = "{!s}\n{!s}".format(
                    utils.prepare_spec(spec, version, release, nvr, patches),
                    utils.generate_changelog(self.git.timestamp, version, release))
                specfile.write(prepared)
        else:
            # Just copy spec from distgit
            shutil.copy2(spec, _spec_path)
        spec = _spec_path

        _sources = []
        for src, _, src_type in rpm.spec(spec).sources:
            if src_type == rpm.RPMBUILD_ISPATCH:
                if patches == PatchesAction.keep:
                    _sources.append(src)
            elif src_type == rpm.RPMBUILD_ISSOURCE:
                # src in fact is url, but we need filename. We don't want to get
                # Content-Disposition from HTTP headers, because link could be not
                # available anymore or broken.
                src = os.path.basename(src)
                if self.git and src == os.path.basename(archive):
                    # Skip sources which are just built
                    continue
                _sources.append(src)
        if _sources and not self.distgit:
            raise NotImplementedError("Patches/Sources are applied in upstream")
        # Copy sources/patches from distgit
        for source in _sources:
            shutil.copy2(os.path.join(self.distgit.cwd, source),
                         os.path.join(cwd, source))

        # Build .(no)src.rpm
        try:
            result = subprocess.run(["rpmbuild", "-bs", _spec_path, "--nodeps",
                                     "--define", "_topdir {!s}".format(cwd),
                                     "--define", "_sourcedir {!s}".format(cwd)],
                                    check=True, universal_newlines=True,
                                    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as err:
            LOGGER.critical("Failed to build (no)source RPM:\n%s", err.output)
            raise
        else:
            LOGGER.debug(result.stdout)
        srpms_dir = os.path.join(cwd, "SRPMS")
        srpms = [f for f in os.listdir(srpms_dir) if SRPM_RE.search(f)]
        assert len(srpms) == 1, "We expect 1 .(no)src.rpm, but we found: {!r}".format(srpms)
        srpm = os.path.join(srpms_dir, srpms[0])
        LOGGER.info("Built (no)source RPM: %r", srpm)
        return srpm
Exemplo n.º 53
0
def getSpecName(spec):
    return rpm.spec(spec).packages[0].headers.format("%{name}")
Exemplo n.º 54
0
 def parseSpec(self, specfile):
     return rpm.spec(specfile)
Exemplo n.º 55
0
def parse_spec(specFile, cacheFile='.repocache.json'):
    '''Parse the Spec file contents.

    Args:
        specFile: A string of spec file path.

    Returns:
        Return the list contains the Spec file name and content. If the file
        is not found, it returns false.
    '''

    if os.path.exists(cacheFile):
        if 'repocache' not in globals().keys():
            echo('green', 'info:', ' Load cache from {} file.'.format(cacheFile))
            with open(cacheFile, 'r') as f:
                global repocache
                repocache = json.loads(f.read())
        return specFile, repocache[specFile]

    items = lambda t, c: re.findall('%s:\s+(.*)'%t, c)
    split_str = lambda l: [re.split('[\s,=|>=|<=]+', i) for i in l]
    flat = lambda L: sum(map(flat, L), []) if isinstance(L, list) else [L]
    remove_ver = lambda l: [i for i in l if not re.match('^[0-9]', i)]
    decode = lambda v: v.decode() if v else v

    if os.path.exists(specFile) and specFile.endswith('.spec'):
        rpm_info = {}
        subpkgs, reqpkgs = [], []
        spec = rpm.spec(specFile)
        hdr = spec.sourceHeader

        reqlist = [decode(i) for i in hdr[rpm.RPMTAG_REQUIRES]]
        content = getoutput('/bin/rpmspec -P {}'.format(specFile))
        content = content[:content.index('%changelog')]

        # subpackages
        name = decode(hdr[rpm.RPMTAG_NAME])
        subpkgs.append(name)
        if re.search('%package', content):
            for i in re.findall('%package\s*(.+)', content):
                if i.startswith('-n'):
                    subpkgs.append(re.match('-n\s*(.*)', i).group(1))
                else:
                    subpkgs.append('{}-{}'.format(name, i))

        provpkgs = remove_ver(flat(split_str(items('Provides', content)))) + subpkgs

        # parse buildrequires
        for i in reqlist:
            if re.match('.*\((.*)\)', i):
                if len(query_package(i)) > 0:
                    reqpkgs.append(query_package(i)[0].name)
            else:
                reqpkgs.append(i)

        rpm_info = {
            "name": decode(hdr[rpm.RPMTAG_NAME]),
            "epoch": hdr[rpm.RPMTAG_EPOCHNUM],
            "version": decode(hdr[rpm.RPMTAG_VERSION]),
            "release": decode(hdr[rpm.RPMTAG_RELEASE]),
            "vendor": decode(hdr[rpm.RPMTAG_VENDOR]),
            "summary": decode(hdr[rpm.RPMTAG_SUMMARY]),
            "packager": decode(hdr[rpm.RPMTAG_PACKAGER]),
            "group": decode(hdr[rpm.RPMTAG_GROUP]),
            "license": decode(hdr[rpm.RPMTAG_LICENSE]),
            "url": decode(hdr[rpm.RPMTAG_URL]),
            "description": decode(hdr[rpm.RPMTAG_DESCRIPTION]),
            "sources": spec.sources,
            "patchs": [decode(i) for i in hdr[rpm.RPMTAG_PATCH]],
            "build_archs": [decode(i) for i in hdr[rpm.RPMTAG_BUILDARCHS]],
            "exclusive_archs": [decode(i) for i in hdr[rpm.RPMTAG_EXCLUSIVEARCH]],
            #"build_requires": [i.DNEVR()[2:] for i in rpm.ds(hdr, 'requires')],
            "build_requires": sorted(list(set(reqpkgs))),
            "requires": remove_ver(flat(split_str(items('\nRequires', content)))),
            "recommends": remove_ver(flat(split_str(items('Recommends', content)))),
            "supplements": [decode(i) for i in hdr[rpm.RPMTAG_SUPPLEMENTS]],
            "suggests": [decode(i) for i in hdr[rpm.RPMTAG_SUGGESTS]],
            "enhances": [decode(i) for i in hdr[rpm.RPMTAG_ENHANCES]],
            "provides": sorted(list(set(provpkgs))),
            "obsoletes": remove_ver(flat(split_str(items('Obsoletes', content)))),
            "conflicts": remove_ver(flat(split_str(items('Conflicts', content))))
        }

        return specFile, rpm_info
    return False
Exemplo n.º 56
0
    def make_srpm(self, tmpdir):
        """
        Build SRPM.

        :param str tmpdir: Temporary directory to work in
        """
        workdir = os.path.join(tmpdir, self.name)
        os.mkdir(workdir)

        assert self.cloned
        import rpm
        if self.distgit:
            spec_git = self.distgit
            spec_name = "{!s}.spec".format(self.name)
            patches = self.distgit.patches
        else:
            spec_git = self.git
            spec_name = self.git.spec_path or "{!s}.spec".format(self.name)
            patches = PatchesAction.keep

        # extract spec file from specified branch and save it in temporary location
        spec = os.path.join(workdir, "original.spec")
        with open(spec, "w") as f_spec:
            subprocess.run(["git", "cat-file", "-p", "{}:{}".format(spec_git.ref, spec_name)],
                           cwd=spec_git.cwd, check=True, stdout=f_spec)

        rpmspec = rpm.spec(spec)
        _name = rpmspec.sourceHeader["Name"]
        if isinstance(_name, bytes):
            _name = _name.decode("utf-8")
        _spec_path = os.path.join(workdir, "{!s}.spec".format(_name))
        if self.git:
            # Get version and release
            version, release = self.git.describe(self.name)

            # If spec is located in upstream it's possible that version can be changed
            # which means we also should align it here
            if not self.distgit:
                _version = rpmspec.sourceHeader["Version"]
                if isinstance(_version, bytes):
                    _version = _version.decode("utf-8")
                LOGGER.debug("Version in upstream spec file: %r", _version)
                if rpm.labelCompare((None, _version, None), (None, version, None)) == 1:
                    # Version in spec > than from git tags
                    LOGGER.debug("Setting version from upstream spec file")
                    version = _version
                    # FIXME: Add prefix 0. to indicate that it was not released yet
                    # There are no reliable way to get in which commit version was set
                    # except iterating over commits
                    release = "0.{!s}".format(release)

            # Prepare archive
            if release == "1":
                # tagged version, no need to add useless numbers
                nvr = "{!s}-{!s}".format(self.name, version)
            else:
                nvr = "{!s}-{!s}-{!s}".format(self.name, version, release)
            archive = os.path.join(workdir, "{!s}.tar.xz".format(nvr))
            LOGGER.debug("Preparing archive %r", archive)
            proc = subprocess.run(["git", "archive", "--prefix={!s}/".format(nvr),
                                   "--format=tar", self.git.ref],
                                  cwd=self.git.cwd, check=True,
                                  stdout=subprocess.PIPE)
            with open(archive, "w") as f_archive:
                subprocess.run(["xz", "-z", "--threads=0", "-"],
                               check=True, input=proc.stdout, stdout=f_archive)

            # Prepare new spec
            with open(_spec_path, "w") as specfile:
                prepared = "{!s}\n{!s}".format(
                    utils.prepare_spec(spec, version, release, nvr, patches),
                    utils.generate_changelog(self.git.timestamp, version, release))
                specfile.write(prepared)
        else:
            # Just copy spec from distgit
            shutil.copy2(spec, _spec_path)
        spec = _spec_path

        _sources = []
        for src, _, src_type in rpm.spec(spec).sources:
            if src_type == rpm.RPMBUILD_ISPATCH:
                if patches == PatchesAction.keep:
                    _sources.append(src)
            elif src_type == rpm.RPMBUILD_ISSOURCE:
                # src in fact is url, but we need filename. We don't want to get
                # Content-Disposition from HTTP headers, because link could be not
                # available anymore or broken.
                src = os.path.basename(src)
                if self.git and src == os.path.basename(archive):
                    # Skip sources which are just built
                    continue
                _sources.append(src)
        if _sources and not self.distgit:
            raise NotImplementedError("Patches/Sources are applied in upstream")
        # Copy sources/patches from distgit
        for source in _sources:
            shutil.copy2(os.path.join(self.distgit.cwd, source),
                         os.path.join(workdir, source))

        # Build .(no)src.rpm
        try:
            result = subprocess.run(["rpmbuild", "-bs", _spec_path, "--nodeps",
                                     "--define", "_topdir {!s}".format(workdir),
                                     "--define", "_sourcedir {!s}".format(workdir)],
                                    check=True, universal_newlines=True,
                                    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as err:
            LOGGER.critical("Failed to build (no)source RPM:\n%s", err.output)
            raise
        else:
            LOGGER.debug(result.stdout)
        srpms_dir = os.path.join(workdir, "SRPMS")
        srpms = [f for f in os.listdir(srpms_dir) if SRPM_RE.search(f)]
        assert len(srpms) == 1, "We expect 1 .(no)src.rpm, but we found: {!r}".format(srpms)

        self.srpm = os.path.join(tmpdir, srpms[0])
        shutil.move(os.path.join(srpms_dir, srpms[0]), self.srpm)
        shutil.rmtree(workdir)

        LOGGER.info("Built (no)source RPM: %r from %r", self.srpm, self.git.ref_info())
        return self.srpm
Exemplo n.º 57
0
                error = True
                continue
            macros.append(words)
        if error:
            sys.exit(1)

        for name in specnames:
            # (re)load rpm config for target if set
            if reloadworks and opts.target:
                rpm.reloadConfig(opts.target)

            for macro in macros:
                rpm.addMacro(*macro)

            try:
                spec = rpm.spec(name)
            except ValueError:
                self.logger.error("Bad spec: %s" % name)
                continue

            # reset default rpm config after each parse to avoid side-effects
            if reloadworks:
                rpm.reloadConfig()

            buildreqs = []
            for d in rpm.ds(spec.sourceHeader, 'requires'):
                buildreqs.append(d.DNEVR()[2:])
                
            self.logger.info('Getting requirements for %s' % name)
            self.install_deps(buildreqs, opts)
            
Exemplo n.º 58
0
def main():
    parser = parser = argparse.ArgumentParser(
        description='rediff patches to avoid fuzzy hunks')
    parser.add_argument('spec', type=str, help='spec file name')
    parser.add_argument('-p',
                        '--patches',
                        type=str,
                        help='comma separated list of patch numbers to rediff')
    parser.add_argument(
        '-s',
        '--skip-patches',
        type=str,
        help='comma separated list of patch numbers to skip rediff')
    parser.add_argument('-v',
                        '--verbose',
                        help='increase output verbosity',
                        action='store_true')
    args = parser.parse_args()

    logging.basicConfig(level=logging.INFO)
    rpm.setVerbosity(rpm.RPMLOG_ERR)

    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)
        rpm.setVerbosity(rpm.RPMLOG_DEBUG)

    if args.patches:
        args.patches = [int(x) for x in args.patches.split(',')]

    if args.skip_patches:
        args.skip_patches = [int(x) for x in args.skip_patches.split(',')]

    specfile = args.spec
    appsourcedir = os.path.dirname(os.path.abspath(specfile))

    try:
        tempdir = tempfile.TemporaryDirectory(dir="/dev/shm")
    except FileNotFoundError as e:
        tempdir = tempfile.TemporaryDirectory(dir="/tmp")
    topdir = tempdir.name
    builddir = os.path.join(topdir, 'BUILD')

    rpm.addMacro("_builddir", builddir)

    r = rpm.spec(specfile)

    patches = {}

    for (name, nr, flags) in r.sources:
        if flags & RPMBUILD_ISPATCH:
            patches[nr] = name

    applied_patches = collections.OrderedDict()
    re_patch = re.compile(r'^%patch(?P<patch_number>\d+)\w*(?P<patch_args>.*)')
    for line in r.parsed.split('\n'):
        m = re_patch.match(line)
        if not m:
            continue
        patch_nr = int(m.group('patch_number'))
        patch_args = m.group('patch_args')
        applied_patches[patch_nr] = patch_args

    appbuilddir = rpm.expandMacro("%{_builddir}/%{?buildsubdir}")

    for patch_nr in applied_patches.keys():
        if args.patches and patch_nr not in args.patches:
            continue
        if args.skip_patches and patch_nr in args.skip_patches:
            continue
        patch_name = patches[patch_nr]
        logging.info("*** patch %d: %s" % (patch_nr, patch_name))

        tempspec = prepare_spec(r, patch_nr, before=True)
        unpack(tempspec.name, appsourcedir, builddir)
        tempspec.close()
        os.rename(appbuilddir, appbuilddir + ".org")

        tempspec = prepare_spec(r, patch_nr, before=False)
        unpack(tempspec.name, appsourcedir, builddir)
        tempspec.close()

        patch_comment = patch_comment_get(patch_name)
        diff(
            appbuilddir + ".org", appbuilddir, builddir, patch_comment,
            os.path.join(topdir,
                         os.path.join(appsourcedir, patch_name + ".rediff")))

        diffstat(os.path.join(topdir, os.path.join(appsourcedir, patch_name)))
        diffstat(
            os.path.join(topdir,
                         os.path.join(appsourcedir, patch_name + ".rediff")))

        shutil.rmtree(builddir)
    tempdir.cleanup()