From f37a14fb60d234c3613039ee3bb64b1bc86a5e7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Sedl=C3=A1=C5=99?= Date: Thu, 28 Jul 2016 13:05:38 +0200 Subject: [PATCH] [createiso] Use shell script for runroot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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ář --- bin/pungi-pylorax-find-templates | 20 -- pungi.spec | 2 - pungi/createiso.py | 121 ++++++----- pungi/phases/createiso.py | 39 ++-- setup.py | 1 - tests/test_createiso_phase.py | 74 ++++--- tests/test_createiso_script.py | 346 ++++++++++++++----------------- 7 files changed, 276 insertions(+), 327 deletions(-) delete mode 100755 bin/pungi-pylorax-find-templates diff --git a/bin/pungi-pylorax-find-templates b/bin/pungi-pylorax-find-templates deleted file mode 100755 index 0fad5d33..00000000 --- a/bin/pungi-pylorax-find-templates +++ /dev/null @@ -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]) diff --git a/pungi.spec b/pungi.spec index 998b2d3a..de9eaf86 100644 --- a/pungi.spec +++ b/pungi.spec @@ -52,8 +52,6 @@ rm -rf %{buildroot} %{__python} setup.py install -O1 --skip-build --root %{buildroot} %{__install} -d %{buildroot}/var/cache/pungi %{__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 %defattr(-,root,root,-) diff --git a/pungi/createiso.py b/pungi/createiso.py index b7d62028..57badaec 100644 --- a/pungi/createiso.py +++ b/pungi/createiso.py @@ -1,31 +1,53 @@ # -*- coding: utf-8 -*- -import argparse +from __future__ import print_function + import os -from kobo import shortcuts +import pipes +from collections import namedtuple from .wrappers.iso import IsoWrapper from .wrappers.jigdo import JigdoWrapper -def find_templates(fallback): - """ - Helper for finding lorax templates. The called program needs to run with - Python 3, while the rest of this script only supports Python 2. - """ - _, output = shortcuts.run(['pungi-pylorax-find-templates', fallback], - stdout=True, show_cmd=True) - return output.strip() +CreateIsoOpts = namedtuple('CreateIsoOpts', + ['buildinstall_method', 'arch', 'output_dir', 'jigdo_dir', + 'iso_name', 'volid', 'graft_points', 'supported', 'os_tree']) +CreateIsoOpts.__new__.__defaults__ = (None,) * len(CreateIsoOpts._fields) -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 = {} if opts.buildinstall_method: if opts.buildinstall_method == 'lorax': - dir = find_templates('/usr/share/lorax') + emit(f, FIND_TEMPLATE_SNIPPET) 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': mkisofs_kwargs["boot_args"] = iso.get_boot_options( 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, exclude=["./lost+found"], 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) - shortcuts.run(cmd, stdout=True, show_cmd=True, workdir=opts.output_dir) + emit(f, cmd) -def run_isohybrid(iso, opts): - """If the image is bootable, it needs to include an MBR or GPT so that it - can actually be booted. This is done by running isohybrid on the image. +def run_isohybrid(f, iso, opts): + """If the image is bootable, it should include an MBR or GPT so that it can + 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"]: 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): - shortcuts.run(iso.get_manifest_cmd(opts.iso_name), stdout=True, - show_cmd=True, workdir=opts.output_dir) +def make_manifest(f, iso, opts): + emit(f, iso.get_manifest_cmd(opts.iso_name)) -def make_jigdo(opts): +def make_jigdo(f, opts): jigdo = JigdoWrapper() files = [ { @@ -71,43 +93,20 @@ def make_jigdo(opts): cmd = jigdo.get_jigdo_cmd(os.path.join(opts.output_dir, opts.iso_name), files, output_dir=opts.jigdo_dir, no_servers=True, report="noprogress") - shortcuts.run(cmd, stdout=True, show_cmd=True, workdir=opts.output_dir) + emit(f, cmd) -def run(opts): - 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) - +def write_script(opts, f): if bool(opts.jigdo_dir) != bool(opts.os_tree): - parser.error('--jigdo-dir must be used together with --os-tree') - run(opts) + raise RuntimeError('jigdo_dir must be used together with os_tree') + + 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) diff --git a/pungi/phases/createiso.py b/pungi/phases/createiso.py index 762a9378..6e63b290 100644 --- a/pungi/phases/createiso.py +++ b/pungi/phases/createiso.py @@ -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.compose_metadata.discinfo import read_discinfo, write_discinfo +from .. import createiso + class CreateisoPhase(PhaseBase): name = "createiso" @@ -125,30 +127,27 @@ class CreateisoPhase(PhaseBase): cmd["mount"] = os.path.abspath(os.path.join(os.path.dirname(iso_dir), os.readlink(iso_dir))) - cmd['cmd'] = [ - 'pungi-createiso', - '--output-dir=%s' % iso_dir, - '--iso-name=%s' % filename, - '--volid=%s' % volid, - '--graft-points=%s' % graft_points, - '--arch=%s' % arch, - ] + opts = createiso.CreateIsoOpts( + output_dir=iso_dir, + iso_name=filename, + volid=volid, + graft_points=graft_points, + arch=arch, + supported=self.compose.supported, + ) if bootable: - cmd['cmd'].append( - '--buildinstall-method=%s' % self.compose.conf['buildinstall_method'] - ) - - if self.compose.supported: - cmd['cmd'].append('--supported') + opts = opts._replace(buildinstall_method=self.compose.conf['buildinstall_method']) if self.compose.conf.get('create_jigdo', True): jigdo_dir = self.compose.paths.compose.jigdo_dir(arch, variant) - cmd['cmd'].extend([ - '--jigdo-dir=%s' % jigdo_dir, - '--os-tree=%s' % os_tree, - ]) + opts = opts._replace(jigdo_dir=jigdo_dir, os_tree=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)) if self.compose.notifier: @@ -203,7 +202,9 @@ class CreateIsoThread(WorkerThread): if runroot: # 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 = { 'lorax': ['lorax'], 'buildinstall': ['anaconda'], diff --git a/setup.py b/setup.py index 1e6c0aae..d14b03ba 100755 --- a/setup.py +++ b/setup.py @@ -41,7 +41,6 @@ setup( 'bin/pungi-fedmsg-notification', 'bin/pungi-koji', 'bin/pungi-make-ostree', - 'bin/pungi-pylorax-find-templates', ], data_files = [ ('/usr/share/pungi', glob.glob('share/*.xsl')), diff --git a/tests/test_createiso_phase.py b/tests/test_createiso_phase.py index c4cd9d9a..ebe1f5af 100755 --- a/tests/test_createiso_phase.py +++ b/tests/test_createiso_phase.py @@ -14,6 +14,7 @@ import sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) from tests import helpers +from pungi.createiso import CreateIsoOpts from pungi.phases import createiso @@ -64,10 +65,11 @@ class CreateisoPhaseTest(helpers.PungiTestCase): 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.split_iso') @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, { 'release_short': 'test', 'release_version': '1.0', @@ -94,6 +96,17 @@ class CreateisoPhaseTest(helpers.PungiTestCase): [mock.call(compose, 'x86_64', compose.variants['Server'])]) self.assertEqual(len(pool.add.call_args_list), 1) 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( pool.queue_put.call_args_list, [mock.call(( @@ -101,13 +114,7 @@ class CreateisoPhaseTest(helpers.PungiTestCase): { 'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir, 'bootable': False, - 'cmd': ['pungi-createiso', - '--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], + 'cmd': ['bash', self.topdir + '/work/x86_64/tmp-Server/createiso-image-name.sh'], 'label': '', 'disc_num': 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.split_iso') @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, { 'release_short': 'test', 'release_version': '1.0', 'release_is_layered': False, 'buildinstall_method': 'lorax', 'bootable': True, - 'createiso_skip': [ - ] + 'createiso_skip': [] }) helpers.touch(os.path.join( 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'])]) self.assertEqual(len(pool.add.call_args_list), 2) 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( pool.queue_put.call_args_list, [mock.call((compose, {'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir, 'bootable': True, - 'cmd': ['pungi-createiso', - '--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], + 'cmd': ['bash', self.topdir + '/work/x86_64/tmp-Server/createiso-image-name.sh'], 'label': '', 'disc_num': 1, 'disc_count': 1}, @@ -179,13 +197,7 @@ class CreateisoPhaseTest(helpers.PungiTestCase): mock.call((compose, {'iso_path': '%s/compose/Server/source/iso/image-name' % self.topdir, 'bootable': False, - 'cmd': ['pungi-createiso', - '--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], + 'cmd': ['bash', self.topdir + '/work/src/tmp-Server/createiso-image-name.sh'], 'label': '', 'disc_num': 1, 'disc_count': 1}, @@ -238,7 +250,7 @@ class CreateisoThreadTest(helpers.PungiTestCase): [mock.call('f25-build', 'x86_64', cmd['cmd'], channel=None, mounts=[self.topdir], packages=['coreutils', 'genisoimage', 'isomd5sum', - 'jigdo', 'pungi'], + 'jigdo'], task_id=True, use_shell=True)]) self.assertEqual( run_runroot.call_args_list, @@ -272,6 +284,7 @@ class CreateisoThreadTest(helpers.PungiTestCase): 'runroot': True, 'runroot_tag': 'f25-build', 'koji_profile': 'koji', + 'create_jigdo': False, }) cmd = { '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, [mock.call('f25-build', 'x86_64', cmd['cmd'], channel=None, mounts=[self.topdir], - packages=['coreutils', 'genisoimage', 'isomd5sum', - 'jigdo', 'pungi'], + packages=['coreutils', 'genisoimage', 'isomd5sum'], task_id=True, use_shell=True)]) self.assertEqual( run_runroot.call_args_list, @@ -368,7 +380,7 @@ class CreateisoThreadTest(helpers.PungiTestCase): [mock.call('f25-build', 'x86_64', cmd['cmd'], channel=None, mounts=[self.topdir], packages=['coreutils', 'genisoimage', 'isomd5sum', - 'jigdo', 'pungi', 'lorax'], + 'jigdo', 'lorax'], task_id=True, use_shell=True)]) self.assertEqual( run_runroot.call_args_list, diff --git a/tests/test_createiso_script.py b/tests/test_createiso_script.py index d214dc7c..834778b2 100755 --- a/tests/test_createiso_script.py +++ b/tests/test_createiso_script.py @@ -6,6 +6,7 @@ import mock import os import sys +import StringIO sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) @@ -15,224 +16,183 @@ from pungi import createiso 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): super(CreateIsoScriptTest, self).setUp() self.outdir = os.path.join(self.topdir, 'isos') - - @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.out = StringIO.StringIO() self.maxDiff = None - self.assertEqual( - run.call_args_list, - [mock.call(['/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'], - 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)] + + def assertScript(self, cmds): + script = self.out.getvalue().strip().split('\n') + self.assertEqual(script[:3], + ['#!/bin/bash', + 'set -ex', + 'cd %s' % self.outdir]) + self.assertEqual(script[3:], cmds) + + def test_minimal_run(self): + createiso.write_script(createiso.CreateIsoOpts( + 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', + ), 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, run): - run.return_value = (0, '/usr/share/lorax') + def test_bootable_run(self): + createiso.write_script(createiso.CreateIsoOpts( + 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([ - '--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', - '--buildinstall-method=lorax', - ]) - - self.maxDiff = None - self.assertItemsEqual( - run.call_args_list, - [mock.call(['/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', - '-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)] + self.assertScript( + [createiso.FIND_TEMPLATE_SNIPPET, + ' '.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', + '-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']), + ' '.join(['/usr/bin/isohybrid', '--uefi', 'DP-1.0-20160405.t.3-x86_64.iso']), + ' '.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_on_i386(self, run): + def test_bootable_run_on_i386(self): # 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([ - '--output-dir=%s' % 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.maxDiff = None - self.assertItemsEqual( - run.call_args_list, - [mock.call(['/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', - '-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)] + self.assertScript( + [createiso.FIND_TEMPLATE_SNIPPET, + ' '.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', + '-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']), + ' '.join(['/usr/bin/isohybrid', 'DP-1.0-20160405.t.3-i386.iso']), + ' '.join(['/usr/bin/implantisomd5', 'DP-1.0-20160405.t.3-i386.iso']), + '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'] ) - @mock.patch('kobo.shortcuts.run') - def test_bootable_run_ppc64(self, run): - run.return_value = (0, '/usr/share/lorax') + def test_bootable_run_ppc64(self): + createiso.write_script(createiso.CreateIsoOpts( + 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([ - '--output-dir=%s' % 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.maxDiff = None - self.assertItemsEqual( - run.call_args_list, - [mock.call(['/usr/bin/genisoimage', '-untranslated-filenames', - '-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)] + self.assertScript( + [createiso.FIND_TEMPLATE_SNIPPET, + ' '.join(['/usr/bin/genisoimage', '-untranslated-filenames', + '-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', '$TEMPLATE/config_files/ppc/mapping', + '-hfs-bless', '/ppc/mac', + '-o', 'DP-1.0-20160405.t.3-ppc64.iso', + '-graft-points', '-path-list', 'graft-list']), + ' '.join(['/usr/bin/implantisomd5', 'DP-1.0-20160405.t.3-ppc64.iso']), + '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'] ) - @mock.patch('kobo.shortcuts.run') - def test_bootable_run_buildinstall(self, run): - createiso.main([ - '--output-dir=%s' % 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=buildinstall', - ]) + def test_bootable_run_buildinstall(self): + createiso.write_script(createiso.CreateIsoOpts( + 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='buildinstall', + ), self.out) - self.maxDiff = None - self.assertItemsEqual( - run.call_args_list, - [mock.call(['/usr/bin/genisoimage', '-untranslated-filenames', - '-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/lib/anaconda-runtime/boot/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(['/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)] + self.assertScript( + [' '.join(['/usr/bin/genisoimage', '-untranslated-filenames', + '-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/lib/anaconda-runtime/boot/mapping', + '-hfs-bless', '/ppc/mac', + '-o', 'DP-1.0-20160405.t.3-ppc64.iso', + '-graft-points', '-path-list', 'graft-list']), + ' '.join(['/usr/bin/implantisomd5', 'DP-1.0-20160405.t.3-ppc64.iso']), + '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'] ) @mock.patch('sys.stderr') @mock.patch('kobo.shortcuts.run') def test_run_with_jigdo_bad_args(self, run, stderr): - with self.assertRaises(SystemExit): - 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', - '--jigdo-dir=%s/jigdo' % self.topdir, - ]) + with self.assertRaises(RuntimeError): + createiso.write_script(createiso.CreateIsoOpts( + 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', + jigdo_dir='%s/jigdo' % self.topdir, + ), self.out) @mock.patch('kobo.shortcuts.run') def test_run_with_jigdo(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', - '--jigdo-dir=%s/jigdo' % self.topdir, - '--os-tree=%s/os' % self.topdir, - ]) - self.maxDiff = None - self.assertItemsEqual( - run.call_args_list, - [mock.call(['/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'], - 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.call(['jigdo-file', 'make-template', '--force', - '--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)] + createiso.write_script(createiso.CreateIsoOpts( + 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', + jigdo_dir='%s/jigdo' % self.topdir, + os_tree='%s/os' % self.topdir, + ), 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', + ' '.join(['jigdo-file', 'make-template', '--force', + '--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//'])] )