Can't install CoreOS with an ignition file

Hi,

I’m a begginer with CoreOS. I want to install it from the following butane file:

variant: fcos
version: 1.6.0
passwd:
  users:
    - name: core
      ssh_authorized_keys:
        - XXX
      password_hash: XXX
storage:
  directories:
    - path: /etc/ucore-autorebase
      mode: 0754
  disks:
    - device: /dev/disk/by-id/coreos-boot-disk
      wipe_table: true
      partitions:
        - label: root
          number: 4
          size_mib: 8192
          resize: true
        - label: swap
          size_mib: 1024
          resize: true
        - label: containersdata
          size_mib: 0
          resize: true
  luks:
    - name: root
      label: luks-root
      device: /dev/disk/by-partlabel/root
      clevis:
        custom:
          needs_network: false
          pin: tpm2
          config: '{"pcr_bank":"sha256","pcr_ids":"0,1,2,3,5,7,12"}'
      key_file:
        inline: |-
          XXX
      wipe_volume: true
    - name: containersdata
      label: luks-containersdata
      device: /dev/disk/by-partlabel/containersdata
      clevis:
        custom:
          needs_network: false
          pin: tpm2
          config: '{"pcr_bank":"sha256","pcr_ids":"0,1,2,3,5,7,12"}'
      key_file:
        inline: |-
          XXX
      wipe_volume: true
    - name: swap
      label: luks-swap
      device: /dev/disk/by-partlabel/swap
      clevis:
        custom:
          needs_network: false
          pin: tpm2
          config: '{"pcr_bank":"sha256","pcr_ids":"0,1,2,3,5,7,12"}'
      key_file:
        inline: |-
          XXX
      wipe_volume: true
  filesystems:
    - device: /dev/disk/by-partlabel/root
      format: xfs
      wipe_filesystem: true
      label: root
    - device: /dev/disk/by-partlabel/swap
      format: swap
      with_mount_unit: true
      label: swap
      wipe_filesystem: true
    - device: /dev/disk/by-partlabel/containersdata
      path: /var/lib/containers
      format: btrfs
      with_mount_unit: true
      label: containersdata
      wipe_filesystem: true

systemd:
  units:
    - name: ucore-unsigned-autorebase.service
      enabled: true
      contents: |
        [Unit]
        Description=uCore autorebase to unsigned OCI and reboot
        ConditionPathExists=!/etc/ucore-autorebase/unverified
        ConditionPathExists=!/etc/ucore-autorebase/signed
        After=network-online.target
        Wants=network-online.target
        [Service]
        Type=oneshot
        StandardOutput=journal+console
        ExecStart=/usr/bin/rpm-ostree rebase --bypass-driver ostree-unverified-registry:ghcr.io/ublue-os/ucore:stable
        ExecStart=/usr/bin/touch /etc/ucore-autorebase/unverified
        ExecStart=/usr/bin/systemctl disable ucore-unsigned-autorebase.service
        ExecStart=/usr/bin/systemctl reboot
        [Install]
        WantedBy=multi-user.target
    - name: ucore-signed-autorebase.service
      enabled: true
      contents: |
        [Unit]
        Description=uCore autorebase to signed OCI and reboot
        ConditionPathExists=/etc/ucore-autorebase/unverified
        ConditionPathExists=!/etc/ucore-autorebase/signed
        After=network-online.target
        Wants=network-online.target
        [Service]
        Type=oneshot
        StandardOutput=journal+console
        ExecStart=/usr/bin/rpm-ostree rebase --bypass-driver ostree-image-signed:docker://ghcr.io/ublue-os/ucore:stable
        ExecStart=/usr/bin/touch /etc/ucore-autorebase/signed
        ExecStart=/usr/bin/systemctl disable ucore-signed-autorebase.service
        ExecStart=/usr/bin/systemctl reboot
        [Install]
        WantedBy=multi-user.target

I convert it to a Ignition file using my windows PC, with the following command that does not return any error:
PS E:> .\butane-x86_64-pc-windows-gnu.exe butane.yaml --strict --pretty > ignition3.ign
which gives me the following ignition file:

