From 13ea8e58347170d8cc4856975ceb9f8714dfc9e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Sedl=C3=A1=C5=99?= Date: Mon, 6 Jun 2022 12:33:17 +0200 Subject: [PATCH] Create DVDs with xorriso MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a different approach for building DVDs when xorriso is enabled. The default of using genisoimage is not changed at all. When the config option is set to use xorriso, the actual execution is different between bootable and non-bootable images. The non-bootable images are still created by running xorrisofs (which is a compatibility tool with same UI as genisoimage). Since the image is not bootable, there should be no problems with boot options. For bootable images, Pungi will instead take the boot.iso generated by Lorax, and use xorriso to inject all the extra files into the image. The shell script that used to invoke all the commands to build the ISO now runs the `xorriso` command in interactive mode and feeds another file into it. The new file contains the xorriso commands to add the required files to the image. Signed-off-by: Lubomír Sedlář --- pungi/createiso.py | 33 +++++++++++++++++++++++++++++++-- pungi/phases/createiso.py | 12 +++++++----- pungi/phases/extra_isos.py | 11 ++++++----- tests/test_createiso_phase.py | 8 ++++++++ 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/pungi/createiso.py b/pungi/createiso.py index 4e1a5336..4d80678c 100644 --- a/pungi/createiso.py +++ b/pungi/createiso.py @@ -15,6 +15,7 @@ CreateIsoOpts = namedtuple( "CreateIsoOpts", [ "buildinstall_method", + "boot_iso", "arch", "output_dir", "jigdo_dir", @@ -26,6 +27,7 @@ CreateIsoOpts = namedtuple( "hfs_compat", "use_xorrisofs", "iso_level", + "script_dir", ], ) CreateIsoOpts.__new__.__defaults__ = (None,) * len(CreateIsoOpts._fields) @@ -116,6 +118,27 @@ def make_jigdo(f, opts): emit(f, cmd) +def write_xorriso_commands(opts): + script = os.path.join(opts.script_dir, "xorriso-%s.txt" % id(opts)) + with open(script, "w") as f: + emit(f, "-indev %s" % opts.boot_iso) + emit(f, "-outdev %s" % os.path.join(opts.output_dir, opts.iso_name)) + emit(f, "-boot_image any replay") + emit(f, "-volid %s" % opts.volid) + + with open(opts.graft_points) as gp: + for line in gp: + iso_path, fs_path = line.strip().split("=", 1) + emit(f, "-map %s %s" % (fs_path, iso_path)) + + if opts.arch == "ppc64le": + # This is needed for the image to be bootable. + emit(f, "-as mkisofs -U --") + + emit(f, "-end") + return script + + def write_script(opts, f): if bool(opts.jigdo_dir) != bool(opts.os_tree): raise RuntimeError("jigdo_dir must be used together with os_tree") @@ -123,8 +146,14 @@ def write_script(opts, f): emit(f, "#!/bin/bash") emit(f, "set -ex") emit(f, "cd %s" % opts.output_dir) - make_image(f, opts) - run_isohybrid(f, opts) + + if opts.use_xorrisofs and opts.buildinstall_method: + script = write_xorriso_commands(opts) + emit(f, "xorriso -dialog on <%s" % script) + else: + make_image(f, opts) + run_isohybrid(f, opts) + implant_md5(f, opts) make_manifest(f, opts) if opts.jigdo_dir: diff --git a/pungi/phases/createiso.py b/pungi/phases/createiso.py index e237cf75..722cfb04 100644 --- a/pungi/phases/createiso.py +++ b/pungi/phases/createiso.py @@ -343,7 +343,10 @@ class CreateisoPhase(PhaseLoggerMixin, PhaseBase): if bootable: opts = opts._replace( - buildinstall_method=self.compose.conf["buildinstall_method"] + buildinstall_method=self.compose.conf[ + "buildinstall_method" + ], + boot_iso=os.path.join(os_tree, "images", "boot.iso"), ) if self.compose.conf["create_jigdo"]: @@ -355,10 +358,9 @@ class CreateisoPhase(PhaseLoggerMixin, PhaseBase): # Reuse was successful, go to next ISO continue - script_file = os.path.join( - self.compose.paths.work.tmp_dir(arch, variant), - "createiso-%s.sh" % filename, - ) + script_dir = self.compose.paths.work.tmp_dir(arch, variant) + opts = opts._replace(script_dir=script_dir) + script_file = os.path.join(script_dir, "createiso-%s.sh" % filename) with open(script_file, "w") as f: createiso.write_script(opts, f) cmd["cmd"] = ["bash", script_file] diff --git a/pungi/phases/extra_isos.py b/pungi/phases/extra_isos.py index 56c5f28f..45d06b63 100644 --- a/pungi/phases/extra_isos.py +++ b/pungi/phases/extra_isos.py @@ -132,14 +132,15 @@ class ExtraIsosThread(WorkerThread): use_xorrisofs=compose.conf.get("createiso_use_xorrisofs"), iso_level=compose.conf.get("iso_level"), ) + os_tree = compose.paths.compose.os_tree(arch, variant) if compose.conf["create_jigdo"]: jigdo_dir = compose.paths.compose.jigdo_dir(arch, variant) - os_tree = compose.paths.compose.os_tree(arch, variant) opts = opts._replace(jigdo_dir=jigdo_dir, os_tree=os_tree) if bootable: opts = opts._replace( - buildinstall_method=compose.conf["buildinstall_method"] + buildinstall_method=compose.conf["buildinstall_method"], + boot_iso=os.path.join(os_tree, "images", "boot.iso"), ) # Check if it can be reused. @@ -148,9 +149,9 @@ class ExtraIsosThread(WorkerThread): config_hash = hash.hexdigest() if not self.try_reuse(compose, variant, arch, config_hash, opts): - script_file = os.path.join( - compose.paths.work.tmp_dir(arch, variant), "extraiso-%s.sh" % filename - ) + script_dir = compose.paths.work.tmp_dir(arch, variant) + opts = opts._replace(script_dir=script_dir) + script_file = os.path.join(script_dir, "extraiso-%s.sh" % filename) with open(script_file, "w") as f: createiso.write_script(opts, f) diff --git a/tests/test_createiso_phase.py b/tests/test_createiso_phase.py index fd3c42ec..538cfb2e 100644 --- a/tests/test_createiso_phase.py +++ b/tests/test_createiso_phase.py @@ -124,6 +124,7 @@ class CreateisoPhaseTest(helpers.PungiTestCase): os_tree=None, hfs_compat=True, use_xorrisofs=False, + script_dir="%s/work/x86_64/tmp-Server" % self.topdir, ) ], ) @@ -240,6 +241,9 @@ class CreateisoPhaseTest(helpers.PungiTestCase): [ CreateIsoOpts( output_dir="%s/compose/Server/x86_64/iso" % self.topdir, + boot_iso=( + "%s/compose/Server/x86_64/os/images/boot.iso" % self.topdir + ), iso_name="image-name", volid="test-1.0 Server.x86_64", graft_points="dummy-graft-points", @@ -250,6 +254,7 @@ class CreateisoPhaseTest(helpers.PungiTestCase): os_tree=None, hfs_compat=True, use_xorrisofs=False, + script_dir="%s/work/x86_64/tmp-Server" % self.topdir, ), CreateIsoOpts( output_dir="%s/compose/Server/source/iso" % self.topdir, @@ -262,6 +267,7 @@ class CreateisoPhaseTest(helpers.PungiTestCase): os_tree=None, hfs_compat=True, use_xorrisofs=False, + script_dir="%s/work/src/tmp-Server" % self.topdir, ), ], ) @@ -394,6 +400,7 @@ class CreateisoPhaseTest(helpers.PungiTestCase): os_tree=None, hfs_compat=True, use_xorrisofs=False, + script_dir="%s/work/src/tmp-Server" % self.topdir, ) ], ) @@ -501,6 +508,7 @@ class CreateisoPhaseTest(helpers.PungiTestCase): os_tree=None, hfs_compat=False, use_xorrisofs=False, + script_dir="%s/work/x86_64/tmp-Server" % self.topdir, ) ], )