Create new Runroot class and use it everywhere where runroot task is executed.

This adds new `Runroot` class and new `runroot_method` option which makes
it possible to choose between two currently available runroot methods:

- Local
- Koji

The main goal of this commit is to make it possible to add new runroot
methods in the future and this is the first step in that direction.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
This commit is contained in:
Jan Kaluza 2019-03-21 10:58:13 +01:00
parent 45cdbb2faf
commit 75bb48a882
11 changed files with 247 additions and 143 deletions

View File

@ -855,7 +855,16 @@ Options
"koji", which points to Fedora's koji.fedoraproject.org. "koji", which points to Fedora's koji.fedoraproject.org.
**runroot** [mandatory] **runroot** [mandatory]
(*bool*) -- run some tasks such as buildinstall or createiso in koji build root (True) or locally (False) (*bool*) -- run some tasks such as buildinstall or createiso in koji build root (True) or locally (False).
There might also be other runroot methods available. These can be chosen by ``runroot_method`` option.
**runroot_method**
(*str*) -- Runroot method to use. It can further specify the runroot method
in case the ``runroot`` is set to True.
Available methods are:
* ``local`` -- runroot tasks are run locally
* ``koji`` -- runroot tasks are run in Koji
**runroot_channel** **runroot_channel**
(*str*) -- name of koji channel (*str*) -- name of koji channel

View File

