#!/bin/bash

set -e

# Kernel networking params to persist
PERSIST_KERNEL_NET_PARAMS=("ipv6.disable" "net.ifnames" "net.naming-scheme")

# Dracut networking params to persist
# Everything other than rd.neednet.
# List from https://www.mankier.com/7/dracut.cmdline#Description-Network
PERSIST_DRACUT_NET_PARAMS=("ip" "ifname" "rd.route" "bootdev" "BOOTIF" "rd.bootif" "nameserver" "rd.peerdns" "biosdevname" "vlan" "bond" "team" "bridge" "rd.net.timeout.carrier")

args=("install")

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

kargs() {
    local -n kargs=$1
    local name="$2" value="$3"
    for arg in "${cmdline[@]}"; do
        if [[ "${arg%%=*}" == "${name}" ]]; then
            value="${arg#*=}"
	    kargs+=($value)
        fi
    done
}

karg_bool() {
    local value=$(karg "$@")
    case "$value" in
        ""|0|no|off) return 1;;
        *) return 0;;
    esac
}

copy_arg() {
    local arg="$1"; shift
    local opt="$1"; shift

    local value="$(karg "${arg}")"
    if [ ! -z "${value}" ]; then
        args+=("${opt}" "${value}")
    fi
}

# Get install device
device="$(karg coreos.inst.install_dev)"
if [ -z "${device}" ]; then
    echo "No install device specified."
    exit 1
fi
if [ "${device##*/}" = "${device}" ]; then
    # karg contains no slashes.  Prepend "/dev/" for compatibility.
    device="/dev/${device}"
fi
args+=("${device}")

# Forward whitelisted kernel arguments to the installed system. We have
# separate sets of whitelists for first-boot kargs and persistent kargs.
# If additional networking options have been specified, add `rd.neednet=1`
# to activate nm-initrd-generator on first boot.
firstboot_args=""
for item in "${cmdline[@]}"; do
    for param in "${PERSIST_KERNEL_NET_PARAMS[@]}" "${PERSIST_DRACUT_NET_PARAMS[@]}"; do
        if [[ $item =~ ^$param(=.*)?$ ]]; then
            firstboot_args+="${item} "
        fi
    done
done
if [ -n "${firstboot_args}" ]; then
    args+=("--append-karg" "rd.neednet=1 ${firstboot_args}")
fi

append_kargs=( )
kargs append_kargs coreos.inst.append
for k in "${append_kargs[@]}"; do
    # can also implode the array and use the flag just once but meh
    # can also have the kargs function just return a string w/o the
    # additional array defined here
	args+=("--append-karg" $k)
done

imgurl="$(karg coreos.inst.image_url)"
imgfile="$(karg coreos.inst.image_file)"
if [ -z "${imgurl}" -a -z "${imgfile}" ]; then
    echo "No image location provided."
    exit 1
fi

# Other args that should just be copied over
copy_arg coreos.inst.image_url       --image-url
copy_arg coreos.inst.image_file      --image-file
copy_arg coreos.inst.save_partlabel  --save-partlabel
copy_arg coreos.inst.save_partindex  --save-partindex

# Insecure boolean
if karg_bool coreos.inst.insecure; then
    args+=("--insecure")
fi

# Ensure device nodes have been created
udevadm settle

# Install
echo "coreos-installer ${args[@]}"
coreos-installer "${args[@]}"
