diff --git a/stages/org.osbuild.coreos.platform b/stages/org.osbuild.coreos.platform new file mode 100755 index 00000000..d2b44d8b --- /dev/null +++ b/stages/org.osbuild.coreos.platform @@ -0,0 +1,116 @@ +#!/usr/bin/python3 +""" +In CoreOS we have the concept of a platform (i.e. AWS, GCP, Metal, QEMU) +where each platform has its own provided disk image with slightly +differing settings/behavior. This stage will perform the necessary +configuration for the given platform. This configuration boils down to +a few steps: +1. Locate the source of platform specific information that is provided + in the CoreOS filesystem tree already (the platforms.json). +2. Copy the platforms.json file into the /boot/ partition, which is + sometimes used by coreos-installer. +3. Read the platforms.json to fetch and platform specific kernel + arguments or grub configuration to set. These arguments/config + are primarily console settings. +4. Apply any platform specific kernel arguments along with the + `ignition.platform.id={platform-name}` kernel argument. +5. Create the grub console.cfg file and apply any platform + specific grub console configuration. +This stage is highly CoreOS specific and subject to change in the +future if/when we change the way platform specific information is +defined in our broader efforts to share more defaults with OSBuild. +""" +import json +import os +import shutil +import sys + +import osbuild.api +from osbuild.util import bls + +SCHEMA_2 = r""" +"options": { + "additionalProperties": false, + "properties": { + "platform": { + "description": "The target platform name/ID", + "type": "string" + } + } +}, +"devices": { + "type": "object", + "additionalProperties": true +}, +"mounts": { + "type": "array" +} +""" + +# Constants +# For console.cfg see https://github.com/coreos/bootupd/pull/620 +# For platforms.json see https://github.com/coreos/coreos-assembler/pull/3709 +GRUB_CONSOLE_CFG = "boot/grub2/console.cfg" +PLATFORMS_JSON_DEST = "boot/coreos/platforms.json" +PLATFORMS_JSON_SOURCE = "usr/share/coreos-assembler/platforms.json" + + +def generate_console_settings_file(console_settings, file_path): + settings_content = "" + if console_settings is not None: + settings_content = "\n".join(console_settings) + file_content = f""" +# Any non-default console settings will be inserted here. +# CONSOLE-SETTINGS-START +{settings_content} +# CONSOLE-SETTINGS-END +""" + with open(file_path, 'w', encoding="utf8") as file: + file.write(file_content) + + +def process_platforms_json(json_file_path, platform): + keys = ["grub_commands", "kernel_arguments"] + result = {} + with open(json_file_path, 'r', encoding="utf8") as file: + data = json.load(file) + if platform in data: + for key in keys: + if key in data[platform]: + result[key] = data[platform][key] + + return result.get("grub_commands", []),\ + result.get("kernel_arguments", []) + + +def main(paths, options): + platform = options.get("platform") + + root = paths["mounts"] + boot_path = os.path.join(root, "boot") + platforms_source_path = os.path.join(root, PLATFORMS_JSON_SOURCE) + platforms_dest_path = os.path.join(root, PLATFORMS_JSON_DEST) + grub_console_cfg_path = os.path.join(root, GRUB_CONSOLE_CFG) + + kernel_arguments = [f"ignition.platform.id={platform}"] + + json_grub_args, json_kargs = None, None + if os.path.exists(platforms_source_path): + os.makedirs(os.path.dirname(platforms_dest_path), mode=0o755, exist_ok=True) + # Copy platforms.json to the boot partition + shutil.copy2(platforms_source_path, platforms_dest_path) + json_grub_args, json_kargs = process_platforms_json(platforms_dest_path, platform) + if json_kargs: + kernel_arguments.extend(json_kargs) + # Write out the GRUB2 console.cfg on all platforms where grub is being used + if os.path.exists(os.path.dirname(grub_console_cfg_path)): + # We add console.cfg file in grub.cfg, that's how the grubconfigs are added + generate_console_settings_file(json_grub_args, grub_console_cfg_path) + # Append kernel arguments in bls entries + bls.options_append(boot_path, kernel_arguments) + + +if __name__ == "__main__": + args = osbuild.api.arguments() + r = main(args["paths"], args["options"]) + sys.exit(r) diff --git a/test/data/manifests/fedora-coreos-container.json b/test/data/manifests/fedora-coreos-container.json index 78885db9..a51f275c 100644 --- a/test/data/manifests/fedora-coreos-container.json +++ b/test/data/manifests/fedora-coreos-container.json @@ -1055,29 +1055,43 @@ } }, { - "type": "org.osbuild.kernel-cmdline.bls-append", + "type": "org.osbuild.coreos.platform", "options": { - "bootpath": "mount:///", - "kernel_opts": [ - "ignition.platform.id=metal" - ] + "platform": "metal" }, "devices": { - "boot": { + "disk": { "type": "org.osbuild.loopback", "options": { "filename": "disk.img", - "start": 264192, - "size": 786432 + "partscan": true } } }, "mounts": [ + { + "name": "root", + "type": "org.osbuild.xfs", + "source": "disk", + "partition": 4, + "target": "/" + }, + { + "name": "ostree.deployment", + "type": "org.osbuild.ostree.deployment", + "options": { + "source": "mount", + "deployment": { + "default": true + } + } + }, { "name": "boot", "type": "org.osbuild.ext4", - "source": "boot", - "target": "/" + "source": "disk", + "partition": 3, + "target": "/boot" } ] } @@ -1108,30 +1122,44 @@ } }, { - "type": "org.osbuild.kernel-cmdline.bls-append", + "type": "org.osbuild.coreos.platform", "options": { - "bootpath": "mount:///", - "kernel_opts": [ - "ignition.platform.id=metal" - ] + "platform": "metal" }, "devices": { - "boot": { + "disk": { "type": "org.osbuild.loopback", "options": { "filename": "disk.img", - "start": 33024, - "size": 98304, + "partscan": true, "sector-size": 4096 } } }, "mounts": [ + { + "name": "root", + "type": "org.osbuild.xfs", + "source": "disk", + "partition": 4, + "target": "/" + }, + { + "name": "ostree.deployment", + "type": "org.osbuild.ostree.deployment", + "options": { + "source": "mount", + "deployment": { + "default": true + } + } + }, { "name": "boot", "type": "org.osbuild.ext4", - "source": "boot", - "target": "/" + "source": "disk", + "partition": 3, + "target": "/boot" } ] } @@ -1162,31 +1190,43 @@ } }, { - "type": "org.osbuild.kernel-cmdline.bls-append", + "type": "org.osbuild.coreos.platform", "options": { - "bootpath": "mount:///", - "kernel_opts": [ - "console=tty0", - "console=ttyS0,115200n8", - "ignition.platform.id=qemu" - ] + "platform": "qemu" }, "devices": { - "boot": { + "disk": { "type": "org.osbuild.loopback", "options": { "filename": "disk.img", - "start": 264192, - "size": 786432 + "partscan": true } } }, "mounts": [ + { + "name": "root", + "type": "org.osbuild.xfs", + "source": "disk", + "partition": 4, + "target": "/" + }, + { + "name": "ostree.deployment", + "type": "org.osbuild.ostree.deployment", + "options": { + "source": "mount", + "deployment": { + "default": true + } + } + }, { "name": "boot", "type": "org.osbuild.ext4", - "source": "boot", - "target": "/" + "source": "disk", + "partition": 3, + "target": "/boot" } ] } diff --git a/test/data/manifests/fedora-coreos-container.mpp.yaml b/test/data/manifests/fedora-coreos-container.mpp.yaml index c1c835b1..ee6abc0f 100644 --- a/test/data/manifests/fedora-coreos-container.mpp.yaml +++ b/test/data/manifests/fedora-coreos-container.mpp.yaml @@ -468,25 +468,34 @@ pipelines: paths: - from: input://tree/disk.img to: tree:///disk.img - - type: org.osbuild.kernel-cmdline.bls-append + - type: org.osbuild.coreos.platform options: - bootpath: mount:/// - kernel_opts: - - ignition.platform.id=metal + platform: metal devices: - boot: + disk: type: org.osbuild.loopback options: filename: disk.img - start: - mpp-format-int: '{image.layout[''boot''].start}' - size: - mpp-format-int: '{image.layout[''boot''].size}' + partscan: true mounts: - - name: boot - type: org.osbuild.ext4 - source: boot - target: / + - name: root + type: org.osbuild.xfs + source: disk + partition: + mpp-format-int: '{image.layout[''root''].partnum}' + target: / + - name: ostree.deployment + type: org.osbuild.ostree.deployment + options: + source: mount + deployment: + default: true + - name: boot + type: org.osbuild.ext4 + source: disk + partition: + mpp-format-int: '{image.layout[''boot''].partnum}' + target: /boot - name: raw-metal4k-image build: name:build stages: @@ -501,27 +510,36 @@ pipelines: paths: - from: input://tree/disk.img to: tree:///disk.img - - type: org.osbuild.kernel-cmdline.bls-append + - type: org.osbuild.coreos.platform options: - bootpath: mount:/// - kernel_opts: - - ignition.platform.id=metal + platform: metal devices: - boot: + disk: type: org.osbuild.loopback options: filename: disk.img - start: - mpp-format-int: '{image4k.layout[''boot''].start}' - size: - mpp-format-int: '{image4k.layout[''boot''].size}' + partscan: true sector-size: - mpp-format-int: "{four_k_sector_size}" + mpp-format-int: "{four_k_sector_size}" mounts: - - name: boot - type: org.osbuild.ext4 - source: boot - target: / + - name: root + type: org.osbuild.xfs + source: disk + partition: + mpp-format-int: '{image4k.layout[''root''].partnum}' + target: / + - name: ostree.deployment + type: org.osbuild.ostree.deployment + options: + source: mount + deployment: + default: true + - name: boot + type: org.osbuild.ext4 + source: disk + partition: + mpp-format-int: '{image4k.layout[''boot''].partnum}' + target: /boot - name: raw-qemu-image build: name:build stages: @@ -536,27 +554,34 @@ pipelines: paths: - from: input://tree/disk.img to: tree:///disk.img - - type: org.osbuild.kernel-cmdline.bls-append + - type: org.osbuild.coreos.platform options: - bootpath: mount:/// - kernel_opts: - - console=tty0 - - console=ttyS0,115200n8 - - ignition.platform.id=qemu + platform: qemu devices: - boot: + disk: type: org.osbuild.loopback options: filename: disk.img - start: - mpp-format-int: '{image.layout[''boot''].start}' - size: - mpp-format-int: '{image.layout[''boot''].size}' + partscan: true mounts: - - name: boot - type: org.osbuild.ext4 - source: boot - target: / + - name: root + type: org.osbuild.xfs + source: disk + partition: + mpp-format-int: '{image.layout[''root''].partnum}' + target: / + - name: ostree.deployment + type: org.osbuild.ostree.deployment + options: + source: mount + deployment: + default: true + - name: boot + type: org.osbuild.ext4 + source: disk + partition: + mpp-format-int: '{image.layout[''boot''].partnum}' + target: /boot - name: metal build: name:build stages: