From 6eec5f87a4e2c3b006a2bded1e85ec565cd7acc6 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sat, 26 Oct 2019 17:11:35 +0200 Subject: [PATCH] [__hostame] Simplify and revert hostnamectl to be a last resort --- .../__hostname/explorer/persistent_hostname | 66 ---------------- cdist/conf/type/__hostname/gencode-remote | 73 +++++++---------- cdist/conf/type/__hostname/manifest | 78 +++++++++++++++---- 3 files changed, 90 insertions(+), 127 deletions(-) delete mode 100755 cdist/conf/type/__hostname/explorer/persistent_hostname diff --git a/cdist/conf/type/__hostname/explorer/persistent_hostname b/cdist/conf/type/__hostname/explorer/persistent_hostname deleted file mode 100755 index 0feb0809..00000000 --- a/cdist/conf/type/__hostname/explorer/persistent_hostname +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh -# -# 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 . -# -# -# Retrieve the persistent hostname -# - -# Firstly, check hostnamectl if available. -if command -v hostnamectl >/dev/null 2>&1 -then - hostnamectl status --static && exit 0 -fi - -# In case hostnamectl is missing or failed: -# Fall back to alternative OS-specific approaches. -case $("$__explorer/os") -in - alpine|archlinux|coreos|debian|devuan|ubuntu) - test -f /etc/hostname && cat /etc/hostname - ;; - centos|fedora|redhat|scientific) - test -f /etc/sysconfig/network \ - && (. /etc/sysconfig/network && echo "$HOSTNAME") - ;; - freebsd) - (. /etc/rc.conf && echo "$hostname") - ;; - gentoo) - (. /etc/conf.d/hostname && echo "$hostname") - ;; - macosx) - scutil --get HostName 2>/dev/null - ;; - netbsd) - if grep -q '^hostname=' /etc/rc.conf - then - (. /etc/rc.conf && echo "$hostname") - elif [ -f /etc/myname ] - then - # Fall back to /etc/myname file - cat /etc/myname - fi - ;; - openbsd) - cat /etc/myname - ;; - suse) - cat /etc/HOSTNAME 2>/dev/null - ;; -esac diff --git a/cdist/conf/type/__hostname/gencode-remote b/cdist/conf/type/__hostname/gencode-remote index 5942b2e3..253bf5ea 100755 --- a/cdist/conf/type/__hostname/gencode-remote +++ b/cdist/conf/type/__hostname/gencode-remote @@ -22,17 +22,17 @@ os=$(cat "$__global/explorer/os") name_running=$(cat "$__global/explorer/hostname") -name_config=$(cat "$__object/explorer/persistent_hostname") has_hostnamectl=$(cat "$__object/explorer/has_hostnamectl") -if [ -f "$__object/parameter/name" ]; then - name_should="$(cat "$__object/parameter/name")" +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|netbsd|openbsd) + centos|fedora|redhat|scientific|freebsd|macosx|netbsd|openbsd) # Hostname is FQDN name_should="${__target_host}" ;; @@ -43,66 +43,49 @@ else esac fi + ################################################################################ -# Check if the hostname is already correct +# Check if the (running) hostname is already correct # -if [ "$name_running" = "$name_should" ] \ - && [ -z "$name_config" -o "$name_config" = "$name_should" ] -then - exit 0 -fi +test "$name_running" != "$name_should" || exit 0 + ################################################################################ # Setup hostname # echo 'changed' >>"$__messages_out" - -# First try to set the hostname using hostnamectl, if available. -if [ -n "$has_hostnamectl" ]; then - # Allow hostnamectl to fail silently. - # Who the fuck invented a tool that needs dbus to set the hostname anyway… - - # NOTE: We write the static hostname to /etc/hostname first in case - # hostnamectl fails. Fallback-code below will then adjust the running - # hostname below. - echo "echo '$name_should' >/etc/hostname" - - echo "hostnamectl set-hostname '$name_should' && exit 0" -fi - -# Use the good old way to set the hostname. Also if hostnamectl fails. +# Use the good old way to set the hostname. case $os in - alpine|archlinux|debian|devuan|ubuntu) - echo "echo '$name_should' >/etc/hostname" - echo "hostname -F /etc/hostname" + alpine|debian|devuan|ubuntu) + echo 'hostname -F /etc/hostname' ;; - coreos|openbmc-phosphor) - # NOTE: systemd-only distros have the hostname already written above. - # But since hostamectl failed, we update the running hostname - # manually. - echo "hostname -F /etc/hostname" - ;; - gentoo) - # NOTE: Writing the hostname to file is done in the manifest for OpenRC. - # For systemd hostnamectl should take care of that. + archlinux|centos|fedora|redhat|scientific|freebsd|netbsd|gentoo) echo "hostname '$name_should'" ;; macosx) echo "scutil --set HostName '$name_should'" ;; + openbsd) + echo 'hostname -F /etc/myname' + ;; suse) - # We write into /etc/HOSTNAME for backwards-compatibility. Modern SuSE - # has hostnamectl anyway and symlinks /etc/HOSTNAME to /etc/hostname. - echo "echo '$name_should' >/etc/HOSTNAME" echo 'hostname -F /etc/HOSTNAME' ;; - centos|fedora|freebsd|netbsd|openbsd|redhat|scientific) - # NOTE: Writing the hostname to file is done in the manifest. - echo "hostname '$name_should'" - ;; *) - echo "echo 'Unsupported OS: $os' >&2; exit 1" + # 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. + # Who invented a tool that needs dbus to set the hostname anyway… + + echo "hostnamectl set-hostname \"\$(cat /etc/hostname)\"" + echo "test \"\$(hostname)\" = \"\$(cat /etc/hostname)\" || hostname -F /etc/hostname" + else + printf "echo 'Unsupported OS: %s' >&2\nexit 1\n" "$os" + fi ;; esac diff --git a/cdist/conf/type/__hostname/manifest b/cdist/conf/type/__hostname/manifest index a4068cc2..78adc20b 100755 --- a/cdist/conf/type/__hostname/manifest +++ b/cdist/conf/type/__hostname/manifest @@ -20,18 +20,25 @@ # along with cdist. If not, see . # +onchange_cmd="echo changed >>'$__messages_out'" + not_supported() { - echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2 - echo "Please contribute an implementation for it if you can." >&2 - exit 1 + echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2 + echo "Please contribute an implementation for it if you can." >&2 + exit 1 } +set_hostname_systemd() { + echo "$1" | __file /etc/hostname --source - --onchange "$onchange_cmd" +} os=$(cat "$__global/explorer/os") max_len=$(cat "$__object/explorer/max_len") +has_hostnamectl=$(cat "$__object/explorer/has_hostnamectl") -if [ -f "$__object/parameter/name" ]; then - name_should="$(cat "$__object/parameter/name")" +if test -s "$__object/parameter/name" +then + name_should=$(cat "$__object/parameter/name") else case $os in @@ -49,18 +56,37 @@ fi if test -n "${max_len}" -a "$(printf '%s' "${name_should}" | wc -c)" -gt "${max_len}" then - printf "Host name too long. Up to %u characters allowed.\n" "${max_len}" >&2 - exit 1 + printf "Host name too long. Up to %u characters allowed.\n" "${max_len}" >&2 + exit 1 fi case $os in - archlinux|debian|suse|ubuntu|devuan|coreos|alpine|macosx) + alpine|debian|devuan|ubuntu) + echo "$name_should" \ + | __file /etc/hostname --source - --onchange "$onchange_cmd" + ;; + macosx) # handled in gencode-remote : ;; + archlinux) + if test -n "$has_hostnamectl" + then + set_hostname_systemd "$name_should" + else + # Only for ancient ArchLinux, write to /etc/rc.conf on pre-systemd + # versions. + __key_value sysconfig-hostname \ + --file /etc/rc.conf \ + --delimiter '=' --exact_delimiter \ + --key 'HOSTNAME' \ + --value "\"$name_should\"" \ + --onchange "$onchange_cmd" + fi + ;; centos|fedora|redhat|scientific) - if test -z "$(cat "$__object/explorer/has_hostnamectl")" + if test -z "$has_hostnamectl" then # Only write to /etc/sysconfig/network on non-systemd versions. # On systemd-based versions this entry is ignored. @@ -68,11 +94,14 @@ in --file /etc/sysconfig/network \ --delimiter '=' --exact_delimiter \ --key HOSTNAME \ - --value "\"$name_should\"" + --value "\"$name_should\"" \ + --onchange "$onchange_cmd" + else + set_hostname_systemd "$name_should" fi ;; gentoo) - if test -z "$(cat "$__object/explorer/has_hostnamectl")" + if test -z "$has_hostnamectl" then # Only write to /etc/conf.d/hostname on OpenRC-based installations. # On systemd use hostnamectl(1) in gencode-remote. @@ -81,6 +110,8 @@ in --delimiter '=' --exact_delimiter \ --key 'hostname' \ --value "\"$name_should\"" + else + set_hostname_systemd "$name_should" fi ;; freebsd) @@ -88,22 +119,37 @@ in --file /etc/rc.conf \ --delimiter '=' --exact_delimiter \ --key 'hostname' \ - --value "\"$name_should\"" + --value "\"$name_should\"" \ + --onchange "$onchange_cmd" ;; netbsd) __key_value rcconf-hostname \ --file /etc/rc.conf \ --delimiter '=' --exact_delimiter \ --key 'hostname' \ - --value "\"$name_should\"" + --value "\"$name_should\"" \ + --onchange "$onchange_cmd" + # To avoid confusion, ensure that the hostname is only stored once __file /etc/myname --state absent ;; openbsd) - echo "$name_should" | __file /etc/myname --source - + echo "$name_should" \ + | __file /etc/myname --source - --onchange "$onchange_cmd" + ;; + suse) + # We write into /etc/HOSTNAME for backwards-compatibility. Modern SuSE + # has hostnamectl anyway and symlinks /etc/HOSTNAME to /etc/hostname. + echo "$name_should" \ + | __file /etc/HOSTNAME --source - --onchange "$onchange_cmd" ;; *) - # On other operating systems we fall back to hostnamectl if available… - test -n "$(cat "$__object/explorer/has_hostnamectl")" || not_supported + # On other operating systems we fall back to systemd's hostnamectl if available… + if test -n "$has_hostnamectl" + then + set_hostname_systemd "$name_should" + else + not_supported + fi ;; esac