Ejecutar un script en el primer arranque mediante un servicio systemd

Asegúrese de que ha completado los pasos descritos en la página inicial de ajuste antes de empezar con este tutorial.

En este tutorial, ejecutaremos un script en el primer arranque mediante un servicio systemd. Agregaremos lo siguiente a la configuración de Butane del escenario anterior:

  • Agregue un script en /usr/local/bin/public-ipv4.sh.

  • Configure un servicio systemd para ejecutar el script en el primer arranque.

Escribiendo el guión

Escribamos un pequeño script que use icanhazip.com para crear un archivo del asunto para exhibir como un mensaje previo al inicio de sesión en la consola y almacenarlo en public-ipv4.sh.

Esto solo es un ejemplo para mostrar como ejecutar un servicio al arrancar.No utilice esto si no confía en los propietarios de icanhazip.com.
cat <<'EOF' > public-ipv4.sh
#!/bin/bash
echo "Detected Public IPv4: is $(curl https://ipv4.icanhazip.com)" > \
    /etc/issue.d/50_public-ipv4.issue
EOF

Esto pudo ser útil en entornos de nube donde tendría diferentes direcciones públicas y privadas.

Almacenaremos este script a /usr/local/bin/public-ipv4.sh cuando aprovisionemos la máquina.

Escribir el servicio systemd

Necesitamos invocar al script de la sección anterior usando una unidad systemd. Escribamos una unidad systemd en el archivo issuegen-public-ipv4.service que haga lo que queremos, lo cual está para ejecutarse en el primer arranque y no de nuevo:

cat <<'EOF' > issuegen-public-ipv4.service
[Unit]
Before=systemd-user-sessions.service
Wants=network-online.target
After=network-online.target
ConditionPathExists=!/var/lib/issuegen-public-ipv4

[Service]
Type=oneshot
ExecStart=/usr/local/bin/public-ipv4.sh
ExecStartPost=/usr/bin/touch /var/lib/issuegen-public-ipv4
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

Escribiremos la configuración Butane y la convertiremos a Ignition

We can now create a Butane config that will include the script and systemd unit file contents by picking up the local public-ipv4.sh and issuegen-public-ipv4.service files using local file references. The final Butane config, stored in services.bu, will be:

variant: fcos
version: 1.6.0
systemd:
  units:
    - name: serial-getty@ttyS0.service
      dropins:
      - name: autologin-core.conf
        contents: |
          [Service]
          # Override Execstart in main unit
          ExecStart=
          # Add new Execstart with `-` prefix to ignore failure`
          ExecStart=-/usr/sbin/agetty --autologin core --noclear %I $TERM
    - name: issuegen-public-ipv4.service
      enabled: true
      contents_local: issuegen-public-ipv4.service
storage:
  files:
    - path: /etc/hostname
      mode: 0644
      contents:
        inline: |
          tutorial
    - path: /etc/profile.d/systemd-pager.sh
      mode: 0644
      contents:
        inline: |
          # Tell systemd to not use a pager when printing information
          export SYSTEMD_PAGER=cat
    - path: /usr/local/bin/public-ipv4.sh
      mode: 0755
      contents:
        local: public-ipv4.sh
Check the Butane Examples and Configuration specifications for more details about local file includes.

With the files public-ipv4.sh, issuegen-public-ipv4.service, and services.bu in the current working directory we can now convert to Ignition:

butane --pretty --strict --files-dir=./ services.bu --output services.ign

Testing

Just as before we will use the following to boot the instance:

# Setup the correct SELinux label to allow access to the config
chcon --verbose --type svirt_home_t services.ign

# Start a Fedora CoreOS virtual machine
virt-install --name=fcos --vcpus=2 --ram=2048 --os-variant=fedora-coreos-stable \
    --import --network=bridge=virbr0 --graphics=none \
    --qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=${PWD}/services.ign" \
    --disk="size=20,backing_store=${PWD}/fedora-coreos.qcow2"

And view on the console that the Detected Public IPv4 is shown in the console output right before you are dropped to a login prompt:

Fedora CoreOS 38.20230709.3.0
Kernel 6.3.11-200.fc38.x86_64 on an x86_64 (ttyS0)

SSH host key: SHA256:tYHKk26+NZ/+ZytWLXClGz813PQJDGP/2+AiuZ8fiqk (ECDSA)
SSH host key: SHA256:jJASZec/91zXd4or0uiFsvsfaLC6viLronfxIwQlNCs (ED25519)
SSH host key: SHA256:2XlSZAehEu666fmXeM8d47lpIJd92MBOqgMazT4GsVw (RSA)
enp1s0: 192.168.124.150 fe80::475a:7a10:2302:b670
Ignition: ran on 2023/08/03 16:40:45 UTC (this boot)
Ignition: user-provided config was applied
No SSH authorized keys provided by Ignition or Afterburn
Detected Public IPv4: is 3.252.102.80
tutorial login: core (automatic login)

Fedora CoreOS 38.20230709.3.0
[core@tutorial ~]$

And the service shows it was launched successfully:

[core@tutorial ~]$ systemctl status --full issuegen-public-ipv4.service
● issuegen-public-ipv4.service
     Loaded: loaded (/etc/systemd/system/issuegen-public-ipv4.service; enabled; preset: enabled)
    Drop-In: /usr/lib/systemd/system/service.d
             └─10-timeout-abort.conf
     Active: active (exited) since Thu 2023-08-03 16:40:55 UTC; 1min 7s ago
    Process: 1423 ExecStart=/usr/local/bin/public-ipv4.sh (code=exited, status=0/SUCCESS)
    Process: 1460 ExecStartPost=/usr/bin/touch /var/lib/issuegen-public-ipv4 (code=exited, status=0/SUCCESS)
   Main PID: 1423 (code=exited, status=0/SUCCESS)
        CPU: 84ms

Aug 03 16:40:55 tutorial systemd[1]: Starting issuegen-public-ipv4.service...
Aug 03 16:40:55 tutorial public-ipv4.sh[1424]:   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
Aug 03 16:40:55 tutorial public-ipv4.sh[1424]:                                  Dload  Upload   Total   Spent    Left  Speed
Aug 03 16:40:55 tutorial public-ipv4.sh[1424]: [158B blob data]
Aug 03 16:40:55 tutorial systemd[1]: Finished issuegen-public-ipv4.service.

Vaciado

Now let’s take down the instance for the next test. First, disconnect from the serial console by pressing CTRL + ] and then destroy the machine:

virsh destroy fcos
virsh undefine --remove-all-storage fcos

You may now proceed with the next tutorial.