[createiso] Use shell script for runroot

Instead of installing pungi itself in the runroot, we can prepare the
commands to be run on compose box, write the shell script into work/
directory, which is mounted in the chroot, and execute that. This way
there is no business logic in runroot (except for finding lorax
templates).

The main advantage of this approach is that we don't need to pull any
extra dependencies into buildroot.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
This commit is contained in:
Lubomír Sedlář 2016-07-28 13:05:38 +02:00
parent 6a682f64fe
commit f37a14fb60
7 changed files with 276 additions and 327 deletions

View File

@ -1,20 +0,0 @@
#!/usr/bin/env python3
# This needs to work with Python 3 as pylorax only provides the find_templates
# function in recent builds that are not provided for Python 2.7.
#
# This script will print a location of lorax templates. If it fails to import
# pylorax, or the find_templates function does not exist, the first command
# line argument will be printed instead.
import sys
if len(sys.argv) != 2:
print('Usage: {} FALLBACK'.format(sys.argv[0]), file=sys.stderr)
sys.exit(1)
try:
import pylorax
print(pylorax.find_templates())
except (ImportError, AttributeError):
print(sys.argv[1])

View File

@ -52,8 +52,6 @@ rm -rf %{buildroot}
%{__python} setup.py install -O1 --skip-build --root %{buildroot} %{__python} setup.py install -O1 --skip-build --root %{buildroot}
%{__install} -d %{buildroot}/var/cache/pungi %{__install} -d %{buildroot}/var/cache/pungi
%{__install} -d %{buildroot}/%{_mandir}/man8 %{__install} -d %{buildroot}/%{_mandir}/man8
# this script has to be run by python3 and setup.py is too dumb
sed -i 's|/usr/bin/python$|/usr/bin/python3|' %{buildroot}/%{_bindir}/pungi-pylorax-find-templates
%files %files
%defattr(-,root,root,-) %defattr(-,root,root,-)

View File