@ -560,6 +560,10 @@ def make_schema():
"type": "boolean", "type": "boolean",
"default": False, "default": False,
}, },
"runroot_method": {
"type": "string",
"enum": ["local", "koji"],
},
"create_jigdo": { "create_jigdo": {
"type": "boolean", "type": "boolean",
"default": True, "default": True,

View File

@ -30,10 +30,10 @@ from pungi.util import get_volid, get_arch_variant_data
from pungi.util import get_file_size, get_mtime, failable, makedirs from pungi.util import get_file_size, get_mtime, failable, makedirs
from pungi.util import copy_all, translate_path from pungi.util import copy_all, translate_path
from pungi.wrappers.lorax import LoraxWrapper from pungi.wrappers.lorax import LoraxWrapper
from pungi.wrappers.kojiwrapper import get_buildroot_rpms, KojiWrapper
from pungi.wrappers import iso from pungi.wrappers import iso
from pungi.wrappers.scm import get_file_from_scm from pungi.wrappers.scm import get_file_from_scm
from pungi.phases.base import PhaseBase from pungi.phases.base import PhaseBase
from pungi.runroot import Runroot
class BuildinstallPhase(PhaseBase): class BuildinstallPhase(PhaseBase):
@ -452,40 +452,24 @@ class BuildinstallThread(WorkerThread):
self.pool.log_info("[BEGIN] %s" % msg) self.pool.log_info("[BEGIN] %s" % msg)
task_id = None # Get list of packages which are neded in runroot.
if runroot:
# run in a koji build root
packages = [] packages = []
if buildinstall_method == "lorax": if buildinstall_method == "lorax":
packages += ["lorax"] packages += ["lorax"]
elif buildinstall_method == "buildinstall": elif buildinstall_method == "buildinstall":
packages += ["anaconda"] packages += ["anaconda"]
runroot_channel = compose.conf.get("runroot_channel")
runroot_tag = compose.conf["runroot_tag"]
koji_wrapper = KojiWrapper(compose.conf["koji_profile"]) # This should avoid a possible race condition with multiple processes
koji_cmd = koji_wrapper.get_runroot_cmd( # trying to get a kerberos ticket at the same time.
runroot_tag, arch, cmd,
channel=runroot_channel,
use_shell=True, task_id=True,
packages=packages, mounts=[compose.topdir],
weight=compose.conf['runroot_weights'].get('buildinstall'),
destdir=output_dir,
)
# avoid race conditions?
# Kerberos authentication failed: Permission denied in replay cache code (-1765328215) # Kerberos authentication failed: Permission denied in replay cache code (-1765328215)
time.sleep(num * 3) time.sleep(num * 3)
output = koji_wrapper.run_runroot_cmd(koji_cmd, log_file=log_file) # Start the runroot task.
if output["retcode"] != 0: runroot = Runroot(compose)
raise RuntimeError("Runroot task failed: %s. See %s for more details." runroot.run(
% (output["task_id"], log_file)) cmd, log_file=log_file, arch=arch, packages=packages,
task_id = output["task_id"] mounts=[compose.topdir], output_dir=output_dir,
weight=compose.conf['runroot_weights'].get('buildinstall'))
else:
# run locally
run(cmd, show_cmd=True, logfile=log_file)
if final_output_dir != output_dir: if final_output_dir != output_dir:
if not os.path.exists(final_output_dir): if not os.path.exists(final_output_dir):
@ -502,7 +486,7 @@ class BuildinstallThread(WorkerThread):
copy_all(log_dir, final_log_dir) copy_all(log_dir, final_log_dir)
log_file = compose.paths.log.log_file(arch, log_filename + '-RPMs') log_file = compose.paths.log.log_file(arch, log_filename + '-RPMs')
rpms = get_buildroot_rpms(compose, task_id) rpms = runroot.get_buildroot_rpms()
with open(log_file, "w") as f: with open(log_file, "w") as f:
f.write("\n".join(rpms)) f.write("\n".join(rpms))

View File

@ -15,7 +15,6 @@
import os import os
import time
import random import random
import shutil import shutil
import stat import stat
@ -28,12 +27,13 @@ from six.moves import shlex_quote
from pungi.wrappers import iso from pungi.wrappers import iso
from pungi.wrappers.createrepo import CreaterepoWrapper from pungi.wrappers.createrepo import CreaterepoWrapper
from pungi.wrappers.kojiwrapper import KojiWrapper from pungi.wrappers import kojiwrapper
from pungi.phases.base import PhaseBase, PhaseLoggerMixin from pungi.phases.base import PhaseBase, PhaseLoggerMixin
from pungi.util import (makedirs, get_volid, get_arch_variant_data, failable, from pungi.util import (makedirs, get_volid, get_arch_variant_data, failable,
get_file_size, get_mtime) get_file_size, get_mtime)
from pungi.media_split import MediaSplitter, convert_media_size from pungi.media_split import MediaSplitter, convert_media_size
from pungi.compose_metadata.discinfo import read_discinfo, write_discinfo from pungi.compose_metadata.discinfo import read_discinfo, write_discinfo
from pungi.runroot import Runroot
from .. import createiso from .. import createiso
@ -269,8 +269,6 @@ def add_iso_to_metadata(
def run_createiso_command(runroot, num, compose, bootable, arch, cmd, mounts, def run_createiso_command(runroot, num, compose, bootable, arch, cmd, mounts,
log_file, with_jigdo=True): log_file, with_jigdo=True):
if runroot:
# run in a koji build root
packages = ["coreutils", "genisoimage", "isomd5sum"] packages = ["coreutils", "genisoimage", "isomd5sum"]
if with_jigdo and compose.conf['create_jigdo']: if with_jigdo and compose.conf['create_jigdo']:
packages.append('jigdo') packages.append('jigdo')
@ -281,19 +279,18 @@ def run_createiso_command(runroot, num, compose, bootable, arch, cmd, mounts,
} }
packages.extend(extra_packages[compose.conf["buildinstall_method"]]) packages.extend(extra_packages[compose.conf["buildinstall_method"]])
runroot_channel = compose.conf.get("runroot_channel") runroot = Runroot(compose)
runroot_tag = compose.conf["runroot_tag"]
# get info about build arches in buildroot_tag build_arch = arch
koji_wrapper = KojiWrapper(compose.conf["koji_profile"]) if runroot.runroot_method == "koji" and not bootable:
runroot_tag = compose.conf["runroot_tag"]
koji_wrapper = kojiwrapper.KojiWrapper(compose.conf["koji_profile"])
koji_proxy = koji_wrapper.koji_proxy koji_proxy = koji_wrapper.koji_proxy
tag_info = koji_proxy.getTag(runroot_tag) tag_info = koji_proxy.getTag(runroot_tag)
if not tag_info: if not tag_info:
raise RuntimeError('Tag "%s" does not exist.' % runroot_tag) raise RuntimeError('Tag "%s" does not exist.' % runroot_tag)
tag_arches = tag_info["arches"].split(" ") tag_arches = tag_info["arches"].split(" ")
build_arch = arch
if not bootable:
if "x86_64" in tag_arches: if "x86_64" in tag_arches:
# assign non-bootable images to x86_64 if possible # assign non-bootable images to x86_64 if possible
build_arch = "x86_64" build_arch = "x86_64"
@ -301,26 +298,9 @@ def run_createiso_command(runroot, num, compose, bootable, arch, cmd, mounts,
# pick random arch from available runroot tag arches # pick random arch from available runroot tag arches
build_arch = random.choice(tag_arches) build_arch = random.choice(tag_arches)
koji_cmd = koji_wrapper.get_runroot_cmd( runroot.run(
runroot_tag, build_arch, cmd, cmd, log_file=log_file, arch=build_arch, packages=packages, mounts=mounts,
channel=runroot_channel, use_shell=True, task_id=True, weight=compose.conf['runroot_weights'].get('createiso'))
packages=packages, mounts=mounts,
weight=compose.conf['runroot_weights'].get('createiso')
)
# This should avoid a possible race condition with multiple processes
# trying to get a kerberos ticket at the same time.
# Kerberos authentication failed: Permission denied in replay cache code (-1765328215)
time.sleep(num * 3)
output = koji_wrapper.run_runroot_cmd(koji_cmd, log_file=log_file)
if output["retcode"] != 0:
raise RuntimeError("Runroot task failed: %s. See %s for more details."
% (output["task_id"], log_file))
else:
# run locally
run(cmd, show_cmd=True, logfile=log_file)
def split_iso(compose, arch, variant, no_split=False, logger=None): def split_iso(compose, arch, variant, no_split=False, logger=None):

View File

@ -7,11 +7,12 @@ from kobo import shortcuts
from kobo.threads import ThreadPool, WorkerThread from kobo.threads import ThreadPool, WorkerThread
from pungi.arch_utils import getBaseArch from pungi.arch_utils import getBaseArch
from pungi.runroot import Runroot
from .base import ConfigGuardedPhase from .base import ConfigGuardedPhase
from .. import util from .. import util
from ..ostree.utils import get_ref_from_treefile, get_commitid_from_commitid_file from ..ostree.utils import get_ref_from_treefile, get_commitid_from_commitid_file
from ..util import get_repo_dicts, translate_path from ..util import get_repo_dicts, translate_path
from ..wrappers import kojiwrapper, scm from ..wrappers import scm
class OSTreePhase(ConfigGuardedPhase): class OSTreePhase(ConfigGuardedPhase):
@ -90,7 +91,7 @@ class OSTreeThread(WorkerThread):
# mount it. # mount it.
util.makedirs(config['ostree_repo']) util.makedirs(config['ostree_repo'])
task_id = self._run_ostree_cmd(compose, variant, arch, config, repodir, self._run_ostree_cmd(compose, variant, arch, config, repodir,
extra_config_file=extra_config_file) extra_config_file=extra_config_file)
if compose.notifier: if compose.notifier:
@ -116,7 +117,7 @@ class OSTreeThread(WorkerThread):
repo_path=translate_path(compose, config['ostree_repo']), repo_path=translate_path(compose, config['ostree_repo']),
local_repo_path=config['ostree_repo']) local_repo_path=config['ostree_repo'])
self.pool.log_info('[DONE ] %s (task id: %s)' % (msg, task_id)) self.pool.log_info('[DONE ] %s' % (msg))
def _run_ostree_cmd(self, compose, variant, arch, config, config_repo, extra_config_file=None): def _run_ostree_cmd(self, compose, variant, arch, config, config_repo, extra_config_file=None):
cmd = [ cmd = [
@ -144,24 +145,15 @@ class OSTreeThread(WorkerThread):
if config.get('force_new_commit', False): if config.get('force_new_commit', False):
cmd.append('--force-new-commit') cmd.append('--force-new-commit')
runroot_channel = compose.conf.get("runroot_channel")
runroot_tag = compose.conf["runroot_tag"]
packages = ['pungi', 'ostree', 'rpm-ostree'] packages = ['pungi', 'ostree', 'rpm-ostree']
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']]
koji = kojiwrapper.KojiWrapper(compose.conf["koji_profile"])
koji_cmd = koji.get_runroot_cmd(runroot_tag, arch, cmd, runroot = Runroot(compose)
channel=runroot_channel, runroot.run(
use_shell=True, task_id=True, cmd, log_file=log_file, arch=arch, packages=packages,
packages=packages, mounts=mounts, mounts=mounts, new_chroot=True,
new_chroot=True, weight=compose.conf['runroot_weights'].get('ostree'))
weight=compose.conf["runroot_weights"].get('ostree'))
output = koji.run_runroot_cmd(koji_cmd, log_file=log_file)
if output["retcode"] != 0:
raise RuntimeError("Runroot task failed: %s. See %s for more details."
% (output["task_id"], log_file))
return output['task_id']
def _clone_repo(self, repodir, url, branch): def _clone_repo(self, repodir, url, branch):
scm.get_dir_from_scm({'scm': 'git', 'repo': url, 'branch': branch, 'dir': '.'}, scm.get_dir_from_scm({'scm': 'git', 'repo': url, 'branch': branch, 'dir': '.'},

View File

@ -11,7 +11,8 @@ from .base import ConfigGuardedPhase, PhaseLoggerMixin
from .. import util from .. import util
from ..arch import get_valid_arches from ..arch import get_valid_arches
from ..util import get_volid, get_repo_urls, version_generator, translate_path from ..util import get_volid, get_repo_urls, version_generator, translate_path
from ..wrappers import kojiwrapper, iso, lorax, scm from ..wrappers import iso, lorax, scm
from ..runroot import Runroot
class OstreeInstallerPhase(PhaseLoggerMixin, ConfigGuardedPhase): class OstreeInstallerPhase(PhaseLoggerMixin, ConfigGuardedPhase):
@ -87,12 +88,12 @@ class OstreeInstallerThread(WorkerThread):
disc_type = compose.conf['disc_types'].get('ostree', 'ostree') disc_type = compose.conf['disc_types'].get('ostree', 'ostree')
volid = get_volid(compose, arch, variant, disc_type=disc_type) volid = get_volid(compose, arch, variant, disc_type=disc_type)
task_id = self._run_ostree_cmd(compose, variant, arch, config, repos, output_dir, volid) self._run_ostree_cmd(compose, variant, arch, config, repos, output_dir, volid)
filename = compose.get_image_name(arch, variant, disc_type=disc_type) filename = compose.get_image_name(arch, variant, disc_type=disc_type)
self._copy_image(compose, variant, arch, filename, output_dir) self._copy_image(compose, variant, arch, filename, output_dir)
self._add_to_manifest(compose, variant, arch, filename) self._add_to_manifest(compose, variant, arch, filename)
self.pool.log_info('[DONE ] %s, (task id: %s)' % (msg, task_id)) self.pool.log_info('[DONE ] %s' % (msg))
def _clone_templates(self, url, branch='master'): def _clone_templates(self, url, branch='master'):
if not url: if not url:
@ -180,20 +181,11 @@ class OstreeInstallerThread(WorkerThread):
cmd = 'rm -rf %s && %s' % (shlex_quote(output_dir), cmd = 'rm -rf %s && %s' % (shlex_quote(output_dir),
' '.join([shlex_quote(x) for x in lorax_cmd])) ' '.join([shlex_quote(x) for x in lorax_cmd]))
runroot_channel = compose.conf.get("runroot_channel")
runroot_tag = compose.conf["runroot_tag"]
packages = ['pungi', 'lorax', 'ostree'] packages = ['pungi', 'lorax', 'ostree']
log_file = os.path.join(self.logdir, 'runroot.log') log_file = os.path.join(self.logdir, 'runroot.log')
koji = kojiwrapper.KojiWrapper(compose.conf["koji_profile"])
koji_cmd = koji.get_runroot_cmd(runroot_tag, arch, cmd, runroot = Runroot(compose)
channel=runroot_channel, runroot.run(
use_shell=True, task_id=True, cmd, log_file=log_file, arch=arch, packages=packages,
packages=packages, mounts=[compose.topdir], mounts=[compose.topdir], output_dir=output_dir,
weight=compose.conf['runroot_weights'].get('ostree_installer'), weight=compose.conf['runroot_weights'].get('ostree_installer'))
destdir=output_dir)
output = koji.run_runroot_cmd(koji_cmd, log_file=log_file)
if output["retcode"] != 0:
raise RuntimeError("Runroot task failed: %s. See %s for more details."
% (output["task_id"], log_file))
return output['task_id']

138
pungi/runroot.py Normal file
View File

@ -0,0 +1,138 @@
# -*- coding: utf-8 -*-
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import kobo.log
from kobo.shortcuts import run
from pungi.wrappers import kojiwrapper
class Runroot(kobo.log.LoggingBase):
def __init__(self, compose, logger=None):
"""
Creates new Runroot instance.
:param Compose compose: Compose instance.
:param Logger logger: Logger instance to log message to.
"""
kobo.log.LoggingBase.__init__(self, logger=logger)
self.compose = compose
self.runroot_method = self.get_runroot_method()
# Holds the result of last `run()` call.
self._result = None
def get_runroot_method(self):
"""
Returns the runroot method by checking the `runroot` and
`runroot_method` options in configuration.
:return: The "local" or "koji" string.
"""
runroot = self.compose.conf.get("runroot", None)
runroot_method = self.compose.conf.get("runroot_method", None)
if runroot is None and runroot_method is None:
raise ValueError("No runroot_method set.")
if runroot is False:
runroot_method = "local"
elif runroot and not runroot_method:
runroot_method = "koji"
return runroot_method
def _run_local(self, command, log_file=None, **kwargs):
"""
Runs the runroot command locally.
"""
run(command, show_cmd=True, logfile=log_file)
self._result = True
def _run_koji(self, command, log_file=None, packages=None,
arch=None, output_dir=None, **kwargs):
"""
Runs the runroot command in Koji.
"""
runroot_channel = self.compose.conf.get("runroot_channel")
runroot_tag = self.compose.conf["runroot_tag"]
if output_dir:
kwargs["destdir"] = output_dir
koji_wrapper = kojiwrapper.KojiWrapper(self.compose.conf["koji_profile"])
koji_cmd = koji_wrapper.get_runroot_cmd(
runroot_tag, arch, command,
channel=runroot_channel, use_shell=True, task_id=True,
packages=packages, **kwargs
)
output = koji_wrapper.run_runroot_cmd(koji_cmd, log_file=log_file)
if output["retcode"] != 0:
raise RuntimeError("Runroot task failed: %s. See %s for more details."
% (output["task_id"], log_file))
self._result = output
def run(self, command, log_file=None, packages=None, arch=None,
output_dir=None, **kwargs):
"""
Runs the runroot task using the `Runroot.runroot_method`. Blocks until
the runroot task is successfully finished. Raises an exception on error.
The **kwargs are optional and matches the `KojiWrapper.get_runroot_cmd()`
kwargs. Some `runroot_method` methods might ignore the kwargs which
do not make sense for them.
:param str command: Command to execute.
:param str log_file: Log file into which the output of runroot task will
be logged.
:param list packages: List of packages which are needed for runroot task
to be executed.
:param str arch: Architecture on which the runroot task should be
executed.
:param str output_dir: Directory where the `command` stores its output.
The permissions of this output_dir might be changed by `runroot_method`
to allow the executor of this runroot task to accesss them.
See `KojiWrapper.get_runroot_cmd()` for more information.
"""
if self.runroot_method == "local":
self._run_local(
command, log_file=log_file, packages=packages, arch=arch,
output_dir=output_dir, **kwargs)
elif self.runroot_method == "koji":
self._run_koji(
command, log_file=log_file, packages=packages, arch=arch,
output_dir=output_dir, **kwargs)
else:
raise ValueError("Unknown runroot_method %r." % self.runroot_method)
def get_buildroot_rpms(self):
"""
Returns the list of RPMs installed in a buildroot in which the runroot
task was executed. This is needed to track what actually generated
the data generated by runroot task.
This must be called after the `run()` method successfully finished,
otherwise raises an exception.
:return: List of RPMs in buildroot in which the runroot task run.
"""
if not self._result:
raise ValueError("Runroot.get_build_rpms before runroot task finished.")
if self.runroot_method in ["local", "koji"]:
if self.runroot_method == "local":
task_id = None
else:
task_id = self._result["task_id"]
return kojiwrapper.get_buildroot_rpms(self.compose, task_id)
else:
raise ValueError("Unknown runroot_method %r." % self.runroot_method)

View File

@ -734,8 +734,8 @@ class BuildinstallThreadTestCase(PungiTestCase):
self.pool = mock.Mock(finished_tasks=set()) self.pool = mock.Mock(finished_tasks=set())
self.cmd = mock.Mock() self.cmd = mock.Mock()
@mock.patch('pungi.phases.buildinstall.KojiWrapper') @mock.patch('pungi.wrappers.kojiwrapper.KojiWrapper')
@mock.patch('pungi.phases.buildinstall.get_buildroot_rpms') @mock.patch('pungi.wrappers.kojiwrapper.get_buildroot_rpms')
@mock.patch('pungi.phases.buildinstall.run') @mock.patch('pungi.phases.buildinstall.run')
def test_buildinstall_thread_with_lorax_in_runroot(self, run, get_buildroot_rpms, KojiWrapperMock): def test_buildinstall_thread_with_lorax_in_runroot(self, run, get_buildroot_rpms, KojiWrapperMock):
compose = BuildInstallCompose(self.topdir, { compose = BuildInstallCompose(self.topdir, {
@ -779,8 +779,8 @@ class BuildinstallThreadTestCase(PungiTestCase):
self.assertItemsEqual(rpms, ['bash', 'zsh']) self.assertItemsEqual(rpms, ['bash', 'zsh'])
self.assertItemsEqual(self.pool.finished_tasks, [('Server', 'x86_64')]) self.assertItemsEqual(self.pool.finished_tasks, [('Server', 'x86_64')])
@mock.patch('pungi.phases.buildinstall.KojiWrapper') @mock.patch('pungi.wrappers.kojiwrapper.KojiWrapper')
@mock.patch('pungi.phases.buildinstall.get_buildroot_rpms') @mock.patch('pungi.wrappers.kojiwrapper.get_buildroot_rpms')
@mock.patch('pungi.phases.buildinstall.run') @mock.patch('pungi.phases.buildinstall.run')
def test_buildinstall_thread_with_buildinstall_in_runroot(self, run, get_buildroot_rpms, KojiWrapperMock): def test_buildinstall_thread_with_buildinstall_in_runroot(self, run, get_buildroot_rpms, KojiWrapperMock):
compose = BuildInstallCompose(self.topdir, { compose = BuildInstallCompose(self.topdir, {
@ -823,8 +823,8 @@ class BuildinstallThreadTestCase(PungiTestCase):
self.assertItemsEqual(rpms, ['bash', 'zsh']) self.assertItemsEqual(rpms, ['bash', 'zsh'])
self.assertItemsEqual(self.pool.finished_tasks, [(None, 'x86_64')]) self.assertItemsEqual(self.pool.finished_tasks, [(None, 'x86_64')])
@mock.patch('pungi.phases.buildinstall.KojiWrapper') @mock.patch('pungi.wrappers.kojiwrapper.KojiWrapper')
@mock.patch('pungi.phases.buildinstall.get_buildroot_rpms') @mock.patch('pungi.wrappers.kojiwrapper.get_buildroot_rpms')
@mock.patch('pungi.phases.buildinstall.run') @mock.patch('pungi.phases.buildinstall.run')
def test_buildinstall_fail_exit_code(self, run, get_buildroot_rpms, KojiWrapperMock): def test_buildinstall_fail_exit_code(self, run, get_buildroot_rpms, KojiWrapperMock):
compose = BuildInstallCompose(self.topdir, { compose = BuildInstallCompose(self.topdir, {
@ -858,8 +858,8 @@ class BuildinstallThreadTestCase(PungiTestCase):
]) ])
self.assertItemsEqual(self.pool.finished_tasks, []) self.assertItemsEqual(self.pool.finished_tasks, [])
@mock.patch('pungi.phases.buildinstall.KojiWrapper') @mock.patch('pungi.wrappers.kojiwrapper.KojiWrapper')
@mock.patch('pungi.phases.buildinstall.get_buildroot_rpms') @mock.patch('pungi.wrappers.kojiwrapper.get_buildroot_rpms')
@mock.patch('pungi.phases.buildinstall.run') @mock.patch('pungi.phases.buildinstall.run')
def test_lorax_fail_exit_code(self, run, get_buildroot_rpms, KojiWrapperMock): def test_lorax_fail_exit_code(self, run, get_buildroot_rpms, KojiWrapperMock):
compose = BuildInstallCompose(self.topdir, { compose = BuildInstallCompose(self.topdir, {
@ -892,8 +892,8 @@ class BuildinstallThreadTestCase(PungiTestCase):
]) ])
self.assertItemsEqual(self.pool.finished_tasks, []) self.assertItemsEqual(self.pool.finished_tasks, [])
@mock.patch('pungi.phases.buildinstall.KojiWrapper') @mock.patch('pungi.wrappers.kojiwrapper.KojiWrapper')
@mock.patch('pungi.phases.buildinstall.get_buildroot_rpms') @mock.patch('pungi.wrappers.kojiwrapper.get_buildroot_rpms')
@mock.patch('pungi.phases.buildinstall.run') @mock.patch('pungi.phases.buildinstall.run')
def test_skips_on_existing_output_dir(self, run, get_buildroot_rpms, KojiWrapperMock): def test_skips_on_existing_output_dir(self, run, get_buildroot_rpms, KojiWrapperMock):
compose = BuildInstallCompose(self.topdir, { compose = BuildInstallCompose(self.topdir, {
@ -921,8 +921,8 @@ class BuildinstallThreadTestCase(PungiTestCase):
self.assertTrue(os.path.exists(dummy_file)) self.assertTrue(os.path.exists(dummy_file))
self.assertItemsEqual(self.pool.finished_tasks, []) self.assertItemsEqual(self.pool.finished_tasks, [])
@mock.patch('pungi.phases.buildinstall.KojiWrapper') @mock.patch('pungi.wrappers.kojiwrapper.KojiWrapper')
@mock.patch('pungi.phases.buildinstall.get_buildroot_rpms') @mock.patch('pungi.wrappers.kojiwrapper.get_buildroot_rpms')
@mock.patch('pungi.phases.buildinstall.run') @mock.patch('pungi.phases.buildinstall.run')
@mock.patch('pungi.phases.buildinstall.copy_all') @mock.patch('pungi.phases.buildinstall.copy_all')
def test_buildinstall_thread_with_lorax_custom_buildinstall_topdir( def test_buildinstall_thread_with_lorax_custom_buildinstall_topdir(

View File

@ -348,7 +348,7 @@ class CreateisoThreadTest(helpers.PungiTestCase):
@mock.patch('pungi.phases.createiso.iso') @mock.patch('pungi.phases.createiso.iso')
@mock.patch('pungi.phases.createiso.get_mtime') @mock.patch('pungi.phases.createiso.get_mtime')
@mock.patch('pungi.phases.createiso.get_file_size') @mock.patch('pungi.phases.createiso.get_file_size')
@mock.patch('pungi.phases.createiso.KojiWrapper') @mock.patch('pungi.wrappers.kojiwrapper.KojiWrapper')
def test_process_in_runroot(self, KojiWrapper, get_file_size, get_mtime, iso): def test_process_in_runroot(self, KojiWrapper, get_file_size, get_mtime, iso):
compose = helpers.DummyCompose(self.topdir, { compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test', 'release_short': 'test',
@ -412,7 +412,7 @@ class CreateisoThreadTest(helpers.PungiTestCase):
@mock.patch('pungi.phases.createiso.iso') @mock.patch('pungi.phases.createiso.iso')
@mock.patch('pungi.phases.createiso.get_mtime') @mock.patch('pungi.phases.createiso.get_mtime')
@mock.patch('pungi.phases.createiso.get_file_size') @mock.patch('pungi.phases.createiso.get_file_size')
@mock.patch('pungi.phases.createiso.KojiWrapper') @mock.patch('pungi.wrappers.kojiwrapper.KojiWrapper')
def test_process_source_iso(self, KojiWrapper, get_file_size, get_mtime, iso): def test_process_source_iso(self, KojiWrapper, get_file_size, get_mtime, iso):
compose = helpers.DummyCompose(self.topdir, { compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test', 'release_short': 'test',
@ -477,7 +477,7 @@ class CreateisoThreadTest(helpers.PungiTestCase):
@mock.patch('pungi.phases.createiso.iso') @mock.patch('pungi.phases.createiso.iso')
@mock.patch('pungi.phases.createiso.get_mtime') @mock.patch('pungi.phases.createiso.get_mtime')
@mock.patch('pungi.phases.createiso.get_file_size') @mock.patch('pungi.phases.createiso.get_file_size')
@mock.patch('pungi.phases.createiso.KojiWrapper') @mock.patch('pungi.wrappers.kojiwrapper.KojiWrapper')
def test_process_bootable(self, KojiWrapper, get_file_size, get_mtime, iso): def test_process_bootable(self, KojiWrapper, get_file_size, get_mtime, iso):
compose = helpers.DummyCompose(self.topdir, { compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test', 'release_short': 'test',
@ -513,7 +513,8 @@ class CreateisoThreadTest(helpers.PungiTestCase):
with mock.patch('time.sleep'): with mock.patch('time.sleep'):
t.process((compose, cmd, compose.variants['Server'], 'x86_64'), 1) t.process((compose, cmd, compose.variants['Server'], 'x86_64'), 1)
self.assertEqual(getTag.call_args_list, [mock.call('f25-build')]) # There is no need to call getTag if `bootable` is True.
self.assertEqual(getTag.call_args_list, [])
self.assertEqual(get_runroot_cmd.call_args_list, self.assertEqual(get_runroot_cmd.call_args_list,
[mock.call('f25-build', 'x86_64', cmd['cmd'], channel=None, [mock.call('f25-build', 'x86_64', cmd['cmd'], channel=None,
mounts=[self.topdir], mounts=[self.topdir],
@ -543,7 +544,7 @@ class CreateisoThreadTest(helpers.PungiTestCase):
@mock.patch('pungi.phases.createiso.iso') @mock.patch('pungi.phases.createiso.iso')
@mock.patch('pungi.phases.createiso.get_mtime') @mock.patch('pungi.phases.createiso.get_mtime')
@mock.patch('pungi.phases.createiso.get_file_size') @mock.patch('pungi.phases.createiso.get_file_size')
@mock.patch('pungi.phases.createiso.KojiWrapper') @mock.patch('pungi.wrappers.kojiwrapper.KojiWrapper')
def test_process_in_runroot_non_existing_tag(self, KojiWrapper, get_file_size, def test_process_in_runroot_non_existing_tag(self, KojiWrapper, get_file_size,
get_mtime, iso): get_mtime, iso):
compose = helpers.DummyCompose(self.topdir, { compose = helpers.DummyCompose(self.topdir, {
@ -575,7 +576,7 @@ class CreateisoThreadTest(helpers.PungiTestCase):
@mock.patch('pungi.phases.createiso.iso') @mock.patch('pungi.phases.createiso.iso')
@mock.patch('pungi.phases.createiso.get_mtime') @mock.patch('pungi.phases.createiso.get_mtime')
@mock.patch('pungi.phases.createiso.get_file_size') @mock.patch('pungi.phases.createiso.get_file_size')
@mock.patch('pungi.phases.createiso.KojiWrapper') @mock.patch('pungi.wrappers.kojiwrapper.KojiWrapper')
def test_process_in_runroot_crash(self, KojiWrapper, get_file_size, get_mtime, iso): def test_process_in_runroot_crash(self, KojiWrapper, get_file_size, get_mtime, iso):
compose = helpers.DummyCompose(self.topdir, { compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test', 'release_short': 'test',
@ -614,7 +615,7 @@ class CreateisoThreadTest(helpers.PungiTestCase):
@mock.patch('pungi.phases.createiso.iso') @mock.patch('pungi.phases.createiso.iso')
@mock.patch('pungi.phases.createiso.get_mtime') @mock.patch('pungi.phases.createiso.get_mtime')
@mock.patch('pungi.phases.createiso.get_file_size') @mock.patch('pungi.phases.createiso.get_file_size')
@mock.patch('pungi.phases.createiso.KojiWrapper') @mock.patch('pungi.wrappers.kojiwrapper.KojiWrapper')
def test_process_in_runroot_fail(self, KojiWrapper, get_file_size, get_mtime, iso): def test_process_in_runroot_fail(self, KojiWrapper, get_file_size, get_mtime, iso):
compose = helpers.DummyCompose(self.topdir, { compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test', 'release_short': 'test',
@ -658,8 +659,8 @@ class CreateisoThreadTest(helpers.PungiTestCase):
@mock.patch('pungi.phases.createiso.iso') @mock.patch('pungi.phases.createiso.iso')
@mock.patch('pungi.phases.createiso.get_mtime') @mock.patch('pungi.phases.createiso.get_mtime')
@mock.patch('pungi.phases.createiso.get_file_size') @mock.patch('pungi.phases.createiso.get_file_size')
@mock.patch('pungi.phases.createiso.run') @mock.patch('pungi.runroot.run')
@mock.patch('pungi.phases.createiso.KojiWrapper') @mock.patch('pungi.wrappers.kojiwrapper.KojiWrapper')
def test_process_locally(self, KojiWrapper, run, get_file_size, get_mtime, iso): def test_process_locally(self, KojiWrapper, run, get_file_size, get_mtime, iso):
compose = helpers.DummyCompose(self.topdir, { compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test', 'release_short': 'test',
@ -703,8 +704,8 @@ class CreateisoThreadTest(helpers.PungiTestCase):
self.assertEqual(image.type, 'dvd') self.assertEqual(image.type, 'dvd')
self.assertEqual(image.subvariant, 'Server') self.assertEqual(image.subvariant, 'Server')
@mock.patch('pungi.phases.createiso.run') @mock.patch('pungi.runroot.run')
@mock.patch('pungi.phases.createiso.KojiWrapper') @mock.patch('pungi.wrappers.kojiwrapper.KojiWrapper')
def test_process_locally_crash(self, KojiWrapper, run): def test_process_locally_crash(self, KojiWrapper, run):
compose = helpers.DummyCompose(self.topdir, { compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test', 'release_short': 'test',

View File

@ -28,7 +28,8 @@ class OstreeInstallerPhaseTest(helpers.PungiTestCase):
compose = helpers.DummyCompose(self.topdir, { compose = helpers.DummyCompose(self.topdir, {
'ostree_installer': [ 'ostree_installer': [
('^Everything$', {'x86_64': cfg}) ('^Everything$', {'x86_64': cfg})
] ],
'runroot': True,
}) })
pool = ThreadPool.return_value pool = ThreadPool.return_value
@ -101,6 +102,7 @@ class OstreeThreadTest(helpers.PungiTestCase):
'translate_paths': [ 'translate_paths': [
(self.topdir + '/work', 'http://example.com/work') (self.topdir + '/work', 'http://example.com/work')
], ],
'runroot': True,
}) })
def assertImageAdded(self, compose, ImageCls, iso): def assertImageAdded(self, compose, ImageCls, iso):

View File

@ -23,7 +23,8 @@ class OSTreePhaseTest(helpers.PungiTestCase):
compose = helpers.DummyCompose(self.topdir, { compose = helpers.DummyCompose(self.topdir, {
'ostree': [ 'ostree': [
('^Everything$', {'x86_64': cfg}) ('^Everything$', {'x86_64': cfg})
] ],
'runroot': True,
}) })
pool = ThreadPool.return_value pool = ThreadPool.return_value
@ -112,14 +113,15 @@ class OSTreeThreadTest(helpers.PungiTestCase):
'config_url': 'https://git.fedorahosted.org/git/fedora-atomic.git', 'config_url': 'https://git.fedorahosted.org/git/fedora-atomic.git',
'config_branch': 'f24', 'config_branch': 'f24',
'treefile': 'fedora-atomic-docker-host.json', 'treefile': 'fedora-atomic-docker-host.json',
'ostree_repo': self.repo 'ostree_repo': self.repo,
} }
self.compose = helpers.DummyCompose(self.topdir, { self.compose = helpers.DummyCompose(self.topdir, {
'koji_profile': 'koji', 'koji_profile': 'koji',
'runroot_tag': 'rrt', 'runroot_tag': 'rrt',
'translate_paths': [ 'translate_paths': [
(self.topdir, 'http://example.com') (self.topdir, 'http://example.com')
] ],
'runroot': True
}) })
self.pool = mock.Mock() self.pool = mock.Mock()