{
  "ignition": {
    "version": "3.5.0"
  },
  "passwd": {
    "users": [
      {
        "name": "core",
        "passwordHash": "XXX",
        "sshAuthorizedKeys": [
          "XXX"
        ]
      }
    ]
  },
  "storage": {
    "directories": [
      {
        "path": "/etc/ucore-autorebase",
        "mode": 492
      }
    ],
    "disks": [
      {
        "device": "/dev/disk/by-id/coreos-boot-disk",
        "partitions": [
          {
            "label": "root",
            "number": 4,
            "resize": true,
            "sizeMiB": 8192
          },
          {
            "label": "swap",
            "resize": true,
            "sizeMiB": 1024
          },
          {
            "label": "containersdata",
            "resize": true,
            "sizeMiB": 0
          }
        ],
        "wipeTable": true
      }
    ],
    "filesystems": [
      {
        "device": "/dev/disk/by-partlabel/root",
        "format": "xfs",
        "label": "root",
        "wipeFilesystem": true
      },
      {
        "device": "/dev/disk/by-partlabel/swap",
        "format": "swap",
        "label": "swap",
        "wipeFilesystem": true
      },
      {
        "device": "/dev/disk/by-partlabel/containersdata",
        "format": "btrfs",
        "label": "containersdata",
        "path": "/var/lib/containers",
        "wipeFilesystem": true
      }
    ],
    "luks": [
      {
        "clevis": {
          "custom": {
            "config": "{\"pcr_bank\":\"sha256\",\"pcr_ids\":\"0,1,2,3,5,7,12\"}",
            "needsNetwork": false,
            "pin": "tpm2"
          }
        },
        "device": "/dev/disk/by-partlabel/root",
        "keyFile": {
          "compression": "",
          "source": "data:,XXX"
        },
        "label": "luks-root",
        "name": "root",
        "wipeVolume": true
      },
      {
        "clevis": {
          "custom": {
            "config": "{\"pcr_bank\":\"sha256\",\"pcr_ids\":\"0,1,2,3,5,7,12\"}",
            "needsNetwork": false,
            "pin": "tpm2"
          }
        },
        "device": "/dev/disk/by-partlabel/containersdata",
        "keyFile": {
          "compression": "",
          "source": "data:,XXX"
        },
        "label": "luks-containersdata",
        "name": "containersdata",
        "wipeVolume": true
      },
      {
        "clevis": {
          "custom": {
            "config": "{\"pcr_bank\":\"sha256\",\"pcr_ids\":\"0,1,2,3,5,7,12\"}",
            "needsNetwork": false,
            "pin": "tpm2"
          }
        },
        "device": "/dev/disk/by-partlabel/swap",
        "keyFile": {
          "compression": "",
          "source": "data:,XXX"
        },
        "label": "luks-swap",
        "name": "swap",
        "wipeVolume": true
      }
    ]
  },
  "systemd": {
    "units": [
      {
        "contents": "# Generated by Butane\n[Swap]\nWhat=/dev/disk/by-partlabel/swap\n\n[Install]\nRequiredBy=swap.target",
        "enabled": true,
        "name": "dev-disk-by\\x2dpartlabel-swap.swap"
      },
      {
        "contents": "# Generated by Butane\n[Unit]\nRequires=systemd-fsck@dev-disk-by\\x2dpartlabel-containersdata.service\nAfter=systemd-fsck@dev-disk-by\\x2dpartlabel-containersdata.service\n\n[Mount]\nWhere=/var/lib/containers\nWhat=/dev/disk/by-partlabel/containersdata\nType=btrfs\n\n[Install]\nRequiredBy=local-fs.target",
        "enabled": true,
        "name": "var-lib-containers.mount"
      },
      {
        "contents": "[Unit]\nDescription=uCore autorebase to unsigned OCI and reboot\nConditionPathExists=!/etc/ucore-autorebase/unverified\nConditionPathExists=!/etc/ucore-autorebase/signed\nAfter=network-online.target\nWants=network-online.target\n[Service]\nType=oneshot\nStandardOutput=journal+console\nExecStart=/usr/bin/rpm-ostree rebase --bypass-driver ostree-unverified-registry:ghcr.io/ublue-os/ucore:stable\nExecStart=/usr/bin/touch /etc/ucore-autorebase/unverified\nExecStart=/usr/bin/systemctl disable ucore-unsigned-autorebase.service\nExecStart=/usr/bin/systemctl reboot\n[Install]\nWantedBy=multi-user.target\n",
        "enabled": true,
        "name": "ucore-unsigned-autorebase.service"
      },
      {
        "contents": "[Unit]\nDescription=uCore autorebase to signed OCI and reboot\nConditionPathExists=/etc/ucore-autorebase/unverified\nConditionPathExists=!/etc/ucore-autorebase/signed\nAfter=network-online.target\nWants=network-online.target\n[Service]\nType=oneshot\nStandardOutput=journal+console\nExecStart=/usr/bin/rpm-ostree rebase --bypass-driver ostree-image-signed:docker://ghcr.io/ublue-os/ucore:stable\nExecStart=/usr/bin/touch /etc/ucore-autorebase/signed\nExecStart=/usr/bin/systemctl disable ucore-signed-autorebase.service\nExecStart=/usr/bin/systemctl reboot\n[Install]\nWantedBy=multi-user.target",
        "enabled": true,
        "name": "ucore-signed-autorebase.service"
      }
    ]
  }
}

But I can’t deploy it. I am on the latest CoreOS live iso. When I run:

sudo coreos-installer install /dev/nvme0n1 —ignition-file /mnt/usb/ignition3.ign

I get the following error:

Error: parsing specified Ignition config

Caused by:
    expected value at line 1 column 1

and I fail to understand why. The file is accessible, readable, I can perfectly read it by using cat, and it looks like all the other example ignition files I have seen. Butane does not return any error when converting it.

What could be the problem ? Thanks in advance for any answer.

Can you check the encoding of your resulting ignition file? IIRC, Windows PowerShell writes UTF-16 when redirecting output into files and I guess the installer expects UTF-8 and chokes on the two-byte representation of the opening {.

Hello @saladcesar and welcome to :fedora: !

In addition to the previous advise, I think this is a somewhat complicated Ignition configuration. I would suggest trying the simplest one first to make sure it is valid, for example:

{
  "ignition": {
    "version": "3.5.0"
  },
  "passwd": {
    "users": [
      {
        "name": "core",
        "passwordHash": "XXX",
        "sshAuthorizedKeys": [
          "XXX"
        ]
      }
    ]
  }
}

Thanks for your answer!

You are right, by default Windows is outputing UTF-16. So I did this:
PS E:> .\butane-x86_64-pc-windows-gnu.exe butane.yaml --strict --pretty | Out-File ignition.ign -Encoding utf8

and VScode confirms that the output file is now UTF-8.

But I am still having exactly the same error when trying to deploy it.

Is it UTF-8 or UTF-8 with BOM (byte order mark)? The latter might also be problematic for the installer.

(Edit: In PowerShell 7.5, Out-File -Encoding accepts utf8BOM and utf8NoBOM. The default PowerShell 5.1 that comes with Windows only accepts Out-File -Encoding utf8)

Bingo! That was it. UTF-8 without BOM works. I really need to move to fedora for my main pc too. Thank you very much!

1 Like

Thanks!

Yes I see that I got a bit too much ahead trying to combine all the features I wanted. I will add them step by step.

By the way, the only feature I am missing now and can’t find an example about, is having unencrypted /boot with ssh, for remote unlocking luks with a password over ssh in case tpm2 is failing. Would you know a working example for that?

Before going down this road, I suggest you experiment a little bit with LUKS and TPM unlocking on a local machine. In my attempts, I found TPM unlocking to be quite brittle. And it also didn’t fall back reliably to the password or recovery key for the partition, when the PCRs didn’t match expectations.

I have only tried LUKS2 on a bare metal machine with a physical keyboard attached.