#!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh

set -e

UNIT_DIR="${1:-/tmp}"

# Usage: cmdline_arg name default_value
cmdline=( $(</proc/cmdline) )
cmdline_arg() {
    local name="$1" value="$2"
    for arg in "${cmdline[@]}"; do
        if [[ "${arg%%=*}" == "${name}" ]]; then
            value="${arg#*=}"
        fi
    done
    echo "${value}"
}

add_requires() {
    local name="$1"
    local requires_dir="${UNIT_DIR}/initrd-root-fs.target.requires"
    mkdir -p "${requires_dir}"
    ln -sf "../${name}" "${requires_dir}/${name}"
}

# set to 1 to enable copying /oem from the initrd
copy_oem=0
# check both the new mount.usr and our old usr kernel options
usr=$(cmdline_arg mount.usr "$(cmdline_arg usr)")
root=$(cmdline_arg root)
rootfstype=$(cmdline_arg rootfstype tmpfs)
rootflags=$(cmdline_arg rootflags)

# If usr= was not specified and a squashfs is bundled in the initrd use it.
if [[ -z "${usr}" && -f /usr.squashfs ]]; then
    copy_oem=1
    add_requires sysroot-usr.mount
    cat >"${UNIT_DIR}/sysroot-usr.mount" <<EOF
# Automatically generated by diskless-generator

[Unit]
Before=initrd-root-fs.target
Wants=remount-sysroot.service
After=remount-sysroot.service
# Make sure the loop device nodes are available
Wants=systemd-tmpfiles-setup-dev-early.service
After=systemd-tmpfiles-setup-dev-early.service

[Mount]
What=/usr.squashfs
Where=/sysroot/usr
Type=squashfs
EOF
    cat >"${UNIT_DIR}/sysusr-usr.mount" <<EOF
# Automatically generated by diskless-generator
[Unit]
# Make sure the loop device nodes are available
Wants=systemd-tmpfiles-setup-dev-early.service
After=systemd-tmpfiles-setup-dev-early.service
Conflicts=initrd-switch-root.target
DefaultDependencies=no
After=systemd-udevd.service

[Mount]
What=/usr.squashfs
Where=/sysusr/usr
Type=squashfs
EOF
fi

# When root= and rootfstype= are unspecified mount it as a tmpfs
if [[ -z "${root}" && "${rootfstype}" == tmpfs ]]; then
    add_requires sysroot.mount
    cat >"${UNIT_DIR}/sysroot.mount" <<EOF
# Automatically generated by diskless-generator

[Unit]
Before=initrd-root-fs.target

[Mount]
What=tmpfs
Where=/sysroot
Type=tmpfs
Options=mode=755${rootflags:+,$rootflags}
EOF

# Alternatively support using btrfs in ram instead of tmpfs
elif [[ -z "${root}" && "${rootfstype}" == btrfs ]]; then
    add_requires sysroot.mount
    cat >"${UNIT_DIR}/sysroot.mount" <<EOF
# Automatically generated by diskless-generator

[Unit]
Requires=diskless-btrfs.service
After=diskless-btrfs.service
Before=initrd-root-fs.target

[Mount]
What=/root.btrfs
Where=/sysroot
Type=btrfs
Options=loop,compress=lzo,discard${rootflags:+,$rootflags}
EOF

    cat >"${UNIT_DIR}/diskless-btrfs.service" <<EOF
# Automatically generated by diskless-generator

[Unit]
DefaultDependencies=no
# Make sure the loop device nodes are available
Wants=systemd-tmpfiles-setup-dev-early.service
After=systemd-tmpfiles-setup-dev-early.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/systemd/diskless-btrfs
EOF
fi

# When /usr is provided by the initrd then OEM may be also, but as tmpfs.
# The contents of /oem are copied into place by 99setup-root
if [[ "${copy_oem}" -eq 1 ]]; then
    add_requires sysroot-oem.mount
    cat >"${UNIT_DIR}/sysroot-oem.mount" <<EOF
# Automatically generated by diskless-generator

[Unit]
# This runs early for initrd-setup-root to populate it.
# Ignition can mount something else on /oem still
# if the user wants so.
Before=initrd-root-fs.target

[Mount]
What=tmpfs
Where=/sysroot/oem
Type=tmpfs
Options=size=0,mode=755
EOF
else
    cat >"${UNIT_DIR}/sysroot-oem.mount" <<EOF
# Automatically generated by diskless-generator
# (Ignition's OEM mounting can also (de)activate the unit)
[Mount]
What=/dev/disk/by-label/OEM
Where=/sysroot/oem
Type=auto
Options=nodev
EOF
fi
