diff --git a/pungi/createiso.py b/pungi/createiso.py index c9520d3d..b46afbfe 100644 --- a/pungi/createiso.py +++ b/pungi/createiso.py @@ -121,6 +121,21 @@ def make_jigdo(f, opts): emit(f, cmd) +def _get_perms(fs_path): + """Compute proper permissions for a file. + + This mimicks what -rational-rock option of genisoimage does. All read bits + are set, so that files and directories are globally readable. If any + execute bit is set for a file, set them all. No writes are allowed and + special bits are erased too. + """ + statinfo = os.stat(fs_path) + perms = 0o444 + if statinfo.st_mode & 0o111: + perms |= 0o111 + return perms + + def write_xorriso_commands(opts): # Create manifest for the boot.iso listing all contents boot_iso_manifest = "%s.manifest" % os.path.join( @@ -162,11 +177,14 @@ def write_xorriso_commands(opts): continue cmd = "-update" if iso_path in updated_files else "-map" emit(f, "%s %s %s" % (cmd, fs_path, iso_path)) + emit(f, "-chmod 0%o %s" % (_get_perms(fs_path), iso_path)) if opts.arch == "ppc64le": # This is needed for the image to be bootable. emit(f, "-as mkisofs -U --") + emit(f, "-chown_r 0 /") + emit(f, "-chgrp_r 0 /") emit(f, "-end") return script diff --git a/tests/helpers.py b/tests/helpers.py index 67fd9db2..948b901f 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -272,7 +272,7 @@ class DummyCompose(object): return tempfile.mkdtemp(suffix=suffix, prefix=prefix, dir=self.topdir) -def touch(path, content=None): +def touch(path, content=None, mode=None): """Helper utility that creates an dummy file in given location. Directories will be created.""" content = content or (path + "\n") @@ -284,6 +284,8 @@ def touch(path, content=None): content = content.encode() with open(path, "wb") as f: f.write(content) + if mode: + os.chmod(path, mode) return path diff --git a/tests/test_createiso_script.py b/tests/test_createiso_script.py index c16bc55a..f7e1688a 100644 --- a/tests/test_createiso_script.py +++ b/tests/test_createiso_script.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from unittest import mock +from parameterized import parameterized import os from six.moves import StringIO @@ -391,3 +392,27 @@ class CreateIsoScriptTest(helpers.PungiTestCase): ), ] ) + + @parameterized.expand( + [("644", 0o644), ("664", 0o664), ("666", 0o666), ("2644", 0o2644)] + ) + def test_get_perms_non_executable(self, test_name, mode): + path = helpers.touch(os.path.join(self.topdir, "f"), mode=mode) + self.assertEqual(createiso._get_perms(path), 0o444) + + @parameterized.expand( + [ + ("544", 0o544), + ("554", 0o554), + ("555", 0o555), + ("744", 0o744), + ("755", 0o755), + ("774", 0o774), + ("775", 0o775), + ("777", 0o777), + ("2775", 0o2775), + ] + ) + def test_get_perms_executable(self, test_name, mode): + path = helpers.touch(os.path.join(self.topdir, "f"), mode=mode) + self.assertEqual(createiso._get_perms(path), 0o555)