From 0b7dcf3cf4ad6d51d153f8dfb2faaec1395f402f Mon Sep 17 00:00:00 2001 From: Renata Ravanelli Date: Wed, 7 Feb 2024 16:43:54 -0300 Subject: [PATCH] Add coreos.platforms stage - Process all necessary operations related to CoreOS platforms is crucial and specific to CoreOS. This step is essential for CoreOS exclusively. - Our approach to handling 'platforms.json' may change as we advance with the OSBuild work. However, we don't have a clear vision about how it will be in the future yet, particularly as we also manage similar components within the osbuild composer to configure cloud parameters. We probably will know better when we start working with the cloud artifacts. As a summary, let's add it know to unblock us, and if we find a better approach in the future, we can always go back and remove it. Signed-off-by: Renata Ravanelli --- stages/org.osbuild.coreos.platform | 116 ++++++++++++++++++ .../manifests/fedora-coreos-container.json | 104 +++++++++++----- .../fedora-coreos-container.mpp.yaml | 109 +++++++++------- 3 files changed, 255 insertions(+), 74 deletions(-) create mode 100755 stages/org.osbuild.coreos.platform 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: