Fedora CoreOS guest on Incus

Hello,

I had a bit of a fight with CoreOS to get the agent up and running (once that’s achieved, most stuff is fine). Ignition and SELinux were a bit of a pain (no semanage on fcos BTW). So I thought I’d share what worked for me…

The way you get your ignition file picked up by whatever image/install media you want is a bit of a frustrating experience: there is no universal mechanism and the specific one picked for KVM (sc. –fw_cfg) requires access to the underlying OS, which we don’t get with IncusOS (and I don’t think we should get at all). So the easiest is probably booting off the official ISO and running coreos-installer install -I https://your.domain/config.ign /dev/sdX

This is the Butane file (butane.yaml):

variant: fcos
version: 1.6.0

      
storage:
  files:

    - path: /etc/cil/run-incus_agent-incus--agent.cil
      overwrite: true
      mode: 0400
      contents:
        inline: "(filecon \"/run/incus_agent/incus-agent\" any (system_u object_r bin_t ((s0)(s0))))\n"
      user: {id: 0}
      group: {id: 0}
      
    - path: /etc/udev/rules.d/99-incus-agent.rules
      overwrite: true
      mode: 0400
      contents:
        inline: "SYMLINK==\"virtio-ports/org.linuxcontainers.incus\", TAG+=\"systemd\", ENV{SYSTEMD_WANTS}+=\"incus-agent.service\"\n"
      user: {id: 0}
      group: {id: 0}
    
systemd:
  units:
            
    - name: sshd.service
      enabled: true
      
    - name: sshd.socket
      mask: true
    
    - name: systemd-timesyncd.service
      enabled: true
        
    - name: run-incus_9pconfig.mount
      enabled: false
      contents: |
        [Unit]
        Description=Mounts incus agent on /run/incus_9pconfig
        [Mount]
        What=config
        Where=/run/incus_9pconfig
        Type=9p
        Options=access=0,trans=virtio,size=1048576
        [Install]
        WantedBy=multi-user.target
        
    - name: run-incus_9pconfig.automount
      enabled: true
      contents: |
        [Unit]
        Description=Automount Incus Agent 9p Config Disk
        [Mount]
        Where=/run/incus_9pconfig
        TimeoutIdleSec=15
        [Install]
        WantedBy=multi-user.target
        
    - name: run-incus_agent.mount
      enabled: true
      contents: |
        [Unit]
        Description=Mounts tmpfs for incus agent
        [Mount]
        What=tmpfs
        Where=/run/incus_agent
        Type=tmpfs
        Options=noatime,nosuid,nodev,mode=0700,size=50M
        [Install]
        WantedBy=multi-user.target
        
    - name: incus-agent.service
      enabled: true
      contents: |
        [Unit]
        Description=Incus - agent
        Documentation=https://linuxcontainers.org/incus/docs/main/
        Before=multi-user.target
        DefaultDependencies=no
        After=run-incus_agent.mount

        [Service]
        Type=notify
        WorkingDirectory=-/run/incus_agent
        ExecStartPre=/usr/bin/cp -Ra /run/incus_9pconfig/. /run/incus_agent
        ExecStartPre=/usr/bin/restorecon -Rv /run/incus_agent
        ExecStart=/run/incus_agent/incus-agent
        Restart=on-failure
        RestartSec=5s
        StartLimitInterval=60
        StartLimitBurst=10
        
        [Install]
        WantedBy=multi-user.target
        
    - name: setup-incus-agent.service
      enabled: true
      contents: |
        [Unit]
        Description=Sets up Incus Agent
        ConditionFirstBoot=yes
        Before=incus-agent.service
        After=run-incus_agent.mount
        [Service]
        Type=oneshot
        WorkingDirectory=-/run/incus_agent
        ExecStart=/usr/bin/semodule -i /etc/cil/run-incus_agent-incus--agent.cil
        [Install]
        WantedBy=multi-user.target

To transpile: butane -s -p butane.yml > config.ign.

Once coreos-installer … is finished, Fedora CoreOS will reboot a couple times, initialise everything and you should be able to incus shell ... inside it.

Not perfect by any stretch of imagination but given that Fedora CoreOS is basically evergreen and does a lot to prevent state shift, it fits that niche of long-running OSes that you can actually mostly afford to fire and forget.