Skip to content

Commit

Permalink
add rpkg spec preprocessing capability
Browse files Browse the repository at this point in the history
Merges: #526
  • Loading branch information
clime authored and praiskup committed Nov 25, 2020
1 parent 0aaaf0b commit bda814a
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 5 deletions.
5 changes: 5 additions & 0 deletions mock/docs/site-defaults.cfg
Expand Up @@ -318,6 +318,11 @@
# the rpms in the results folder.
# config_opts['plugin_conf']['sign_opts']['opts'] = '--addsign %(rpms)s -D "%%_gpg_name your_name" -D "%%_gpg_path /home/your_name/.gnupg"'

# Enable preprocessing step before srpm build by using rpkg utilities
# config_opts['plugin_conf']['rpkg_preprocessor_enable'] = False
# config_opts['plugin_conf']['rpkg_preprocessor_opts']['requires'] = ['preproc-rpmspec']
# config_opts['plugin_conf']['rpkg_preprocessor_opts']['cmd'] = '/usr/bin/preproc-rpmspec %(source_spec)s --output %(target_spec)s'

#############################################################################
#
# environment for chroot
Expand Down
17 changes: 14 additions & 3 deletions mock/py/mockbuild/backend.py
Expand Up @@ -559,6 +559,7 @@ def buildsrpm(self, spec, sources, timeout, follow_links):
try:
self.uid_manager.becomeUser(self.buildroot.chrootuid, self.buildroot.chrootgid)
self.state.start("buildsrpm")
host_chroot_sources = None

# copy spec/sources
shutil.copy(spec, self.buildroot.make_chroot_path(self.buildroot.builddir, "SPECS"))
Expand All @@ -567,14 +568,24 @@ def buildsrpm(self, spec, sources, timeout, follow_links):
# Resolve any symlinks
sources = os.path.realpath(sources)
if os.path.isdir(sources):
file_util.rmtree(self.buildroot.make_chroot_path(self.buildroot.builddir, "SOURCES"))
host_chroot_sources = self.buildroot.make_chroot_path(
self.buildroot.builddir, "SOURCES")
file_util.rmtree(host_chroot_sources)

shutil.copytree(sources,
self.buildroot.make_chroot_path(self.buildroot.builddir, "SOURCES"),
host_chroot_sources,
symlinks=(not follow_links))
else:
shutil.copy(sources, self.buildroot.make_chroot_path(self.buildroot.builddir, "SOURCES"))
host_chroot_sources = self.buildroot.make_chroot_path(
self.buildroot.builddir, "SOURCES", os.path.basename(sources))
shutil.copy(sources, host_chroot_sources)

spec = self.buildroot.make_chroot_path(self.buildroot.builddir, "SPECS", os.path.basename(spec))

self.plugins.call_hooks('pre_srpm_build',
spec,
host_chroot_sources)

# get rid of rootdir prefix
chrootspec = spec.replace(self.buildroot.make_chroot_path(), '')

Expand Down
8 changes: 6 additions & 2 deletions mock/py/mockbuild/config.py
Expand Up @@ -28,7 +28,7 @@
PLUGIN_LIST = ['tmpfs', 'root_cache', 'yum_cache', 'mount', 'bind_mount',
'ccache', 'selinux', 'package_state', 'chroot_scan',
'lvm_root', 'compress_logs', 'sign', 'pm_request',
'hw_info', 'procenv', 'showrc']
'hw_info', 'procenv', 'showrc', 'rpkg_preprocessor']


def nspawn_supported():
Expand Down Expand Up @@ -191,7 +191,11 @@ def setup_default_config_opts(unprivUid, version, pkgpythondir):
'compress_logs_opts': {
'command': 'gzip',
},

'rpkg_preprocessor_enable': False,
'rpkg_preprocessor_opts': {
'requires': ['preproc-rpmspec'],
'cmd': '/usr/bin/preproc-rpmspec %(source_spec)s --output %(target_spec)s',
},
}

