execute commands in a CoreOS cloud-config (e.g. to add swap)

3k views Asked by At

I see that unlike the standard cloud-config file, there is no runcmd option in a CoreOS cloud-config file. Currently, I enable swap on a CoreOS machine by adding the following to my cloud-config:

units:
    - name: swap.service
      command: start
      content: |
        [Unit]
        Description=Turn on swap

        [Service]
        Type=oneshot
        Environment="SWAPFILE=/1GiB.swap"
        RemainAfterExit=true
        ExecStartPre=/usr/sbin/losetup -f ${SWAPFILE}
        ExecStart=/usr/bin/sh -c "/sbin/swapon $(/usr/sbin/losetup -j ${SWAPFILE} | /usr/bin/cut -d : -f 1)"
        ExecStop=/usr/bin/sh -c "/sbin/swapoff $(/usr/sbin/losetup -j ${SWAPFILE} | /usr/bin/cut -d : -f 1)"
        ExecStopPost=/usr/bin/sh -c "/usr/sbin/losetup -d $(/usr/sbin/losetup -j ${SWAPFILE} | /usr/bin/cut -d : -f 1)"

        [Install]
        WantedBy=local.target

Then after initializing my CoreOS image I have to ssh into the machine and run:

sudo fallocate -l 1024m /1GiB.swap && sudo chmod 600 /1GiB.swap \
&& sudo chattr +C /1GiB.swap && sudo mkswap /1GiB.swap

sudo reboot

before swap will be enabled (e.g. as evidenced by top).

It seems like I should be able to accomplish the latter commands in the cloud-config file itself, but I'm not clear on how I can run such commands without a runmcd field in cloud-config. Perhaps this can be done either by editing my swap.service unit or perhaps by adding another unit, but I haven't figured out quite how.

So, that leaves me with two questions: (1) Can this be done or will it always be necessary to run the last commands manually? (2) If the former, then how?

2

There are 2 answers

0
Guss On BEST ANSWER

@cboettig - thanks to your unit file example and @philibaker note, I got this going - basically the only thing I had to do was to change the ExecStartPre to:

ExecStartPre=/bin/bash -c "\
    fallocate -l 2g $SWAPFILE && \
    chmod 600 $SWAPFILE && \
    chattr +C $SWAPFILE && \
    mkswap $SWAPFILE && \
    losetup -f $SWAPFILE"

and that includes the entire setup in the preexec step.

0
phillbaker On

As pointed out in this answer to an issue on Github, you end up writing a unit to invoke the command of your choice. This answer, gives a good example of using an arbitrary command:

#cloud-config 
....
coreos:
  units:
    - name: runcmd.service
      command: start
      content: |
        [Unit]
        Description=Creates a tmp foo file

        [Service]
        Type=oneshot
        ExecStart=/bin/sh -c "touch /tmp/foo;"