#!/bin/sh
. walt-script-common

wait_for_ssh() {
    while [ 1 ]
    do
        # if port 22 is opened, send empty line to let sshd
        # close the connection and let this nc command stop.
        if walt-timeout 5 busybox nc 127.0.0.1 22 >/dev/null 2>&1 << EOF

EOF
        then
            break  # OK, port 22 is ready to accept connections
        fi
        busybox sleep 1
    done
}

call_image_bootup_script() {
    if [ -f "/bin/on-bootup" ]
    then
        if [ -x "/bin/on-bootup" ]
        then
            /bin/on-bootup
        else
            echo "WARNING: cannot run /bin/on-bootup (execute permission missing)." >&2
        fi
    fi
}

remove_nologin() {
    busybox rm -f /run/nologin
}

run_permanent_connection() {
    nc_stop="/run/walt/notify-bootup-$$.marker"
    busybox rm -f $nc_stop
    {
        echo REQ_NOTIFY_BOOTUP_STATUS
        # It is important to keep nc stdin open until we detect a disconnection
        # otherwise nc stops immediately.
        # Some versions of busybox nc also fail to stop when the remote end
        # is closed. We send EOL chars periodically to detect this.
        while [ ! -f $nc_stop ]
        do
            echo
            busybox sleep 20
        done
    } | {
        busybox nc $walt_server_ip $walt_server_notify_bootup_port || true
        echo END
    } | {
        connected=0
        # read OK from server within 3 seconds
        if msg_ok=$(wait_for_input_line_shortly 3)
        then
            if [ "$msg_ok" = "OK" ]
            then
                connected=1
                # Correct response obtained from server.
                # We can now wait indefinitely on connection, buf if busybox nc
                # stops, this will terminate the read below
                read msg_end
            fi
        fi
        # let the caller know what happened
        if [ $connected -eq 1 ]
        then
            echo DISCONNECTED
        else
            echo CONNECT_FAILED
        fi
        # connection failure or disconnection, stop the loop above
        echo > $nc_stop
    }
}

echo "[walt:bg] walt-notify-bootup started."

# We consider the node is ready when its
# sshd service is ready to accept connections.
wait_for_ssh

# call script /bin/on-bootup if image provides it
call_image_bootup_script

# remove /run/nologin if present
# (if present a warning message may be printed when connecting
# very early and the OS considers bootup procedure is not complete)
remove_nologin

# save uptime to know when the OS got ready
[ ! -e /run/uptime-ready ] && cp /proc/uptime /run/uptime-ready

# we maintain a permanent connection to walt server.
# opening it will set our status to "booted".
# if this connection is closed on our side, the server
# can detect we are down. if this connection is closed
# on server side, we know that the server is down and
# images are probably umounted, so we reboot.
retries=2
while true
do
    status=$(run_permanent_connection)
    # in rare cases a TCP connection may fail, so we must try
    # a few times.
    if [ "$status" = "CONNECT_FAILED" -a $retries -gt 0 ]
    then
        retries=$((retries - 1))
        echo "[walt:bg] walt-notify-bootup: reconnecting attempt after 5 seconds"
        busybox sleep 5
        continue
    else
        echo "[walt:bg] walt-notify-bootup:" \
             "failed or lost connection to walt server!" >&2
        trigger_walt_reboot reboot
    fi
done