@ -1,31 +1,53 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import argparse from __future__ import print_function
import os import os
from kobo import shortcuts import pipes
from collections import namedtuple
from .wrappers.iso import IsoWrapper from .wrappers.iso import IsoWrapper
from .wrappers.jigdo import JigdoWrapper from .wrappers.jigdo import JigdoWrapper
def find_templates(fallback): CreateIsoOpts = namedtuple('CreateIsoOpts',
""" ['buildinstall_method', 'arch', 'output_dir', 'jigdo_dir',
Helper for finding lorax templates. The called program needs to run with 'iso_name', 'volid', 'graft_points', 'supported', 'os_tree'])
Python 3, while the rest of this script only supports Python 2. CreateIsoOpts.__new__.__defaults__ = (None,) * len(CreateIsoOpts._fields)
"""
_, output = shortcuts.run(['pungi-pylorax-find-templates', fallback],
stdout=True, show_cmd=True)
return output.strip()
def make_image(iso, opts): def quote(str):
"""Quote an argument for shell, but make sure $TEMPLATE variable will be
expanded.
"""
if str.startswith('$TEMPLATE'):
return '$TEMPLATE%s' % pipes.quote(str.replace('$TEMPLATE', '', 1))
return pipes.quote(str)
def emit(f, cmd):
"""Print line of shell code into the stream."""
if isinstance(cmd, basestring):
print(cmd, file=f)
else:
print(' '.join([quote(x) for x in cmd]), file=f)
FIND_TEMPLATE_SNIPPET = """
if ! TEMPLATE="$(python3 -c 'import pylorax; print(pylorax.find_templates())')"; then
TEMPLATE=/usr/share/lorax;
fi
""".replace('\n', '')
def make_image(f, iso, opts):
mkisofs_kwargs = {} mkisofs_kwargs = {}
if opts.buildinstall_method: if opts.buildinstall_method:
if opts.buildinstall_method == 'lorax': if opts.buildinstall_method == 'lorax':
dir = find_templates('/usr/share/lorax') emit(f, FIND_TEMPLATE_SNIPPET)
mkisofs_kwargs["boot_args"] = iso.get_boot_options( mkisofs_kwargs["boot_args"] = iso.get_boot_options(
opts.arch, os.path.join(dir, 'config_files/ppc')) opts.arch, os.path.join('$TEMPLATE', 'config_files/ppc'))
elif opts.buildinstall_method == 'buildinstall': elif opts.buildinstall_method == 'buildinstall':
mkisofs_kwargs["boot_args"] = iso.get_boot_options( mkisofs_kwargs["boot_args"] = iso.get_boot_options(
opts.arch, "/usr/lib/anaconda-runtime/boot") opts.arch, "/usr/lib/anaconda-runtime/boot")
@ -37,29 +59,29 @@ def make_image(iso, opts):
cmd = iso.get_mkisofs_cmd(opts.iso_name, None, volid=opts.volid, cmd = iso.get_mkisofs_cmd(opts.iso_name, None, volid=opts.volid,
exclude=["./lost+found"], exclude=["./lost+found"],
graft_points=opts.graft_points, **mkisofs_kwargs) graft_points=opts.graft_points, **mkisofs_kwargs)
shortcuts.run(cmd, stdout=True, show_cmd=True, workdir=opts.output_dir) emit(f, cmd)
def implant_md5(iso, opts): def implant_md5(f, iso, opts):
cmd = iso.get_implantisomd5_cmd(opts.iso_name, opts.supported) cmd = iso.get_implantisomd5_cmd(opts.iso_name, opts.supported)
shortcuts.run(cmd, stdout=True, show_cmd=True, workdir=opts.output_dir) emit(f, cmd)
def run_isohybrid(iso, opts): def run_isohybrid(f, iso, opts):
"""If the image is bootable, it needs to include an MBR or GPT so that it """If the image is bootable, it should include an MBR or GPT so that it can
can actually be booted. This is done by running isohybrid on the image. be booted when written to USB disk. This is done by running isohybrid on
the image.
""" """
if opts.buildinstall_method and opts.arch in ["x86_64", "i386"]: if opts.buildinstall_method and opts.arch in ["x86_64", "i386"]:
cmd = iso.get_isohybrid_cmd(opts.iso_name, opts.arch) cmd = iso.get_isohybrid_cmd(opts.iso_name, opts.arch)
shortcuts.run(cmd, stdout=True, show_cmd=True, workdir=opts.output_dir) emit(f, cmd)
def make_manifest(iso, opts): def make_manifest(f, iso, opts):
shortcuts.run(iso.get_manifest_cmd(opts.iso_name), stdout=True, emit(f, iso.get_manifest_cmd(opts.iso_name))
show_cmd=True, workdir=opts.output_dir)
def make_jigdo(opts): def make_jigdo(f, opts):
jigdo = JigdoWrapper() jigdo = JigdoWrapper()
files = [ files = [
{ {
@ -71,43 +93,20 @@ def make_jigdo(opts):
cmd = jigdo.get_jigdo_cmd(os.path.join(opts.output_dir, opts.iso_name), cmd = jigdo.get_jigdo_cmd(os.path.join(opts.output_dir, opts.iso_name),
files, output_dir=opts.jigdo_dir, files, output_dir=opts.jigdo_dir,
no_servers=True, report="noprogress") no_servers=True, report="noprogress")
shortcuts.run(cmd, stdout=True, show_cmd=True, workdir=opts.output_dir) emit(f, cmd)
def run(opts): def write_script(opts, f):
iso = IsoWrapper()
make_image(iso, opts)
run_isohybrid(iso, opts)
implant_md5(iso, opts)
make_manifest(iso, opts)
if opts.jigdo_dir:
make_jigdo(opts)
def main(args=None):
parser = argparse.ArgumentParser()
parser.add_argument('--output-dir', required=True,
help='where to put the final image')
parser.add_argument('--iso-name', required=True,
help='filename for the created ISO image')
parser.add_argument('--volid', required=True,
help='volume id for the image')
parser.add_argument('--graft-points', required=True,
help='')
parser.add_argument('--buildinstall-method',
choices=['lorax', 'buildinstall'],
help='how was the boot.iso created for bootable products')
parser.add_argument('--arch', required=True,
help='what arch are we building the ISO for')
parser.add_argument('--supported', action='store_true',
help='supported flag for implantisomd5')
parser.add_argument('--jigdo-dir',
help='where to put jigdo files')
parser.add_argument('--os-tree',
help='where to put jigdo files')
opts = parser.parse_args(args)
if bool(opts.jigdo_dir) != bool(opts.os_tree): if bool(opts.jigdo_dir) != bool(opts.os_tree):
parser.error('--jigdo-dir must be used together with --os-tree') raise RuntimeError('jigdo_dir must be used together with os_tree')
run(opts)
emit(f, "#!/bin/bash")
emit(f, "set -ex")
emit(f, "cd %s" % opts.output_dir)
iso = IsoWrapper()
make_image(f, iso, opts)
run_isohybrid(f, iso, opts)
implant_md5(f, iso, opts)
make_manifest(f, iso, opts)
if opts.jigdo_dir:
make_jigdo(f, opts)

View File

@ -35,6 +35,8 @@ from pungi.util import (makedirs, get_volid, get_arch_variant_data, failable,
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 .. import createiso
class CreateisoPhase(PhaseBase): class CreateisoPhase(PhaseBase):
name = "createiso" name = "createiso"
@ -125,30 +127,27 @@ class CreateisoPhase(PhaseBase):
cmd["mount"] = os.path.abspath(os.path.join(os.path.dirname(iso_dir), cmd["mount"] = os.path.abspath(os.path.join(os.path.dirname(iso_dir),
os.readlink(iso_dir))) os.readlink(iso_dir)))
cmd['cmd'] = [ opts = createiso.CreateIsoOpts(
'pungi-createiso', output_dir=iso_dir,
'--output-dir=%s' % iso_dir, iso_name=filename,
'--iso-name=%s' % filename, volid=volid,
'--volid=%s' % volid, graft_points=graft_points,
'--graft-points=%s' % graft_points, arch=arch,
'--arch=%s' % arch, supported=self.compose.supported,
] )
if bootable: if bootable:
cmd['cmd'].append( opts = opts._replace(buildinstall_method=self.compose.conf['buildinstall_method'])
'--buildinstall-method=%s' % self.compose.conf['buildinstall_method']
)
if self.compose.supported:
cmd['cmd'].append('--supported')
if self.compose.conf.get('create_jigdo', True): if self.compose.conf.get('create_jigdo', True):
jigdo_dir = self.compose.paths.compose.jigdo_dir(arch, variant) jigdo_dir = self.compose.paths.compose.jigdo_dir(arch, variant)
cmd['cmd'].extend([ opts = opts._replace(jigdo_dir=jigdo_dir, os_tree=os_tree)
'--jigdo-dir=%s' % jigdo_dir,
'--os-tree=%s' % os_tree,
])
script_file = os.path.join(self.compose.paths.work.tmp_dir(arch, variant),
'createiso-%s.sh' % filename)
with open(script_file, 'w') as f:
createiso.write_script(opts, f)
cmd['cmd'] = ['bash', script_file]
commands.append((cmd, variant, arch)) commands.append((cmd, variant, arch))
if self.compose.notifier: if self.compose.notifier:
@ -203,7 +202,9 @@ class CreateIsoThread(WorkerThread):
if runroot: if runroot:
# run in a koji build root # run in a koji build root
packages = ["coreutils", "genisoimage", "isomd5sum", "jigdo", "pungi"] packages = ["coreutils", "genisoimage", "isomd5sum"]
if compose.conf.get('create_jigdo', True):
packages.append('jigdo')
extra_packages = { extra_packages = {
'lorax': ['lorax'], 'lorax': ['lorax'],
'buildinstall': ['anaconda'], 'buildinstall': ['anaconda'],

View File

@ -41,7 +41,6 @@ setup(
'bin/pungi-fedmsg-notification', 'bin/pungi-fedmsg-notification',
'bin/pungi-koji', 'bin/pungi-koji',
'bin/pungi-make-ostree', 'bin/pungi-make-ostree',
'bin/pungi-pylorax-find-templates',
], ],
data_files = [ data_files = [
('/usr/share/pungi', glob.glob('share/*.xsl')), ('/usr/share/pungi', glob.glob('share/*.xsl')),

View File

@ -14,6 +14,7 @@ import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from tests import helpers from tests import helpers
from pungi.createiso import CreateIsoOpts
from pungi.phases import createiso from pungi.phases import createiso
@ -64,10 +65,11 @@ class CreateisoPhaseTest(helpers.PungiTestCase):
mock.call('No RPMs found for Server.src, skipping ISO')] mock.call('No RPMs found for Server.src, skipping ISO')]
) )
@mock.patch('pungi.createiso.write_script')
@mock.patch('pungi.phases.createiso.prepare_iso') @mock.patch('pungi.phases.createiso.prepare_iso')
@mock.patch('pungi.phases.createiso.split_iso') @mock.patch('pungi.phases.createiso.split_iso')
@mock.patch('pungi.phases.createiso.ThreadPool') @mock.patch('pungi.phases.createiso.ThreadPool')
def test_start_one_worker(self, ThreadPool, split_iso, prepare_iso): def test_start_one_worker(self, ThreadPool, split_iso, prepare_iso, write_script):
compose = helpers.DummyCompose(self.topdir, { compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test', 'release_short': 'test',
'release_version': '1.0', 'release_version': '1.0',
@ -94,6 +96,17 @@ class CreateisoPhaseTest(helpers.PungiTestCase):
[mock.call(compose, 'x86_64', compose.variants['Server'])]) [mock.call(compose, 'x86_64', compose.variants['Server'])])
self.assertEqual(len(pool.add.call_args_list), 1) self.assertEqual(len(pool.add.call_args_list), 1)
self.maxDiff = None self.maxDiff = None
self.assertItemsEqual(
[x[0][0] for x in write_script.call_args_list],
[CreateIsoOpts(
output_dir='%s/compose/Server/x86_64/iso' % self.topdir,
iso_name='image-name',
volid='test-1.0 Server.x86_64',
graft_points='dummy-graft-points',
arch='x86_64',
supported=True,
jigdo_dir='%s/compose/Server/x86_64/jigdo' % self.topdir,
os_tree='%s/compose/Server/x86_64/os' % self.topdir)])
self.assertItemsEqual( self.assertItemsEqual(
pool.queue_put.call_args_list, pool.queue_put.call_args_list,
[mock.call(( [mock.call((
@ -101,13 +114,7 @@ class CreateisoPhaseTest(helpers.PungiTestCase):
{ {
'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir, 'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir,
'bootable': False, 'bootable': False,
'cmd': ['pungi-createiso', 'cmd': ['bash', self.topdir + '/work/x86_64/tmp-Server/createiso-image-name.sh'],
'--output-dir=%s/compose/Server/x86_64/iso' % self.topdir,
'--iso-name=image-name', '--volid=test-1.0 Server.x86_64',
'--graft-points=dummy-graft-points',
'--arch=x86_64', '--supported',
'--jigdo-dir=%s/compose/Server/x86_64/jigdo' % self.topdir,
'--os-tree=%s/compose/Server/x86_64/os' % self.topdir],
'label': '', 'label': '',
'disc_num': 1, 'disc_num': 1,
'disc_count': 1, 'disc_count': 1,
@ -117,18 +124,18 @@ class CreateisoPhaseTest(helpers.PungiTestCase):
))] ))]
) )
@mock.patch('pungi.createiso.write_script')
@mock.patch('pungi.phases.createiso.prepare_iso') @mock.patch('pungi.phases.createiso.prepare_iso')
@mock.patch('pungi.phases.createiso.split_iso') @mock.patch('pungi.phases.createiso.split_iso')
@mock.patch('pungi.phases.createiso.ThreadPool') @mock.patch('pungi.phases.createiso.ThreadPool')
def test_bootable(self, ThreadPool, split_iso, prepare_iso): def test_bootable(self, ThreadPool, split_iso, prepare_iso, write_script):
compose = helpers.DummyCompose(self.topdir, { compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test', 'release_short': 'test',
'release_version': '1.0', 'release_version': '1.0',
'release_is_layered': False, 'release_is_layered': False,
'buildinstall_method': 'lorax', 'buildinstall_method': 'lorax',
'bootable': True, 'bootable': True,
'createiso_skip': [ 'createiso_skip': []
]
}) })
helpers.touch(os.path.join( helpers.touch(os.path.join(
compose.paths.compose.os_tree('x86_64', compose.variants['Server']), compose.paths.compose.os_tree('x86_64', compose.variants['Server']),
@ -157,20 +164,31 @@ class CreateisoPhaseTest(helpers.PungiTestCase):
mock.call(compose, 'src', compose.variants['Server'])]) mock.call(compose, 'src', compose.variants['Server'])])
self.assertEqual(len(pool.add.call_args_list), 2) self.assertEqual(len(pool.add.call_args_list), 2)
self.maxDiff = None self.maxDiff = None
self.assertItemsEqual(
[x[0][0] for x in write_script.call_args_list],
[CreateIsoOpts(output_dir='%s/compose/Server/x86_64/iso' % self.topdir,
iso_name='image-name',
volid='test-1.0 Server.x86_64',
graft_points='dummy-graft-points',
arch='x86_64',
buildinstall_method='lorax',
supported=True,
jigdo_dir='%s/compose/Server/x86_64/jigdo' % self.topdir,
os_tree='%s/compose/Server/x86_64/os' % self.topdir),
CreateIsoOpts(output_dir='%s/compose/Server/source/iso' % self.topdir,
iso_name='image-name',
volid='test-1.0 Server.src',
graft_points='dummy-graft-points',
arch='src',
supported=True,
jigdo_dir='%s/compose/Server/source/jigdo' % self.topdir,
os_tree='%s/compose/Server/source/tree' % self.topdir)])
self.assertItemsEqual( self.assertItemsEqual(
pool.queue_put.call_args_list, pool.queue_put.call_args_list,
[mock.call((compose, [mock.call((compose,
{'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir, {'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir,
'bootable': True, 'bootable': True,
'cmd': ['pungi-createiso', 'cmd': ['bash', self.topdir + '/work/x86_64/tmp-Server/createiso-image-name.sh'],
'--output-dir=%s/compose/Server/x86_64/iso' % self.topdir,
'--iso-name=image-name', '--volid=test-1.0 Server.x86_64',
'--graft-points=dummy-graft-points',
'--arch=x86_64',
'--buildinstall-method=lorax',
'--supported',
'--jigdo-dir=%s/compose/Server/x86_64/jigdo' % self.topdir,
'--os-tree=%s/compose/Server/x86_64/os' % self.topdir],
'label': '', 'label': '',
'disc_num': 1, 'disc_num': 1,
'disc_count': 1}, 'disc_count': 1},
@ -179,13 +197,7 @@ class CreateisoPhaseTest(helpers.PungiTestCase):
mock.call((compose, mock.call((compose,
{'iso_path': '%s/compose/Server/source/iso/image-name' % self.topdir, {'iso_path': '%s/compose/Server/source/iso/image-name' % self.topdir,
'bootable': False, 'bootable': False,
'cmd': ['pungi-createiso', 'cmd': ['bash', self.topdir + '/work/src/tmp-Server/createiso-image-name.sh'],
'--output-dir=%s/compose/Server/source/iso' % self.topdir,
'--iso-name=image-name', '--volid=test-1.0 Server.src',
'--graft-points=dummy-graft-points',
'--arch=src', '--supported',
'--jigdo-dir=%s/compose/Server/source/jigdo' % self.topdir,
'--os-tree=%s/compose/Server/source/tree' % self.topdir],
'label': '', 'label': '',
'disc_num': 1, 'disc_num': 1,
'disc_count': 1}, 'disc_count': 1},
@ -238,7 +250,7 @@ class CreateisoThreadTest(helpers.PungiTestCase):
[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],
packages=['coreutils', 'genisoimage', 'isomd5sum', packages=['coreutils', 'genisoimage', 'isomd5sum',
'jigdo', 'pungi'], 'jigdo'],
task_id=True, use_shell=True)]) task_id=True, use_shell=True)])
self.assertEqual( self.assertEqual(
run_runroot.call_args_list, run_runroot.call_args_list,
@ -272,6 +284,7 @@ class CreateisoThreadTest(helpers.PungiTestCase):
'runroot': True, 'runroot': True,
'runroot_tag': 'f25-build', 'runroot_tag': 'f25-build',
'koji_profile': 'koji', 'koji_profile': 'koji',
'create_jigdo': False,
}) })
cmd = { cmd = {
'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir, 'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir,
@ -301,8 +314,7 @@ class CreateisoThreadTest(helpers.PungiTestCase):
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],
packages=['coreutils', 'genisoimage', 'isomd5sum', packages=['coreutils', 'genisoimage', 'isomd5sum'],
'jigdo', 'pungi'],
task_id=True, use_shell=True)]) task_id=True, use_shell=True)])
self.assertEqual( self.assertEqual(
run_runroot.call_args_list, run_runroot.call_args_list,
@ -368,7 +380,7 @@ class CreateisoThreadTest(helpers.PungiTestCase):
[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],
packages=['coreutils', 'genisoimage', 'isomd5sum', packages=['coreutils', 'genisoimage', 'isomd5sum',
'jigdo', 'pungi', 'lorax'], 'jigdo', 'lorax'],
task_id=True, use_shell=True)]) task_id=True, use_shell=True)])
self.assertEqual( self.assertEqual(
run_runroot.call_args_list, run_runroot.call_args_list,

View File

@ -6,6 +6,7 @@ import mock
import os import os
import sys import sys
import StringIO
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
@ -15,224 +16,183 @@ from pungi import createiso
class CreateIsoScriptTest(helpers.PungiTestCase): class CreateIsoScriptTest(helpers.PungiTestCase):
def assertEqualCalls(self, actual, expected):
self.assertEqual(len(actual), len(expected))
for x, y in zip(actual, expected):
self.assertEqual(x, y)
def setUp(self): def setUp(self):
super(CreateIsoScriptTest, self).setUp() super(CreateIsoScriptTest, self).setUp()
self.outdir = os.path.join(self.topdir, 'isos') self.outdir = os.path.join(self.topdir, 'isos')
self.out = StringIO.StringIO()
@mock.patch('kobo.shortcuts.run')
def test_minimal_run(self, run):
createiso.main([
'--output-dir=%s' % self.outdir,
'--iso-name=DP-1.0-20160405.t.3-x86_64.iso',
'--volid=DP-1.0-20160405.t.3',
'--graft-points=graft-list',
'--arch=x86_64',
])
self.maxDiff = None self.maxDiff = None
self.assertEqual(
run.call_args_list, def assertScript(self, cmds):
[mock.call(['/usr/bin/genisoimage', '-untranslated-filenames', script = self.out.getvalue().strip().split('\n')
'-volid', 'DP-1.0-20160405.t.3', '-J', '-joliet-long', self.assertEqual(script[:3],
'-rational-rock', '-translation-table', ['#!/bin/bash',
'-input-charset', 'utf-8', '-x', './lost+found', 'set -ex',
'-o', 'DP-1.0-20160405.t.3-x86_64.iso', 'cd %s' % self.outdir])
'-graft-points', '-path-list', 'graft-list'], self.assertEqual(script[3:], cmds)
show_cmd=True, stdout=True, workdir=self.outdir),
mock.call(['/usr/bin/implantisomd5', 'DP-1.0-20160405.t.3-x86_64.iso'], def test_minimal_run(self):
show_cmd=True, stdout=True, workdir=self.outdir), createiso.write_script(createiso.CreateIsoOpts(
mock.call('isoinfo -R -f -i DP-1.0-20160405.t.3-x86_64.iso | grep -v \'/TRANS.TBL$\' | sort >> DP-1.0-20160405.t.3-x86_64.iso.manifest', output_dir=self.outdir,
show_cmd=True, stdout=True, workdir=self.outdir)] iso_name='DP-1.0-20160405.t.3-x86_64.iso',
volid='DP-1.0-20160405.t.3',
graft_points='graft-list',
arch='x86_64',
), self.out)
self.assertScript(
[' '.join(['/usr/bin/genisoimage', '-untranslated-filenames',
'-volid', 'DP-1.0-20160405.t.3', '-J', '-joliet-long',
'-rational-rock', '-translation-table',
'-input-charset', 'utf-8', '-x', './lost+found',
'-o', 'DP-1.0-20160405.t.3-x86_64.iso',
'-graft-points', '-path-list', 'graft-list']),
' '.join(['/usr/bin/implantisomd5', 'DP-1.0-20160405.t.3-x86_64.iso']),
'isoinfo -R -f -i DP-1.0-20160405.t.3-x86_64.iso | grep -v \'/TRANS.TBL$\' | sort >> DP-1.0-20160405.t.3-x86_64.iso.manifest']
) )
@mock.patch('kobo.shortcuts.run') def test_bootable_run(self):
def test_bootable_run(self, run): createiso.write_script(createiso.CreateIsoOpts(
run.return_value = (0, '/usr/share/lorax') output_dir=self.outdir,
iso_name='DP-1.0-20160405.t.3-x86_64.iso',
volid='DP-1.0-20160405.t.3',
graft_points='graft-list',
arch='x86_64',
buildinstall_method='lorax',
), self.out)
createiso.main([ self.assertScript(
'--output-dir=%s' % self.outdir, [createiso.FIND_TEMPLATE_SNIPPET,
'--iso-name=DP-1.0-20160405.t.3-x86_64.iso', ' '.join(['/usr/bin/genisoimage', '-untranslated-filenames',
'--volid=DP-1.0-20160405.t.3', '-volid', 'DP-1.0-20160405.t.3', '-J', '-joliet-long',
'--graft-points=graft-list', '-rational-rock', '-translation-table',
'--arch=x86_64', '-input-charset', 'utf-8', '-x', './lost+found',
'--buildinstall-method=lorax', '-b', 'isolinux/isolinux.bin', '-c', 'isolinux/boot.cat',
]) '-no-emul-boot',
'-boot-load-size', '4', '-boot-info-table',
self.maxDiff = None '-eltorito-alt-boot', '-e', 'images/efiboot.img',
self.assertItemsEqual( '-no-emul-boot',
run.call_args_list, '-o', 'DP-1.0-20160405.t.3-x86_64.iso',
[mock.call(['/usr/bin/genisoimage', '-untranslated-filenames', '-graft-points', '-path-list', 'graft-list']),
'-volid', 'DP-1.0-20160405.t.3', '-J', '-joliet-long', ' '.join(['/usr/bin/isohybrid', '--uefi', 'DP-1.0-20160405.t.3-x86_64.iso']),
'-rational-rock', '-translation-table', ' '.join(['/usr/bin/implantisomd5', 'DP-1.0-20160405.t.3-x86_64.iso']),
'-input-charset', 'utf-8', '-x', './lost+found', 'isoinfo -R -f -i DP-1.0-20160405.t.3-x86_64.iso | grep -v \'/TRANS.TBL$\' | sort >> DP-1.0-20160405.t.3-x86_64.iso.manifest']
'-b', 'isolinux/isolinux.bin', '-c', 'isolinux/boot.cat',
'-no-emul-boot',
'-boot-load-size', '4', '-boot-info-table',
'-eltorito-alt-boot', '-e', 'images/efiboot.img',
'-no-emul-boot',
'-o', 'DP-1.0-20160405.t.3-x86_64.iso',
'-graft-points', '-path-list', 'graft-list'],
show_cmd=True, stdout=True, workdir=self.outdir),
mock.call(['pungi-pylorax-find-templates', '/usr/share/lorax'],
show_cmd=True, stdout=True),
mock.call(['/usr/bin/isohybrid', '--uefi', 'DP-1.0-20160405.t.3-x86_64.iso'],
show_cmd=True, stdout=True, workdir=self.outdir),
mock.call(['/usr/bin/implantisomd5', 'DP-1.0-20160405.t.3-x86_64.iso'],
show_cmd=True, stdout=True, workdir=self.outdir),
mock.call('isoinfo -R -f -i DP-1.0-20160405.t.3-x86_64.iso | grep -v \'/TRANS.TBL$\' | sort >> DP-1.0-20160405.t.3-x86_64.iso.manifest',
show_cmd=True, stdout=True, workdir=self.outdir)]
) )
@mock.patch('kobo.shortcuts.run') def test_bootable_run_on_i386(self):
def test_bootable_run_on_i386(self, run):
# This will call isohybrid, but not with --uefi switch # This will call isohybrid, but not with --uefi switch
run.return_value = (0, '/usr/share/lorax') createiso.write_script(createiso.CreateIsoOpts(
output_dir=self.outdir,
iso_name='DP-1.0-20160405.t.3-i386.iso',
volid='DP-1.0-20160405.t.3',
graft_points='graft-list',
arch='i386',
buildinstall_method='lorax',
), self.out)
createiso.main([ self.assertScript(
'--output-dir=%s' % self.outdir, [createiso.FIND_TEMPLATE_SNIPPET,
'--iso-name=DP-1.0-20160405.t.3-i386.iso', ' '.join(['/usr/bin/genisoimage', '-untranslated-filenames',
'--volid=DP-1.0-20160405.t.3', '-volid', 'DP-1.0-20160405.t.3', '-J', '-joliet-long',
'--graft-points=graft-list', '-rational-rock', '-translation-table',
'--arch=i386', '-input-charset', 'utf-8', '-x', './lost+found',
'--buildinstall-method=lorax', '-b', 'isolinux/isolinux.bin', '-c', 'isolinux/boot.cat',
]) '-no-emul-boot',
'-boot-load-size', '4', '-boot-info-table',
self.maxDiff = None '-o', 'DP-1.0-20160405.t.3-i386.iso',
self.assertItemsEqual( '-graft-points', '-path-list', 'graft-list']),
run.call_args_list, ' '.join(['/usr/bin/isohybrid', 'DP-1.0-20160405.t.3-i386.iso']),
[mock.call(['/usr/bin/genisoimage', '-untranslated-filenames', ' '.join(['/usr/bin/implantisomd5', 'DP-1.0-20160405.t.3-i386.iso']),
'-volid', 'DP-1.0-20160405.t.3', '-J', '-joliet-long', 'isoinfo -R -f -i DP-1.0-20160405.t.3-i386.iso | grep -v \'/TRANS.TBL$\' | sort >> DP-1.0-20160405.t.3-i386.iso.manifest']
'-rational-rock', '-translation-table',
'-input-charset', 'utf-8', '-x', './lost+found',
'-b', 'isolinux/isolinux.bin', '-c', 'isolinux/boot.cat',
'-no-emul-boot',
'-boot-load-size', '4', '-boot-info-table',
'-o', 'DP-1.0-20160405.t.3-i386.iso',
'-graft-points', '-path-list', 'graft-list'],
show_cmd=True, stdout=True, workdir=self.outdir),
mock.call(['pungi-pylorax-find-templates', '/usr/share/lorax'],
show_cmd=True, stdout=True),
mock.call(['/usr/bin/isohybrid', 'DP-1.0-20160405.t.3-i386.iso'],
show_cmd=True, stdout=True, workdir=self.outdir),
mock.call(['/usr/bin/implantisomd5', 'DP-1.0-20160405.t.3-i386.iso'],
show_cmd=True, stdout=True, workdir=self.outdir),
mock.call('isoinfo -R -f -i DP-1.0-20160405.t.3-i386.iso | grep -v \'/TRANS.TBL$\' | sort >> DP-1.0-20160405.t.3-i386.iso.manifest',
show_cmd=True, stdout=True, workdir=self.outdir)]
) )
@mock.patch('kobo.shortcuts.run') def test_bootable_run_ppc64(self):
def test_bootable_run_ppc64(self, run): createiso.write_script(createiso.CreateIsoOpts(
run.return_value = (0, '/usr/share/lorax') output_dir=self.outdir,
iso_name='DP-1.0-20160405.t.3-ppc64.iso',
volid='DP-1.0-20160405.t.3',
graft_points='graft-list',
arch='ppc64',
buildinstall_method='lorax',
), self.out)
createiso.main([ self.assertScript(
'--output-dir=%s' % self.outdir, [createiso.FIND_TEMPLATE_SNIPPET,
'--iso-name=DP-1.0-20160405.t.3-ppc64.iso', ' '.join(['/usr/bin/genisoimage', '-untranslated-filenames',
'--volid=DP-1.0-20160405.t.3', '-volid', 'DP-1.0-20160405.t.3', '-J', '-joliet-long',
'--graft-points=graft-list', '-rational-rock', '-translation-table',
'--arch=ppc64', '-x', './lost+found',
'--buildinstall-method=lorax', '-part', '-hfs', '-r', '-l', '-sysid', 'PPC', '-no-desktop',
]) '-allow-multidot', '-chrp-boot', '-map', '$TEMPLATE/config_files/ppc/mapping',
'-hfs-bless', '/ppc/mac',
self.maxDiff = None '-o', 'DP-1.0-20160405.t.3-ppc64.iso',
self.assertItemsEqual( '-graft-points', '-path-list', 'graft-list']),
run.call_args_list, ' '.join(['/usr/bin/implantisomd5', 'DP-1.0-20160405.t.3-ppc64.iso']),
[mock.call(['/usr/bin/genisoimage', '-untranslated-filenames', 'isoinfo -R -f -i DP-1.0-20160405.t.3-ppc64.iso | grep -v \'/TRANS.TBL$\' | sort >> DP-1.0-20160405.t.3-ppc64.iso.manifest']
'-volid', 'DP-1.0-20160405.t.3', '-J', '-joliet-long',
'-rational-rock', '-translation-table',
'-x', './lost+found',
'-part', '-hfs', '-r', '-l', '-sysid', 'PPC', '-no-desktop',
'-allow-multidot', '-chrp-boot', '-map', '/usr/share/lorax/config_files/ppc/mapping',
'-hfs-bless', '/ppc/mac',
'-o', 'DP-1.0-20160405.t.3-ppc64.iso',
'-graft-points', '-path-list', 'graft-list'],
show_cmd=True, stdout=True, workdir=self.outdir),
mock.call(['pungi-pylorax-find-templates', '/usr/share/lorax'],
show_cmd=True, stdout=True),
mock.call(['/usr/bin/implantisomd5', 'DP-1.0-20160405.t.3-ppc64.iso'],
show_cmd=True, stdout=True, workdir=self.outdir),
mock.call('isoinfo -R -f -i DP-1.0-20160405.t.3-ppc64.iso | grep -v \'/TRANS.TBL$\' | sort >> DP-1.0-20160405.t.3-ppc64.iso.manifest',
show_cmd=True, stdout=True, workdir=self.outdir)]
) )
@mock.patch('kobo.shortcuts.run') def test_bootable_run_buildinstall(self):
def test_bootable_run_buildinstall(self, run): createiso.write_script(createiso.CreateIsoOpts(
createiso.main([ output_dir=self.outdir,
'--output-dir=%s' % self.outdir, iso_name='DP-1.0-20160405.t.3-ppc64.iso',
'--iso-name=DP-1.0-20160405.t.3-ppc64.iso', volid='DP-1.0-20160405.t.3',
'--volid=DP-1.0-20160405.t.3', graft_points='graft-list',
'--graft-points=graft-list', arch='ppc64',
'--arch=ppc64', buildinstall_method='buildinstall',
'--buildinstall-method=buildinstall', ), self.out)
])
self.maxDiff = None self.assertScript(
self.assertItemsEqual( [' '.join(['/usr/bin/genisoimage', '-untranslated-filenames',
run.call_args_list, '-volid', 'DP-1.0-20160405.t.3', '-J', '-joliet-long',
[mock.call(['/usr/bin/genisoimage', '-untranslated-filenames', '-rational-rock', '-translation-table',
'-volid', 'DP-1.0-20160405.t.3', '-J', '-joliet-long', '-x', './lost+found',
'-rational-rock', '-translation-table', '-part', '-hfs', '-r', '-l', '-sysid', 'PPC', '-no-desktop',
'-x', './lost+found', '-allow-multidot', '-chrp-boot',
'-part', '-hfs', '-r', '-l', '-sysid', 'PPC', '-no-desktop', '-map', '/usr/lib/anaconda-runtime/boot/mapping',
'-allow-multidot', '-chrp-boot', '-hfs-bless', '/ppc/mac',
'-map', '/usr/lib/anaconda-runtime/boot/mapping', '-o', 'DP-1.0-20160405.t.3-ppc64.iso',
'-hfs-bless', '/ppc/mac', '-graft-points', '-path-list', 'graft-list']),
'-o', 'DP-1.0-20160405.t.3-ppc64.iso', ' '.join(['/usr/bin/implantisomd5', 'DP-1.0-20160405.t.3-ppc64.iso']),
'-graft-points', '-path-list', 'graft-list'], 'isoinfo -R -f -i DP-1.0-20160405.t.3-ppc64.iso | grep -v \'/TRANS.TBL$\' | sort >> DP-1.0-20160405.t.3-ppc64.iso.manifest']
show_cmd=True, stdout=True, workdir=self.outdir),
mock.call(['/usr/bin/implantisomd5', 'DP-1.0-20160405.t.3-ppc64.iso'],
show_cmd=True, stdout=True, workdir=self.outdir),
mock.call('isoinfo -R -f -i DP-1.0-20160405.t.3-ppc64.iso | grep -v \'/TRANS.TBL$\' | sort >> DP-1.0-20160405.t.3-ppc64.iso.manifest',
show_cmd=True, stdout=True, workdir=self.outdir)]
) )
@mock.patch('sys.stderr') @mock.patch('sys.stderr')
@mock.patch('kobo.shortcuts.run') @mock.patch('kobo.shortcuts.run')
def test_run_with_jigdo_bad_args(self, run, stderr): def test_run_with_jigdo_bad_args(self, run, stderr):
with self.assertRaises(SystemExit): with self.assertRaises(RuntimeError):
createiso.main([ createiso.write_script(createiso.CreateIsoOpts(
'--output-dir=%s' % self.outdir, output_dir=self.outdir,
'--iso-name=DP-1.0-20160405.t.3-x86_64.iso', iso_name='DP-1.0-20160405.t.3-x86_64.iso',
'--volid=DP-1.0-20160405.t.3', volid='DP-1.0-20160405.t.3',
'--graft-points=graft-list', graft_points='graft-list',
'--arch=x86_64', arch='x86_64',
'--jigdo-dir=%s/jigdo' % self.topdir, jigdo_dir='%s/jigdo' % self.topdir,
]) ), self.out)
@mock.patch('kobo.shortcuts.run') @mock.patch('kobo.shortcuts.run')
def test_run_with_jigdo(self, run): def test_run_with_jigdo(self, run):
createiso.main([ createiso.write_script(createiso.CreateIsoOpts(
'--output-dir=%s' % self.outdir, output_dir=self.outdir,
'--iso-name=DP-1.0-20160405.t.3-x86_64.iso', iso_name='DP-1.0-20160405.t.3-x86_64.iso',
'--volid=DP-1.0-20160405.t.3', volid='DP-1.0-20160405.t.3',
'--graft-points=graft-list', graft_points='graft-list',
'--arch=x86_64', arch='x86_64',
'--jigdo-dir=%s/jigdo' % self.topdir, jigdo_dir='%s/jigdo' % self.topdir,
'--os-tree=%s/os' % self.topdir, os_tree='%s/os' % self.topdir,
]) ), self.out)
self.maxDiff = None
self.assertItemsEqual( self.assertScript(
run.call_args_list, [' '.join(['/usr/bin/genisoimage', '-untranslated-filenames',
[mock.call(['/usr/bin/genisoimage', '-untranslated-filenames', '-volid', 'DP-1.0-20160405.t.3', '-J', '-joliet-long',
'-volid', 'DP-1.0-20160405.t.3', '-J', '-joliet-long', '-rational-rock', '-translation-table',
'-rational-rock', '-translation-table', '-input-charset', 'utf-8', '-x', './lost+found',
'-input-charset', 'utf-8', '-x', './lost+found', '-o', 'DP-1.0-20160405.t.3-x86_64.iso',
'-o', 'DP-1.0-20160405.t.3-x86_64.iso', '-graft-points', '-path-list', 'graft-list']),
'-graft-points', '-path-list', 'graft-list'], ' '.join(['/usr/bin/implantisomd5', 'DP-1.0-20160405.t.3-x86_64.iso']),
show_cmd=True, stdout=True, workdir=self.outdir), 'isoinfo -R -f -i DP-1.0-20160405.t.3-x86_64.iso | grep -v \'/TRANS.TBL$\' | sort >> DP-1.0-20160405.t.3-x86_64.iso.manifest',
mock.call(['/usr/bin/implantisomd5', 'DP-1.0-20160405.t.3-x86_64.iso'], ' '.join(['jigdo-file', 'make-template', '--force',
show_cmd=True, stdout=True, workdir=self.outdir), '--image=%s/isos/DP-1.0-20160405.t.3-x86_64.iso' % self.topdir,
mock.call('isoinfo -R -f -i DP-1.0-20160405.t.3-x86_64.iso | grep -v \'/TRANS.TBL$\' | sort >> DP-1.0-20160405.t.3-x86_64.iso.manifest', '--jigdo=%s/jigdo/DP-1.0-20160405.t.3-x86_64.iso.jigdo' % self.topdir,
show_cmd=True, stdout=True, workdir=self.outdir), '--template=%s/jigdo/DP-1.0-20160405.t.3-x86_64.iso.template' % self.topdir,
mock.call(['jigdo-file', 'make-template', '--force', '--no-servers-section', '--report=noprogress', self.topdir + '/os//'])]
'--image=%s/isos/DP-1.0-20160405.t.3-x86_64.iso' % self.topdir,
'--jigdo=%s/jigdo/DP-1.0-20160405.t.3-x86_64.iso.jigdo' % self.topdir,
'--template=%s/jigdo/DP-1.0-20160405.t.3-x86_64.iso.template' % self.topdir,
'--no-servers-section', '--report=noprogress', self.topdir + '/os//'],
show_cmd=True, stdout=True, workdir=self.outdir)]
) )