#!/bin/sh -e
#
# 2014-2017 Steven Armstrong (steven-cdist at armstrong.cc)
# 2014 Nico Schottelius (nico-cdist at schottelius.org)
# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#

os=$(cat "${__global:?}/explorer/os")
name_running=$(cat "${__global:?}/explorer/hostname")
has_hostnamectl=$(cat "${__object:?}/explorer/has_hostnamectl")


if test -s "${__object:?}/parameter/name"
then
    name_should=$(cat "${__object:?}/parameter/name")
else
    case ${os}
    in
        # RedHat-derivatives and BSDs
        (centos|fedora|redhat|scientific|freebsd|macosx|netbsd|openbsd)
            # Hostname is FQDN
            name_should=${__target_host:?}
            ;;
        (*)
            # Hostname is only first component of FQDN
            name_should=${__target_host:?}
            name_should=${name_should%%.*}
            ;;
    esac
fi


################################################################################
# Check if the (running) hostname is already correct
#
test "${name_running}" != "${name_should}" || exit 0


################################################################################
# Setup hostname
#
echo 'changed' >>"${__messages_out:?}"

# Use the good old way to set the hostname.
case ${os}
in
    (alpine|debian|devuan|ubuntu)
        echo 'hostname -F /etc/hostname'
        ;;
    (archlinux)
        echo 'command -v hostnamectl >/dev/null 2>&1' \
            "&& hostnamectl set-hostname '${name_should}'" \
            "|| hostname '${name_should}'"
        ;;
    (centos|fedora|redhat|scientific|freebsd|netbsd|openbsd|gentoo|void)
        echo "hostname '${name_should}'"
        ;;
    (openwrt)
        echo "echo '${name_should}' >/proc/sys/kernel/hostname"
        ;;
    (macosx)
        echo "scutil --set HostName '${name_should}'"
        ;;
    (solaris)
        echo "uname -S '${name_should}'"
        ;;
    (slackware|suse)
        # We do not read from /etc/HOSTNAME, because the running
        # hostname is the first component only while the file contains
        # the FQDN.
        echo "hostname '${name_should}'"
        ;;
    (*)
        # Fall back to set the hostname using hostnamectl, if available.
        if test -n "${has_hostnamectl}"
        then
            # Don't use hostnamectl as the primary means to set the hostname for
            # systemd systems, because it cannot be trusted to work reliably and
            # exit with non-zero when it fails (e.g. hostname too long,
            # D-Bus failure, etc.).

            echo "hostnamectl set-hostname \"\$(cat /etc/hostname)\""
            echo "test \"\$(hostname)\" = \"\$(cat /etc/hostname)\"" \
                 " || hostname -F /etc/hostname"
        else
            printf "echo 'Unsupported OS: %s' >&2\n" "${os}"
            printf 'exit 1\n'
        fi
        ;;
esac
