Allow setting runroot_method per Pungi phase.

The `runroot_method` now accepts `dict` value with phase name as a key
and runroot method as a value. For backward compatibility, the `str`
value is still supported.

The new `global_runroot_method` option has been added which defines
the runroot method in case it is not set in `dict` in the `runroot_method`.

This commit allows running `createiso` phase locally while keeping the other
phases in Koji.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
This commit is contained in:
Jan Kaluza 2020-01-02 10:34:03 +01:00 committed by lsedlar
parent b415e31f9d
commit 817acdbbac
7 changed files with 74 additions and 9 deletions

View File

@ -45,6 +45,7 @@ import jsonschema
import six import six
from kobo.shortcuts import force_list from kobo.shortcuts import force_list
from pungi.phases import PHASES_NAMES from pungi.phases import PHASES_NAMES
from pungi.runroot import RUNROOT_TYPES
from productmd.common import RELEASE_TYPES from productmd.common import RELEASE_TYPES
from productmd.composeinfo import COMPOSE_TYPES from productmd.composeinfo import COMPOSE_TYPES
@ -586,9 +587,39 @@ def make_schema():
"runroot": { "runroot": {
"deprecated": "remove it. Please specify 'runroot_method' if you want to enable runroot, otherwise run things locally", "deprecated": "remove it. Please specify 'runroot_method' if you want to enable runroot, otherwise run things locally",
}, },
"runroot_method": { "global_runroot_method": {
"type": "string", "type": "string",
"enum": ["local", "koji", "openssh"], "enum": RUNROOT_TYPES,
},
"runroot_method": {
"oneOf": [
{
"type": "string",
"enum": RUNROOT_TYPES,
},
{
"type": "object",
"properties": {
"buildinstall": {
"type": "string",
"enum": RUNROOT_TYPES,
},
"ostree_installer": {
"type": "string",
"enum": RUNROOT_TYPES,
},
"ostree": {
"type": "string",
"enum": RUNROOT_TYPES,
},
"createiso": {
"type": "string",
"enum": RUNROOT_TYPES,
},
},
"additionalProperties": False,
}
]
}, },
"runroot_ssh_username": { "runroot_ssh_username": {
"type": "string", "type": "string",

View File

@ -455,7 +455,7 @@ class BuildinstallThread(WorkerThread):
time.sleep(num * 3) time.sleep(num * 3)
# Start the runroot task. # Start the runroot task.
runroot = Runroot(compose) runroot = Runroot(compose, phase="buildinstall")
runroot.run( runroot.run(
cmd, log_file=log_file, arch=arch, packages=packages, cmd, log_file=log_file, arch=arch, packages=packages,
mounts=[compose.topdir], mounts=[compose.topdir],

View File

@ -278,7 +278,7 @@ def run_createiso_command(num, compose, bootable, arch, cmd, mounts,
} }
packages.extend(extra_packages[compose.conf["buildinstall_method"]]) packages.extend(extra_packages[compose.conf["buildinstall_method"]])
runroot = Runroot(compose) runroot = Runroot(compose, phase="createiso")
build_arch = arch build_arch = arch
if runroot.runroot_method == "koji" and not bootable: if runroot.runroot_method == "koji" and not bootable:

View File

@ -162,7 +162,7 @@ class OSTreeThread(WorkerThread):
log_file = os.path.join(self.logdir, 'runroot.log') log_file = os.path.join(self.logdir, 'runroot.log')
mounts = [compose.topdir, config['ostree_repo']] mounts = [compose.topdir, config['ostree_repo']]
runroot = Runroot(compose) runroot = Runroot(compose, phase="ostree")
runroot.run( runroot.run(
cmd, log_file=log_file, arch=arch, packages=packages, cmd, log_file=log_file, arch=arch, packages=packages,
mounts=mounts, new_chroot=True, mounts=mounts, new_chroot=True,

View File

@ -199,7 +199,7 @@ class OstreeInstallerThread(WorkerThread):
log_file = os.path.join(self.logdir, 'runroot.log') log_file = os.path.join(self.logdir, 'runroot.log')
runroot = Runroot(compose) runroot = Runroot(compose, phase="ostree_installer")
runroot.run( runroot.run(
cmd, log_file=log_file, arch=arch, packages=packages, cmd, log_file=log_file, arch=arch, packages=packages,
mounts=[compose.topdir], chown_paths=[output_dir], mounts=[compose.topdir], chown_paths=[output_dir],

View File

@ -21,25 +21,31 @@ from kobo.shortcuts import run
from pungi.wrappers import kojiwrapper from pungi.wrappers import kojiwrapper
RUNROOT_TYPES = ["local", "koji", "openssh"]
class Runroot(kobo.log.LoggingBase): class Runroot(kobo.log.LoggingBase):
def __init__(self, compose, logger=None): def __init__(self, compose, logger=None, phase=None):
""" """
Creates new Runroot instance. Creates new Runroot instance.
:param Compose compose: Compose instance. :param Compose compose: Compose instance.
:param Logger logger: Logger instance to log message to. :param Logger logger: Logger instance to log message to.
:param str phase: Pungi phase the runroot task is run as part of.
""" """
kobo.log.LoggingBase.__init__(self, logger=logger) kobo.log.LoggingBase.__init__(self, logger=logger)
self.compose = compose self.compose = compose
self.runroot_method = self.get_runroot_method() self.runroot_method = self.get_runroot_method(phase)
# Holds the result of last `run()` call. # Holds the result of last `run()` call.
self._result = None self._result = None
def get_runroot_method(self): def get_runroot_method(self, phase=None):
""" """
Returns the runroot method by checking the `runroot_tag` and Returns the runroot method by checking the `runroot_tag` and
`runroot_method` options in configuration. `runroot_method` options in configuration.
:param str phase: Pungi phase to get the runroot method for.
:return: The configured method :return: The configured method
""" """
runroot_tag = self.compose.conf.get("runroot_tag") runroot_tag = self.compose.conf.get("runroot_tag")
@ -48,6 +54,15 @@ class Runroot(kobo.log.LoggingBase):
# If we have runroot tag and no method, let's assume koji method # If we have runroot tag and no method, let's assume koji method
# for backwards compatibility. # for backwards compatibility.
return "koji" return "koji"
if isinstance(runroot_method, dict):
# If runroot_method is set to dict, check if there is runroot_method
# override for the current phase.
if phase in runroot_method:
return runroot_method[phase]
global_runroot_method = self.compose.conf.get("global_runroot_method")
return global_runroot_method or "local"
# Otherwise use the configured method or default to local if nothing is # Otherwise use the configured method or default to local if nothing is
# given. # given.
return runroot_method or "local" return runroot_method or "local"

View File

@ -27,6 +27,25 @@ class TestRunrootOpenSSH(helpers.PungiTestCase):
method = self.runroot.get_runroot_method() method = self.runroot.get_runroot_method()
self.assertEqual(method, "openssh") self.assertEqual(method, "openssh")
def test_get_runroot_method_phase(self):
self.compose.conf["runroot_method"] = {"ostree": "openssh"}
method = self.runroot.get_runroot_method(phase="ostree")
self.assertEqual(method, "openssh")
# Test fallback to local
method = self.runroot.get_runroot_method(phase="createiso")
self.assertEqual(method, "local")
def test_get_runroot_method_global_runroot_method(self):
self.compose.conf["runroot_method"] = {"ostree": "openssh"}
self.compose.conf["global_runroot_method"] = "koji"
method = self.runroot.get_runroot_method(phase="ostree")
self.assertEqual(method, "openssh")
# Test global_runroot_method
method = self.runroot.get_runroot_method(phase="createiso")
self.assertEqual(method, "koji")
def _ssh_call(self, cmd, suffix=None): def _ssh_call(self, cmd, suffix=None):
""" """
Helper method returning default SSH mock.call with given command `cmd`. Helper method returning default SSH mock.call with given command `cmd`.