Blob Blame History Raw
#!/usr/bin/python3
"""
Assemble a Rock Ridge enhanced ISO 9660 filesystem (iso)

Uses the `xorrisofs`(1) command line utility to assemble a
Assemble a Rock Ridge enhanced ISO 9660 filesystem (iso).

The iso can be made bootable by specifying a combination of
`boot` and `efi`. What exact options make sense depend on
the target platform.

The `isolevel` options controls the limits of data size and
filenames: if the iso should contain a  file, like a rootfs
image, that is bigger than 4GB, at least iso level 3 is
required.
"""

import os
import subprocess
import sys

import osbuild.api


SCHEMA_2 = r"""
"options": {
  "additionalProperties": false,
  "required": ["filename", "volid"],
  "properties": {
    "filename": {
      "type": "string",
      "description": "Filename of the iso to create"
    },
    "volid": {
      "type": "string",
      "description": "Volume id to set",
      "pattern": "[A-Z0-9_-]{1,32}"
    },
    "sysid": {
      "type": "string",
      "description": "System id to set",
      "pattern": "[A-Z0-9_-]{1,32}"
    },
    "boot": {
      "type": "object",
      "additionalProperties": false,
      "required": ["image", "catalog"],
      "properties": {
        "image": {
          "type": "string",
          "description": "Path to the boot image (on the iso)"
        },
        "catalog": {
          "type": "string",
          "description": "Path to the boot catalog file (on the iso)"
        }
      }
    },
    "efi": {
      "type": "string"
    },
    "isohybridmbr": {
      "type": "string",
      "description": "Install the argument (buildroot) as ISOLINUX isohybrid MBR"
    },
    "isolevel": {
      "type": "integer",
      "description": "The ISO 9660 version (limits of data size and filenames)",
      "minimum": 1,
      "maximum": 4
    }
  }
},
"inputs": {
  "type": "object",
  "additionalProperties": false,
  "required": ["tree"],
  "properties": {
    "tree": {
      "type": "object",
      "additionalProperties": true
    }
  }
}
"""


def main(inputs, output_dir, options):
    tree = inputs["tree"]["path"]
    boot = options.get("boot", {})
    filename = options["filename"]
    vol_id = options["volid"]
    sys_id = options.get("sysid")
    efi = options.get("efi")
    isohybrid = options.get("isohybridmbr")
    isolevel = options.get("isolevel")

    cmd = [
        "/usr/bin/xorrisofs",
        "-verbose"
    ]

    if isolevel:
        cmd += [
            "-iso-level", str(isolevel)
        ]

    cmd += [
        "-V", vol_id
    ]

    if sys_id:
        cmd += [
            "-sysid", sys_id
        ]

    if isohybrid:
        cmd += [
            "-isohybrid-mbr", isohybrid,
        ]

    if boot:
        image = boot["image"]
        catalog = boot["catalog"]
        cmd += [
            "-b", image,
            "-c", catalog,
            "-boot-load-size", "4",
            "-boot-info-table",
            "-no-emul-boot"
        ]

    cmd += [
        "-rock", "-joliet"
    ]

    if efi:
        cmd += [
            "-eltorito-alt-boot",
            "-e", efi,
            "-no-emul-boot"
        ]

        if isohybrid:
            cmd += ["-isohybrid-gpt-basdat"]

    cmd += [
        '-o', os.path.join(output_dir, filename),
        tree
    ]

    print(cmd)
    subprocess.run(cmd, check=True)


if __name__ == '__main__':
    args = osbuild.api.arguments()
    ret = main(args["inputs"],
               args["tree"],
               args["options"])
    sys.exit(ret)