#!/bin/sh
# Copyright © 2006-2018 Canonical Ltd.
# Copyright © 2020 Paul Gevers
# Copyright © 2020 Lars Kruse
# Copyright © 2022 Simon McVittie
# SPDX-License-Identifier: GPL-2.0-or-later

# Note: this script does not handle timeouts: if the boot process gets stuck
# for some reason, it will wait forever. Timeouts are to be handled externally.

set -eu

init_system=unknown
if [ "$(dpkg-query -W --showformat='${Status}' systemd-sysv 2>/dev/null)" = "install ok installed" ]; then
    # For systemd detection, rely on the package and not on checking
    # /var/run/systemd, we may be execution this script so early that
    # /run is not mounted yet.
    init_system=systemd
fi

case $init_system in
    systemd)
        systemd_version=$(dpkg-query -W -f '${Version}' systemd)

        # Wait for the systemd socket to become available.
        # Without this we can't use any systemctl command.
        while [ ! -S /run/systemd/private ]; do sleep 1; done

        if dpkg --compare-versions "$systemd_version" ge 240; then
            state=$(systemctl is-system-running --wait || true)
        else
            while true; do
                state=$(systemctl is-system-running || true)
                if [ "$state" = running ] || [ "$state" = degraded ] || [ "$state" = maintenance ]; then
                    break
                fi
                sleep 1
            done
        fi
        if [ "$state" != running ]; then
            echo "System completed boot but is in '$state' state" >&2
        fi
        ;;
    *)
        # Assume a sysv-compatible init system
        while ! runlevel | grep -q '^. [1-5]$' 2>/dev/null; do
            sleep 1
        done
        while pgrep -f '/etc/init[.]d/rc' > /dev/null; do
            sleep 1
        done
        ;;
esac

# If cloud-init is installed, wait for it to finish
if command -v cloud-init >/dev/null; then
    if ! state=$(cloud-init status --wait 2>/dev/null); then
        # output of "status" command has format: "status: STATE"
        echo "cloud-init complete but reports $state" >&2
    fi
fi