config_opts['environment'] = {
Expand Down
123 changes: 123 additions & 0 deletions mock/py/mockbuild/plugins/rpkg_preprocessor.py
@@ -0,0 +1,123 @@
# -*- coding: utf-8 -*-
# vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=python:textwidth=0:
# License: GPL2 or later see COPYING
# Written by clime
# Copyright (C) 2020 clime <clime@fedoraproject.org>

# python library imports
import os
import os.path
import re
import subprocess
import configparser
import shlex

# our imports
import mockbuild.util
from mockbuild.trace_decorator import getLog, traceLog
from mockbuild.exception import PkgError

requires_api_version = "1.1"


# plugin entry point
@traceLog()
def init(plugins, conf, buildroot):
RpkgPreprocessor(plugins, conf, buildroot)


class RpkgPreprocessor(object):
"""preprocess spec file by using rpkg utilities"""
# pylint: disable=too-few-public-methods
@traceLog()
def __init__(self, plugins, conf, buildroot):
self.buildroot = buildroot
self.config = buildroot.config
self.state = buildroot.state
self.opts = conf
self.log = getLog()
plugins.add_hook("pre_srpm_build", self._preprocess_proxy)
self.log.info("rpkg_preprocessor: initialized")

@traceLog()
def _install_requires(self, requires):
try:
self.buildroot.uid_manager.becomeUser(0, 0)
self.buildroot.pkg_manager.install(*requires, check=True)
finally:
self.buildroot.uid_manager.restorePrivs()

@traceLog()
def _preprocess_proxy(self, host_chroot_spec, host_chroot_sources):
if not host_chroot_sources or not os.path.isdir(host_chroot_sources):
self.log.debug("Sources not specified or not a directory. "
"Skipping rpkg preprocessing step.")
return

self._preprocess(host_chroot_spec, host_chroot_sources)

@traceLog()
def _preprocess(self, host_chroot_spec, host_chroot_sources):
rpkg_conf_path = os.path.join(host_chroot_sources, 'rpkg.conf')

if not os.path.isfile(rpkg_conf_path):
self.log.info("rpkg.conf not found. "
"Skipping rpkg preprocessing step.")
return

parser = configparser.ConfigParser(
interpolation=configparser.ExtendedInterpolation())

try:
parser.read(rpkg_conf_path)
except configparser.ParsingError as e:
raise PkgError("Parsing of %s failed with error: %s" % (rpkg_conf_path, repr(e)))

try:
preprocess_spec = parser.getboolean('rpkg', 'preprocess_spec')
except (configparser.Error, ValueError):
self.log.warning(
"Could not get boolean value of rpkg.preprocess_spec option from rpkg.conf.")
preprocess_spec = False

if not preprocess_spec:
self.log.info("preprocess_spec not enabled in rpkg.conf. "
"Skipping rpkg preprocessing step.")
return

# try to locate spec file in SOURCES, which will be our input
host_chroot_sources_spec = os.path.join(host_chroot_sources,
os.path.basename(host_chroot_spec))

if not os.path.isfile(host_chroot_sources_spec):
raise PkgError("%s is not a file. Spec file needs to be among sources." %
host_chroot_sources_spec)

self.log.info("Installing rpkg preprocessing requires...")
self._install_requires(self.opts.get('requires', []))

# get rid of host rootdir prefixes
rootdir_prefix = self.buildroot.make_chroot_path()
chroot_spec = host_chroot_spec.replace(rootdir_prefix, '')
chroot_sources = host_chroot_sources.replace(rootdir_prefix, '')
chroot_sources_spec = host_chroot_sources_spec.replace(rootdir_prefix, '')

command_str = self.opts.get('cmd') % {'source_spec': chroot_sources_spec,
'target_spec': chroot_spec}
command = shlex.split(command_str)

# determine whether to use private network or not based on rpmbuild_networking
private_network = (not self.config.get('rpmbuild_networking', False))

self.buildroot.doChroot(
command,
shell=False,
cwd=chroot_sources,
logger=self.buildroot.build_log,
uid=self.buildroot.chrootuid,
gid=self.buildroot.chrootgid,
user=self.buildroot.chrootuser,
unshare_net=private_network,
nspawn_args=self.config.get('nspawn_args', []),
printOutput=self.config.get('print_main_output', True)
)

0 comments on commit bda814a

Please sign in to comment.