From 2cf44c66d46435e859fe0528d4b414dafd8b468a Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 15 Jan 2020 19:00:30 +0100 Subject: [PATCH 01/64] [__directory] Add --state exists and --state pre-exists --- cdist/conf/type/__directory/gencode-remote | 17 ++++++++++++++--- cdist/conf/type/__directory/man.rst | 15 +++++++++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/cdist/conf/type/__directory/gencode-remote b/cdist/conf/type/__directory/gencode-remote index 374db47a..e1ab69d7 100755 --- a/cdist/conf/type/__directory/gencode-remote +++ b/cdist/conf/type/__directory/gencode-remote @@ -3,6 +3,7 @@ # 2011-2013 Nico Schottelius (nico-cdist at schottelius.org) # 2013 Steven Armstrong (steven-cdist armstrong.cc) # 2014 Daniel Heule (hda at sfs.biz) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -21,8 +22,8 @@ # destination="/$__object_id" -state_should="$(cat "$__object/parameter/state")" -type="$(cat "$__object/explorer/type")" +state_should=$(cat "$__object/parameter/state") +type=$(cat "$__object/explorer/type") stat_file="$__object/explorer/stat" # variable to keep track if we have to set directory attributes @@ -72,7 +73,7 @@ set_mode() { } case "$state_should" in - present) + present|exists) if [ "$type" != "directory" ]; then set_attributes=1 if [ "$type" != "none" ]; then @@ -83,6 +84,10 @@ case "$state_should" in fi echo "mkdir $mkdiropt '$destination'" echo "create" >> "$__messages_out" + elif [ "$state_should" = 'exists' ]; then + # The type is directory and --state exists. We are done and do not + # check or set the attributes. + exit 0 fi # Note: Mode - needs to happen last as a chown/chgrp can alter mode by @@ -103,6 +108,12 @@ case "$state_should" in fi done ;; + pre-exists) + if [ "$type" != "directory" ]; then + echo "Directory \"$destination\" does not exist" >&2 + exit 1 + fi + ;; absent) if [ "$type" = "directory" ]; then echo "rm -rf '$destination'" diff --git a/cdist/conf/type/__directory/man.rst b/cdist/conf/type/__directory/man.rst index 74b00afe..7755334c 100644 --- a/cdist/conf/type/__directory/man.rst +++ b/cdist/conf/type/__directory/man.rst @@ -19,7 +19,18 @@ None. OPTIONAL PARAMETERS ------------------- state - 'present' or 'absent', defaults to 'present' + 'present', 'absent', 'exists' or 'pre-exists', defaults to 'present' where: + + present + the directory exists and the given attributes are set. + absent + the directory does not exist. + exists + the directory exists, but its attributes are not altered if it already + existed. + pre-exists + check that the directory exists and is indeed a directory, but do not + create or modify it. group Group to chgrp to. @@ -36,7 +47,7 @@ BOOLEAN PARAMETERS parents Whether to create parents as well (mkdir -p behaviour). Warning: all intermediate directory permissions default - to whatever mkdir -p does. + to whatever mkdir -p does. Usually this means root:root, 0700. From e3553b15b620b1abbd46720614e53c7d64c67410 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sat, 18 Jan 2020 19:47:23 +0100 Subject: [PATCH 02/64] Add Steven's __netowrk_interface type --- .../files/debian/00000-wait-for-ip | 38 +++ .../files/debian/ifupdown-symmetric-routing | 64 +++++ .../files/debian/interfaces | 9 + .../__network_interface/files/debian/manifest | 233 +++++++++++++++++ .../files/debian/network-online | 49 ++++ .../files/network-wait-online.service | 17 ++ .../files/redhat/ifup-pre-local | 39 +++ .../files/redhat/ifupdown-local | 84 ++++++ .../__network_interface/files/redhat/manifest | 171 +++++++++++++ .../__network_interface/files/redhat/name-map | 1 + .../files/symmetric-routing | 240 ++++++++++++++++++ cdist/conf/type/__network_interface/man.text | 167 ++++++++++++ cdist/conf/type/__network_interface/manifest | 86 +++++++ .../__network_interface/parameter/boolean | 6 + .../parameter/default/method | 1 + .../parameter/default/state | 1 + .../__network_interface/parameter/optional | 20 ++ 17 files changed, 1226 insertions(+) create mode 100755 cdist/conf/type/__network_interface/files/debian/00000-wait-for-ip create mode 100755 cdist/conf/type/__network_interface/files/debian/ifupdown-symmetric-routing create mode 100644 cdist/conf/type/__network_interface/files/debian/interfaces create mode 100755 cdist/conf/type/__network_interface/files/debian/manifest create mode 100644 cdist/conf/type/__network_interface/files/debian/network-online create mode 100644 cdist/conf/type/__network_interface/files/network-wait-online.service create mode 100755 cdist/conf/type/__network_interface/files/redhat/ifup-pre-local create mode 100755 cdist/conf/type/__network_interface/files/redhat/ifupdown-local create mode 100755 cdist/conf/type/__network_interface/files/redhat/manifest create mode 100644 cdist/conf/type/__network_interface/files/redhat/name-map create mode 100755 cdist/conf/type/__network_interface/files/symmetric-routing create mode 100644 cdist/conf/type/__network_interface/man.text create mode 100755 cdist/conf/type/__network_interface/manifest create mode 100644 cdist/conf/type/__network_interface/parameter/boolean create mode 100644 cdist/conf/type/__network_interface/parameter/default/method create mode 100644 cdist/conf/type/__network_interface/parameter/default/state create mode 100644 cdist/conf/type/__network_interface/parameter/optional diff --git a/cdist/conf/type/__network_interface/files/debian/00000-wait-for-ip b/cdist/conf/type/__network_interface/files/debian/00000-wait-for-ip new file mode 100755 index 00000000..3103ef62 --- /dev/null +++ b/cdist/conf/type/__network_interface/files/debian/00000-wait-for-ip @@ -0,0 +1,38 @@ +#!/bin/sh +# +# workaround the bloody upstart race conditions +# by delaying the emission of the net-device-up signal until the interface is +# really up and configured. +# +# environment variables: +# METHOD=dhcp +# MODE=start +# LOGICAL=eth0 +# PHASE=post-up +# ADDRFAM=inet +# VERBOSITY=0 +# PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +# IF_METRIC=100 +# IFACE=eth0 +# PWD=/root + +# nothing to do for loopback +[ "$IFACE" = lo ] && exit 0 + +LOG_FILE="/tmp/wait-for-ip-${IFACE}.log" +cp /dev/null $LOG_FILE +RETRY=20 +index=0 + +if [ "$ADDRFAM" = "inet" -a "$METHOD" = "dhcp" ]; then + until [ -n "$ip" -o $index -eq $RETRY ]; do + ip=$(ip -o -family inet addr show dev $IFACE | awk '{split($4, a, "/"); print a[1]}') + index=$((index+1)) + sleep 0.5 + done + if [ -n "$ip" ]; then + echo "Interface $IFACE is up with ip $ip after $index of $RETRY tries." >> $LOG_FILE + else + echo "Interface $IFACE failed to come up with an ip address, giving up after $RETRY tries." >> $LOG_FILE + fi +fi diff --git a/cdist/conf/type/__network_interface/files/debian/ifupdown-symmetric-routing b/cdist/conf/type/__network_interface/files/debian/ifupdown-symmetric-routing new file mode 100755 index 00000000..cdb528ab --- /dev/null +++ b/cdist/conf/type/__network_interface/files/debian/ifupdown-symmetric-routing @@ -0,0 +1,64 @@ +#!/bin/sh +# +# See 'IFACE OPTIONS' in interfaces(5) for available variables. +# + +DEBUG= +#DEBUG=1 +debug() { + if [ "$DEBUG" ]; then + echo "[DEBUG] $@" >&2 + fi +} + +interface="$IFACE" + +# noop for loopback +[ "$interface" = "lo" ] && exit 0 + +# only work with ipv4 +[ "$ADDRFAM" = "inet" ] || exit 0 + +# Interface must be explicitly configured to do symmetric routing. +[ "${IF_SYMMETRIC_ROUTING:-no}" = "no" ] && exit 0 + + +case "$MODE" in + start) + action="up" + ;; + stop) + action="down" + ;; +esac + +case "$METHOD" in + dhcp) + LEASEFILE="/var/lib/dhcp/dhclient.${interface}.leases" + ip_address="$(awk '/fixed-address/ {sub(/;$/,""); print $2}' "$LEASEFILE" | tail -1)" + subnet_mask_or_prefix="$(awk '/option subnet-mask/ {sub(/;$/,""); print $3}' "$LEASEFILE" | tail -1)" + gateway="$(awk '/option routers/ {sub(/;$/,""); print $3}' "$LEASEFILE" | tail -1)" + ;; + static) + [ -n "$IF_ADDRESS" ] && ip_address="$IF_ADDRESS" + [ -n "$IF_NETMASK" ] && subnet_mask_or_prefix="$IF_NETMASK" + [ -n "$IF_GATEWAY" ] && gateway="$IF_GATEWAY" + ;; + *) + echo "Unknown/unsupported METHOD: $METHOD" >&2 + exit 1 + ;; +esac + +debug "$interface -----" +debug "action: $action" +debug "interface: $interface" +debug "ip_address: $ip_address" +debug "subnet_mask_or_prefix: $subnet_mask_or_prefix" +debug "gateway: $gateway" +debug "/$interface -----" + +if [ -n "$action" -a -n "$interface" -a -n "$ip_address" -a -n "$subnet_mask_or_prefix" ]; then + symmetric-routing "$action" "$interface" "$ip_address" "$subnet_mask_or_prefix" "$gateway" +fi + diff --git a/cdist/conf/type/__network_interface/files/debian/interfaces b/cdist/conf/type/__network_interface/files/debian/interfaces new file mode 100644 index 00000000..95fdb011 --- /dev/null +++ b/cdist/conf/type/__network_interface/files/debian/interfaces @@ -0,0 +1,9 @@ +# Generated by cdist __network_interface +# Changes will be overwritten. + +# loopback +auto lo +iface lo inet loopback + +# include per interface configurations +source /etc/network/interfaces.d/*.conf diff --git a/cdist/conf/type/__network_interface/files/debian/manifest b/cdist/conf/type/__network_interface/files/debian/manifest new file mode 100755 index 00000000..1e16c771 --- /dev/null +++ b/cdist/conf/type/__network_interface/files/debian/manifest @@ -0,0 +1,233 @@ +#!/bin/sh -e +# +# 2012-2018 Steven Armstrong (steven-cdist at armstrong.cc) +# +# 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 . +# + +__package ifupdown +# Use cumulus ifupdown2 instead of ifupown and ifenslave +# ifupdown2 is currently not compatible with network-wait-online. +#__package ifupdown \ +# --name ifupdown2 + +type_files="$__type/files/debian" +mkdir "$__object/files" +interface_filename="${__object_id}.conf" + +( +cat << DONE +# Created by cdist ${__type##*/} +# Do not change. Changes will be overwritten. +# + +DONE + +if [ -f "$__object/parameter/comment" ]; then + cat "$__object/parameter/comment" | awk '{ print "# "$0 }' +fi + +if [ -f "$__object/parameter/onboot" ]; then + printf "auto %s\n" "$name" +elif [ -f "$__object/parameter/hotplug" ]; then + printf "allow-hotplug %s\n" "$name" +fi + +ignored_parameters="linkdelay" +manually_handled_parameters="name comment extra-config state method onboot hotplug nodns noroute no-network-wait-online symmetric-routing bond-slaves" +case "$method" in + dhcp) + printf "iface %s inet %s\n" "$name" "$method" + ignored_parameters="$ignored_parameters address broadcast gateway netmask" + ;; + static|manual) + printf "iface %s inet %s\n" "$name" "$method" + ;; + *) + echo "Unsupported value for parameter --method. Got '$method'. See man page for supported values." >&2 + exit 1 + ;; +esac + +for param in $(ls "$__object/parameter/"); do + if echo "$ignored_parameters" | grep -w -q "$param"; then + continue + fi + if echo "$manually_handled_parameters" | grep -w -q "$param"; then + continue + fi + + if [ -f "$type_files/name-map" ]; then + key="$(awk -v param=$param '{ if ($1 == param) {print $2;} else { print param;} }' "$type_files/name-map")" + else + key="$param" + fi + printf " %s %s\n" "$key" "$(cat "$__object/parameter/$param")" +done + +if [ -f "$__object/parameter/bond-mode" -o -f "$__object/parameter/bond-primary" ]; then + # Note: ifenslave is not needed when using ifupdown2 + # install package required for bonding + __package ifenslave + if [ -f "$__object/parameter/bond-slaves" ]; then + printf ' bond-slaves %s\n' "$(cat "$__object/parameter/bond-slaves")" + else + # need this or the slave tries to bring the master up, but the master hangs waiting for a slave + printf ' bond-slaves none\n' + fi +fi + +if [ -f "$__object/parameter/no-network-wait-online" ]; then + # Do not consider this interface in network-wait-online.service + printf ' no-network-wait-online yes\n' +fi + +if [ -f "$__object/parameter/symmetric-routing" ]; then + # Deploy scripts that implement the feature ... + __file /sbin/symmetric-routing \ + --owner root --group root --mode 0755 \ + --source "$__type/files/symmetric-routing" + require="__package/ifupdown __file/sbin/symmetric-routing" \ + __file /etc/network/if-up.d/symmetric-routing \ + --owner root --group root --mode 0755 \ + --source "$__type/files/debian/ifupdown-symmetric-routing" + require="__package/ifupdown __file/etc/network/if-up.d/symmetric-routing" \ + __link /etc/network/if-down.d/symmetric-routing \ + --type symbolic \ + --source ../if-up.d/symmetric-routing + # ... then enable it in interface stanza file. + printf ' symmetric-routing yes\n' +fi + +if [ -n "$vlan" -a -n "$device" ]; then + # Explicit parent interface for vlans + printf ' vlan-raw-device %s\n' "$device" +fi + +if [ -f "$__object/parameter/extra-config" ]; then + extra_config="$(cat "$__object/parameter/extra-config")" + if [ "$extra_config" = "-" ]; then + extra_config="$__object/stdin" + fi + awk '{print " " $0}' "$extra_config" +fi + +) >> "$__object/files/$interface_filename" + +__directory /etc/network \ + --state present \ + --owner root \ + --group root \ + --mode 755 + +require="__directory/etc/network" \ + __directory /etc/network/interfaces.d \ + --state present \ + --owner root \ + --group root \ + --mode 755 + +require="__directory/etc/network" \ + __file /etc/network/interfaces \ + --source "$type_files/interfaces" \ + --owner root \ + --group root \ + --mode 644 + +require="__file/etc/network/interfaces __directory/etc/network/interfaces.d" \ + __file "/etc/network/interfaces.d/$interface_filename" \ + --owner root \ + --group root \ + --mode 644 \ + --source "$__object/files/$interface_filename" \ + --state "$state" + + +if [ "$method" = "dhcp" -a -f "$__object/parameter/noroute" ]; then +( +cat << DONE +# Created by cdist ${__type##*/} +# Do not change. Changes will be overwritten. +# + +if [ "\$interface" = "$name" ]; then + +case "\$reason" in + BOUND|RENEW|REBIND|REBOOT) + # prevent default gateway to be set by this interface + unset new_routers + ;; +esac + +fi +DONE +) | \ +__file "/etc/dhcp/dhclient-enter-hooks.d/cdist-__network_interface-${name}-noroute" \ + --owner root \ + --group root \ + --mode 644 \ + --source - \ + --state "$state" +fi # end noroute + +if [ "$method" = "dhcp" -a -f "$__object/parameter/nodns" ]; then +( +cat << DONE +# Created by cdist ${__type##*/} +# Do not change. Changes will be overwritten. +# + +if [ "\$interface" = "$name" ]; then + +# Prevent /etc/resolv.conf from being changed by this interface +# by overriding the default 'make_resolv_conf' function. +make_resolv_conf(){ + : +} + +fi +DONE +) | \ +__file "/etc/dhcp/dhclient-enter-hooks.d/cdist-__network_interface-${name}-nodns" \ + --owner root \ + --group root \ + --mode 644 \ + --source - \ + --state "$state" +fi # end nodns + + +os=$(cat "$__global/explorer/os") +if [ "$os" = "ubuntu" ]; then + # workaround the bloody upstart race conditions + # by deploying a script that delays the emission of the net-device-up + # signal until the interface is really up and configured. + #script_name="00000-wait-for-ip" + #__file "/etc/network/if-up.d/$script_name" \ + # --owner root --group root --mode 755 \ + # --source "$type_files/$script_name" + + # Deal with systemd network-online.target race conditions + require="__package/ifupdown" \ + __file /etc/network/if-pre-up.d/network-online \ + --owner root --group root --mode 0755 \ + --source "$__type/files/debian/network-online" + require="__file/etc/network/if-pre-up.d/network-online" \ + __link /etc/network/if-up.d/network-online \ + --type symbolic \ + --source ../if-pre-up.d/network-online +fi + diff --git a/cdist/conf/type/__network_interface/files/debian/network-online b/cdist/conf/type/__network_interface/files/debian/network-online new file mode 100644 index 00000000..c7e4836d --- /dev/null +++ b/cdist/conf/type/__network_interface/files/debian/network-online @@ -0,0 +1,49 @@ +#!/bin/sh +# +# See 'IFACE OPTIONS' in interfaces(5) for available variables. +# + +DEBUG= +#DEBUG=1 +debug() { + if [ "$DEBUG" ]; then + echo "[DEBUG] $@" >&2 + fi +} + +interface="$IFACE" + +# noop for loopback +[ "$interface" = "lo" ] && exit 0 + +# nothing usefull we could do for '--all' +[ "$interface" = "--all" ] && exit 0 + +# Interface is configured to not be considered by network-wait-online.service +[ "${IF_NO_NETWORK_WAIT_ONLINE:-no}" = "yes" ] && exit 0 + + +case "$MODE" in + start) + action="up" + ;; + stop) + action="down" + ;; +esac + +state_dir=/run/network-online-interfaces +mkdir -p "$state_dir" + +case "$PHASE" in + pre-up) + # Create flag file to wait for in network-wait-online.service + touch "$state_dir/$interface" + ;; + post-up) + # This interface is up! + # Remove the flag file that was created in /sbin/ifup-pre-local + # so that the network-wait-online.service can reach the network-online.target + rm -rf "$state_dir/$interface" + ;; +esac diff --git a/cdist/conf/type/__network_interface/files/network-wait-online.service b/cdist/conf/type/__network_interface/files/network-wait-online.service new file mode 100644 index 00000000..e194b91b --- /dev/null +++ b/cdist/conf/type/__network_interface/files/network-wait-online.service @@ -0,0 +1,17 @@ +[Unit] +Description=Wait for network to be configured +Documentation=man:ifup(8) +DefaultDependencies=no +Conflicts=shutdown.target +After=%NETWORK_SERVICE_NAME% +Before=network-online.target + +[Service] +Type=oneshot +RemainAfterExit=yes +TimeoutStartSec=3min +ExecStart=/bin/sh -ec 'while [ "$(ls -1 /run/network-online-interfaces/)" ]; do sleep 1; done' + +[Install] +WantedBy=network-online.target + diff --git a/cdist/conf/type/__network_interface/files/redhat/ifup-pre-local b/cdist/conf/type/__network_interface/files/redhat/ifup-pre-local new file mode 100755 index 00000000..0030906a --- /dev/null +++ b/cdist/conf/type/__network_interface/files/redhat/ifup-pre-local @@ -0,0 +1,39 @@ +#!/bin/sh + +#echo "/sbin/ifup-pre-local" >&2 +#set -x + +config="$1" +interface="$1" + +cd /etc/sysconfig/network-scripts +. ./network-functions + +[ -f ../network ] && . ../network + +need_config "$config" + +source_config + +# If not started at boot we don't care +[ "${ONBOOT:-no}" = "no" ] && exit 0 + +# noop for loopback +[ "$DEVICE" = "lo" ] && exit 0 + +state_dir=/run/network-online-interfaces +mkdir -p "$state_dir" + +if [ "${NO_NETWORK_WAIT_ONLINE:-no}" = "no" ]; then + # remember device for later use in network-wait-online.service + touch "$state_dir/$DEVICE" +fi + +# hackaround bugs in /etc/sysconfig/network-scripts/ifup +wait_for_device=20 +index=0 +until [ -d "/sys/class/net/$DEVICE" -o $index -eq $wait_for_device ]; do + echo "waiting for /sys/class/net/$DEVICE $index/$wait_for_device" >&2 + sleep 1 + index=$(($index + 1)) +done diff --git a/cdist/conf/type/__network_interface/files/redhat/ifupdown-local b/cdist/conf/type/__network_interface/files/redhat/ifupdown-local new file mode 100755 index 00000000..31a02d0b --- /dev/null +++ b/cdist/conf/type/__network_interface/files/redhat/ifupdown-local @@ -0,0 +1,84 @@ +#!/bin/sh + +myname="${0##*/}" + +case "$myname" in + ifup-local) + action="up" + ;; + ifdown-local|ifdown-pre-local) + action="down" + ;; + *) + echo "Unable to determine action from script name: $myname" >&2 + exit 1 + ;; +esac + +DEBUG= +#DEBUG=1 +debug() { + if [ "$DEBUG" ]; then + echo "[DEBUG] $@" >&2 + fi +} + +interface="$1" + +# noop for loopback +[ "$interface" = "lo" ] && exit 0 + + +cd /etc/sysconfig/network-scripts +. ./network-functions + +[ -f ../network ] && . ../network + +need_config "$interface" +source_config + +case "${BOOTPROTO}" in + bootp|dhcp) + generate_lease_file_name + ip_address="$(awk '/fixed-address/ {sub(/;$/,""); print $2}' "$LEASEFILE" | tail -1)" + subnet_mask_or_prefix="$(awk '/option subnet-mask/ {sub(/;$/,""); print $3}' "$LEASEFILE" | tail -1)" + gateway="$(awk '/option routers/ {sub(/;$/,""); print $3}' "$LEASEFILE" | tail -1)" + ;; + none) + # No ip address set -> nothing we could do + [ -n "$IPADDR" ] && ip_address="$IPADDR" + [ -n "$PREFIX" ] && subnet_mask_or_prefix="$PREFIX" || { + [ -n "$NETMASK" ] && subnet_mask_or_prefix="$NETMASK" + } + [ -n "$GATEWAY" ] && gateway="$GATEWAY" + ;; + *) + echo "Unknown/unsupported BOOTPROTO: $BOOTPROTO" >&2 + exit 1 + ;; +esac + +debug "$interface -----" +debug "action: $action" +debug "interface: $interface" +debug "ip_address: $ip_address" +debug "subnet_mask_or_prefix: $subnet_mask_or_prefix" +debug "gateway: $gateway" +debug "/$interface -----" + +# Interface must be explicitly configured to do symmetric routing. +if [ "${SYMMETRIC_ROUTING:-no}" = "yes" ]; then + if [ -n "$action" -a -n "$interface" -a -n "$ip_address" -a -n "$subnet_mask_or_prefix" ]; then + symmetric-routing "$action" "$interface" "$ip_address" "$subnet_mask_or_prefix" "$gateway" + fi +fi + +case "$action" in + up) + # This interface is up! + # Remove the flag file that was created in /sbin/ifup-pre-local + # so that the network-wait-online.service can reach the network-online.target + state_dir=/run/network-online-interfaces + rm -rf "$state_dir/$interface" + ;; +esac diff --git a/cdist/conf/type/__network_interface/files/redhat/manifest b/cdist/conf/type/__network_interface/files/redhat/manifest new file mode 100755 index 00000000..59f17818 --- /dev/null +++ b/cdist/conf/type/__network_interface/files/redhat/manifest @@ -0,0 +1,171 @@ +#!/bin/sh -e +# +# 2014 Steven Armstrong (steven-cdist at armstrong.cc) +# +# 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 . +# + +type_files="$__type/files/redhat" +mkdir "$__object/files" +interface_filename="ifcfg-${name}" + +( +cat << DONE +# Created by cdist ${__type##*/} +# Do not change. Changes will be overwritten. +# + +DONE + +if [ -f "$__object/parameter/comment" ]; then + cat "$__object/parameter/comment" | awk '{ print "# "$0 }' +fi + +printf 'DEVICE="%s"\n' "$name" +printf 'NM_CONTROLLED=no\n' +printf 'USERCTL=no\n' + +if [ -f "$__object/parameter/onboot" ]; then + printf 'ONBOOT=yes\n' +else + printf 'ONBOOT=no\n' +fi +if [ -f "$__object/parameter/hotplug" ]; then + printf 'HOTPLUG=yes\n' +else + printf 'HOTPLUG=no\n' +fi +if [ -f "$__object/parameter/nodns" ]; then + printf 'PEERDNS=no\n' +else + printf 'PEERDNS=yes\n' +fi +if [ -f "$__object/parameter/noroute" ]; then + printf 'DEFROUTE=no\n' +else + printf 'DEFROUTE=yes\n' +fi +if [ -f "$__object/parameter/no-network-wait-online" ]; then + printf 'NO_NETWORK_WAIT_ONLINE=yes\n' +fi +if [ -f "$__object/parameter/symmetric-routing" ]; then + # Deploy scripts that implement the feature ... + __file /sbin/symmetric-routing \ + --owner root --group root --mode 0755 \ + --source "$__type/files/symmetric-routing" + # ... then enable it in interface cfg file. + printf 'SYMMETRIC_ROUTING=yes\n' +fi + +ignored_parameters="" +manually_handled_parameters="name comment extra-config state method onboot hotplug nodns noroute no-network-wait-online symmetric-routing" +case "$method" in + dhcp) + printf 'BOOTPROTO=dhcp\n' + ignored_parameters="$ignored_parameters address broadcast gateway netmask" + ;; + static|manual) + printf 'BOOTPROTO=none\n' + ;; + *) + echo "Unsupported value for parameter --method. Got '$method'. See man page for supported values." >&2 + exit 1 + ;; +esac + +for param in $(ls "$__object/parameter/"); do + if echo "$ignored_parameters" | grep -w -q "$param"; then + continue + fi + if echo "$manually_handled_parameters" | grep -w -q "$param"; then + continue + fi + + case "$param" in + bond-master) + # if someone is my master, I am a slave + printf 'SLAVE=yes\n' + printf 'MASTER=%s\n' "$(cat "$__object/parameter/$param")" + ;; + bond-*) + key="$(echo "${param#*bond-}" | tr - _)" + if [ "$param" = "bond-arp-ip-target" ]; then + value="$(cat "$__object/parameter/$param" | tr '\n' ,)" + # strip trailing comma + value="${value%,}" + else + value="$(cat "$__object/parameter/$param")" + fi + printf '%s=%s\n' "$key" "$value" >> "$__object/files/bonding_opts" + ;; + *) + # check for redhat specific name for this parameter + if [ -f "$type_files/name-map" ]; then + key="$(awk -v param=$param '{ if ($1 == param) {print $2;} else { print param;} }' "$type_files/name-map")" + else + key="$param" + fi + # redhat likes things uppercase + key="$(echo "$key" | tr '[:lower:]' '[:upper:]')" + printf '%s=%s\n' "$key" "$(cat "$__object/parameter/$param")" + ;; + esac +done +if [ -f "$__object/files/bonding_opts" ]; then + value="$(cat "$__object/files/bonding_opts" | tr '\n' ' ')" + # strip trailing space + value="${value% }" + printf 'BONDING_OPTS="%s"\n' "$value" +fi + +if [ -n "$vlan" -a -n "$device" ]; then + # Enable vlan for this interface + printf 'VLAN=yes\n' +fi + +if [ -f "$__object/parameter/extra-config" ]; then + extra_config="$(cat "$__object/parameter/extra-config")" + if [ "$extra_config" = "-" ]; then + extra_config="$__object/stdin" + fi + cat "$extra_config" +fi + + +) >> "$__object/files/$interface_filename" + +__file "/etc/sysconfig/network-scripts/$interface_filename" \ + --owner root \ + --group root \ + --mode 644 \ + --source "$__object/files/$interface_filename" \ + --state "$state" + +# Deploy helper scripts +__file /sbin/ifupdown-local \ + --owner root --group root --mode 0755 \ + --source "$__type/files/redhat/ifupdown-local" +require="__file/sbin/ifupdown-local" \ + __link /sbin/ifup-local \ + --type symbolic \ + --source ./ifupdown-local +require="__file/sbin/ifupdown-local" \ + __link /sbin/ifdown-pre-local \ + --type symbolic \ + --source ./ifupdown-local +__file /sbin/ifup-pre-local \ + --owner root --group root --mode 0755 \ + --source "$__type/files/redhat/ifup-pre-local" diff --git a/cdist/conf/type/__network_interface/files/redhat/name-map b/cdist/conf/type/__network_interface/files/redhat/name-map new file mode 100644 index 00000000..3e4decf6 --- /dev/null +++ b/cdist/conf/type/__network_interface/files/redhat/name-map @@ -0,0 +1 @@ +address ipaddr diff --git a/cdist/conf/type/__network_interface/files/symmetric-routing b/cdist/conf/type/__network_interface/files/symmetric-routing new file mode 100755 index 00000000..ecedfff9 --- /dev/null +++ b/cdist/conf/type/__network_interface/files/symmetric-routing @@ -0,0 +1,240 @@ +#!/bin/sh +# + +set -e + +error() { + echo "[ERROR] $@" >&2 +} +die() { + error "$@" + exit 1 +} +info() { + echo "[INFO] $@" >&2 +} +debug() { + if [ "$DEBUG" ]; then + echo "[DEBUG] $@" >&2 + fi +} + +usage() { + cat << EOS 1>&2 +Usage: ${0##*/} [OPTIONS] ACTION INTERFACE IP_ADDRESS SUBNET_MASK_OR_PREFIX [GATEWAY] +(see -h for more information) +EOS +} + +help() { + usage 2>&1 | head -n -1 1>&2 + + cat << EOS 1>&2 + +Setup policy based routing for the given interface +to ensure symmetric routing. + +ACTION must be either 'up' or 'down' to add respectively remove the +routing table entries. + +Options: + -h show this help message + -d run in debug mode + -x run with 'set -x' set + -n no action, just show what would be done without doing it + +Examples: + ${0##*/} up eth1 192.168.42.23 255.255.255.0 192.168.0.1 + ${0##*/} down eth1 192.168.42.23 255.255.255.0 192.168.0.1 + # gateway is optional + ${0##*/} up eth1 192.168.42.23 255.255.255.0 + ${0##*/} down eth1 192.168.42.23 255.255.255.0 + # same but using prefix instead of subnet mask + ${0##*/} up eth1 192.168.42.23 24 192.168.0.1 + ${0##*/} down eth1 192.168.42.23 24 192.168.0.1 + +EOS +} + +die_usage() { + error "$@" + usage + exit 1 +} + + +### Utility functions + +# Convert ip to int. +ip2int() { + _ip="$1" + { IFS=. read _a _b _c _d; } << _done +$_ip +_done + echo $(((((((_a << 8) | _b) << 8) | _c) << 8) | _d)) + unset _ip _a _b _c _d +} + +# Convert int to ip. +int2ip() { + _ui32=$1; shift + _ip= + for _n in 1 2 3 4; do + _ip=$((_ui32 & 0xff))${_ip:+.}$_ip + _ui32=$((_ui32 >> 8)) + done + echo $_ip + unset _ui32 _ip _n +} + +# Convert the given prefix into a subnet mask. +mask_from_prefix() { + _prefix="$1" + _mask=$((0xffffffff << (32 - $_prefix))) + int2ip $_mask + unset _prefix _mask +} + +# Calculate network number from the given ip and prefix. +network_from_ip_and_prefix() { + _ip="$1" + _prefix="$2" + _addr=$(ip2int $_ip) + _mask=$((0xffffffff << (32 - $_prefix))) + int2ip $((_addr & _mask)) + unset _ip _prefix _addr _mask +} + +# Calculate number of bits in the given subnet mask. +prefix_from_mask() { + # Assumes there's no "255." after a non-255 byte in the mask + _mask="$1" + _x=${_mask##*255.} + set -- 0^^^128^192^224^240^248^252^254^ $(( (${#1} - ${#_x})*2 )) ${_x%%.*} + _x=${1%%$3*} + echo $(( $2 + (${#_x}/4) )) + unset _mask _x +} + +rt_tables=/etc/iproute2/rt_tables +#rt_tables=/tmp/rt_tables +# Get and if required create a routing table for the given table name. +table_id_from_name() { + _interface="$1" + _table_id=$(awk -vname=$_interface '{ if ($2 == name) print $1 }' "$rt_tables") + if [ -z "$_table_id" ]; then + # find unused table id and create a new table for this interface + _used_ids=$(awk '$1 !~ /^(#| |255|254|253|0)/ { print $1 }' "$rt_tables") + for _tid in $(seq 1 252); do + if echo "$_used_ids" | grep -q "$_tid"; then + continue + else + _table_id="$_tid" + [ $NOACTION ] || printf '%s %s\n' "$_table_id" "$_interface" >> "$rt_tables" + break + fi + done + fi + echo "$_table_id" + unset _interface _table_id _used_ids _tid +} + + +### Parse command line arguments + +NOACTION= +DEBUG= +SETX= +while getopts "ndxh" options +do + #echo "$flag" $OPTIND $OPTARG + case $options in + n) NOACTION=1;; + d) DEBUG=1;; + x) SETX=1;; + ?|h) help + exit 0 + ;; + *) usage + exit 1 + ;; + esac +done +# Strip arguments allready handled by getopts +shift $((OPTIND-1)) + +[ "$SETX" ] && set -x + +# Validate arguments +[ "$#" -ge 4 ] || die_usage "Expected at least 4 arguments, got: $#" + +action="$1" # up | down +interface="$2" +ip_address="$3" +subnet_mask_or_prefix="$4" +gateway="$5" + +debug "action: $action" +debug "interface: $interface" +debug "ip_address: $ip_address" +debug "subnet_mask_or_prefix: $subnet_mask_or_prefix" +debug "gateway: $gateway" + + +case "$subnet_mask_or_prefix" in + *.*) + # has a dot, must be a subnet mask + subnet_mask="$subnet_mask_or_prefix" + prefix=$(prefix_from_mask "$subnet_mask") + network="$(network_from_ip_and_prefix "$ip_address" "$prefix")" + ;; + *) + # no dot, must be prefix + prefix="$subnet_mask_or_prefix" + subnet_mask="$(mask_from_prefix "$prefix")" + network="$(network_from_ip_and_prefix "$ip_address" "$prefix")" + ;; +esac + +table_name="$interface" +table_id="$(table_id_from_name "$table_name")" + +debug "subnet_mask: $subnet_mask" +debug "prefix: $prefix" +debug "network: $network" +debug "table_name: $table_name" +debug "table_id: $table_id" + +( +case "$action" in + up) + # setup routing table for interface + printf 'ip route add "%s/%s" dev "%s" proto static src "%s" table "%s"\n' \ + "$network" "$prefix" "$interface" "$ip_address" "$table_name" + if [ -n "$gateway" ]; then + printf 'ip route add default via "%s" table "%s"\n' "$gateway" "$table_name" + fi + printf 'ip rule add from "%s" table "%s"\n' "$ip_address" "$table_name" + ;; + down) + printf 'ip rule del from "%s" table "%s"\n' "$ip_address" "$table_name" + if [ -n "$gateway" ]; then + printf 'ip route del default via "%s" table "%s"\n' "$gateway" "$table_name" + fi + printf 'ip route del "%s/%s" dev "%s" proto static src "%s" table "%s"\n' \ + "$network" "$prefix" "$interface" "$ip_address" "$table_name" + ;; + *) + echo "Unknown action: $action" >&2 + exit 1 + ;; +esac +# tell the kernel that it needs to re-parse the policy database +printf 'ip route flush cache\n' +) | ( + if [ "$NOACTION" ]; then + cat + else + /bin/sh -s + fi +) diff --git a/cdist/conf/type/__network_interface/man.text b/cdist/conf/type/__network_interface/man.text new file mode 100644 index 00000000..c9115e99 --- /dev/null +++ b/cdist/conf/type/__network_interface/man.text @@ -0,0 +1,167 @@ +cdist-type__network_interface(7) +================================ +Steven Armstrong + + +NAME +---- +cdist-type__network_interface - configure network interfaces + + +DESCRIPTION +----------- +Configures network interfaces on debian an redhat based systems. +Interface names containing a dot are assumed to be vlan tagged sub interfaces. +e.g. eth0.10 is vlan 10 on physical device eth0 + + +REQUIRED PARAMETERS +------------------- + + +OPTIONAL PARAMETERS +------------------- +name:: + The name of the physical or logical network device. + Defaults to __object_id. +method:: + The method for determining an IP address for the interface. + 'dhcp', 'static' or 'manual'. + Defaults to 'dhcp'. +address:: + The IP address of the network interface. + Only used if --method is not 'dhcp' +broadcast:: + Only used if --method is not 'dhcp' +comment:: +extra-config:: + additional config that is added to the generated interfaces file verbatim +gateway:: + Default gateway (dotted quad) + Only used if --method is not 'dhcp' +netmask:: + The subnet mask to apply to the interface + Only used if --method is not 'dhcp' +metric:: + Routing metric for the default gateway +mtu:: + The Maximum Transmission Unit size to use for the interface +state:: + 'present' or 'absent', defaults to 'present' +bond-arp-interval:: + Specifies (in milliseconds) how often ARP monitoring occurs. +bond-arp-ip-target:: + Specifies the target IP address of ARP requests when the arp_interval parameter is enabled. + Can be specified up to 16 times. +bond-master:: + The name of the master (bonding) interface to which this slave should be enslaved. +bond-miimon:: + Specifies (in milliseconds) how often MII link monitoring occurs. +bond-mode:: + Allows you to specify the bonding policy. The value can be one of: + balance-rr (0) + active-backup (1) + balance-xor (2) + broadcast (3) + 802.3ad (4) + balance-tlb (5) + balance-alb (6) +bond-primary:: + Specifies the interface name, such as eth0, of the primary device. +bond-slaves:: + The slave interfaces that form this bonding. +linkdelay:: + Only useable on Redhat based systems. + Time in seconds that the system should pause after the specific interface + is enabled. This may be useful if one interface is connected to a + switch which has spanning tree enabled and must wait for STP to + converge before the interface should be considered usable. + + +BOOLEAN PARAMETERS +------------------ +onboot: + Whether to bring the interface up on boot +hotplug:: + Allow/disallow hotplug support for this interface +nodns:: + Do not configure nameservers in /etc/resolv.conf. +noroute:: + Do not set default route. +no-network-wait-online:: + Do not consider this network interface in the network-wait-online.service unit. +symmetric-routing:: + Manage routing tables and rules to ensure symmetric routing. + + +EXAMPLES +-------- + +-------------------------------------------------------------------------------- +__network_interface eth0 --onboot +# Same thing, but explicitly define method +__network_interface eth0 --method dhcp --onboot + +__network_interface eth1 \ + --method static \ + --address 192.168.42.23 \ + --netmask 255.255.255.0 \ + --gateway 192.168.42.1 \ + --onboot + +__network_interface eth3 --method dhcp --hotplug + + +# Don't wait for Infiniband interface to be up before reaching systemd network-online.target +__network_interface ib0 --method dhcp --no-network-wait-online + +# active-backup bonding with 2 slaves +__network_interface bond0 \ + --onboot \ + --method static \ + --bond-mode active-backup \ + --bond-miimon 500 \ + --bond-primary eth5 \ + --address 10.205.9.65 \ + --netmask 255.255.224.0 + +__network_interface eth5 \ + --onboot \ + --method manual \ + --bond-master bond0 + +__network_interface eth6 \ + --onboot \ + --method manual \ + --bond-master bond0 + + +# extra config +__network_interface eth0 \ + --method dhcp \ + --extra-config - << DONE +post-up ip route add 10.205.0.0/19 via 10.205.161.1 +post-up ip route add 10.205.96.0/19 via 10.205.161.1 +pre-down ip route del 10.205.0.0/19 via 10.205.161.1 +pre-down ip route del 10.205.96.0/19 via 10.205.161.1 +DONE +-------------------------------------------------------------------------------- + + +SEE ALSO +-------- +- cdist-type(7) +- Redhat bonding documentation + https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/sec-Using_Channel_Bonding.html + https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Networking_Guide/sec-Using_Channel_Bonding.html + https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/s2-networkscripts-interfaces-chan.html +- Debian bonding documentation + /usr/share/doc/ifenslave-2.6/README.Debian.gz +- Symmetric routing + http://www.microhowto.info/howto/ensure_symmetric_routing_on_a_server_with_multiple_default_gateways.html + + +COPYING +------- +Copyright \(C) 2012-2016 Steven Armstrong. Free use of this software is +granted under the terms of the GNU General Public License version 3 (GPLv3). diff --git a/cdist/conf/type/__network_interface/manifest b/cdist/conf/type/__network_interface/manifest new file mode 100755 index 00000000..0fed7894 --- /dev/null +++ b/cdist/conf/type/__network_interface/manifest @@ -0,0 +1,86 @@ +#!/bin/sh -e +# +# 2012-2014 Steven Armstrong (steven-cdist at armstrong.cc) +# 2020 Adapted for upstream cdist by Darko Poljak (darko.poljak at gmail.com) +# +# 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 . +# + +os=$(cat "$__global/explorer/os") +osv="$(cat "$__global/explorer/os_version")" + +not_supported() { + echo "Your operating system ($os $osv) is currently not supported by this type (${__type##*/})." >&2 + echo "Please contribute an implementation for it if you can." >&2 + exit 1 +} + +case "$os" in + ubuntu) + osv_int="$(echo "$osv" | tr -d .)" + if [ "$osv_int" -lt 1110 ]; then + not_supported + fi + manifest_file="$__type/files/debian/manifest" + systemd_network_service_name="networking.service" + ;; + debian) + manifest_file="$__type/files/debian/manifest" + systemd_network_service_name="networking.service" + ;; + centos|redhat) + manifest_file="$__type/files/redhat/manifest" + systemd_network_service_name="network.service" + ;; + *) + not_supported + ;; +esac + +name="$(cat "$__object/parameter/name" 2>/dev/null || echo "$__object_id")" +method="$(cat "$__object/parameter/method")" +state="$(cat "$__object/parameter/state")" + +device= +vlan= +case "$name" in + *.*) + device="${name%.*}" + vlan="${name#*.}" + ;; +esac + + +# export variables +export name +export device +export vlan +export method +export state + +# run os specific manifest +"$manifest_file" + + +if grep -q systemd "$__global/explorer/init"; then + sed -e "s|%NETWORK_SERVICE_NAME%|${systemd_network_service_name}|" \ + "$__type/files/network-wait-online.service" | \ + __file /etc/systemd/system/network-wait-online.service \ + --owner root --group root --mode 0644 \ + --source - + require="__file/etc/systemd/system/network-wait-online.service" \ + __service network-wait-online --no-start +fi diff --git a/cdist/conf/type/__network_interface/parameter/boolean b/cdist/conf/type/__network_interface/parameter/boolean new file mode 100644 index 00000000..a15f76a2 --- /dev/null +++ b/cdist/conf/type/__network_interface/parameter/boolean @@ -0,0 +1,6 @@ +hotplug +nodns +noroute +onboot +no-network-wait-online +symmetric-routing diff --git a/cdist/conf/type/__network_interface/parameter/default/method b/cdist/conf/type/__network_interface/parameter/default/method new file mode 100644 index 00000000..72ab18f1 --- /dev/null +++ b/cdist/conf/type/__network_interface/parameter/default/method @@ -0,0 +1 @@ +dhcp diff --git a/cdist/conf/type/__network_interface/parameter/default/state b/cdist/conf/type/__network_interface/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__network_interface/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__network_interface/parameter/optional b/cdist/conf/type/__network_interface/parameter/optional new file mode 100644 index 00000000..17a87788 --- /dev/null +++ b/cdist/conf/type/__network_interface/parameter/optional @@ -0,0 +1,20 @@ +address +bond-arp-interval +bond-arp-ip-target +bond-master +bond-miimon +bond-mode +bond-primary +bond-slaves +broadcast +comment +extra-config +gateway +linkdelay +method +metric +mtu +name +netmask +network +state From f03299ebf341b92c3715965e5c77423cfa516ca5 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Thu, 23 Jan 2020 13:58:04 +0100 Subject: [PATCH 03/64] __service -> __start_on_boot --- cdist/conf/type/__network_interface/manifest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/conf/type/__network_interface/manifest b/cdist/conf/type/__network_interface/manifest index 0fed7894..840734a4 100755 --- a/cdist/conf/type/__network_interface/manifest +++ b/cdist/conf/type/__network_interface/manifest @@ -82,5 +82,5 @@ if grep -q systemd "$__global/explorer/init"; then --owner root --group root --mode 0644 \ --source - require="__file/etc/systemd/system/network-wait-online.service" \ - __service network-wait-online --no-start + __start_on_boot network-wait-online fi From a30b4e3619ef57ba5a3bd9bf044c5e2415157f16 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Thu, 23 Jan 2020 14:10:48 +0100 Subject: [PATCH 04/64] Fix shellcheck issues --- .../__network_interface/files/debian/manifest | 19 ++++++++++++------- .../__network_interface/files/redhat/manifest | 16 ++++++++++------ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/cdist/conf/type/__network_interface/files/debian/manifest b/cdist/conf/type/__network_interface/files/debian/manifest index 1e16c771..13340327 100755 --- a/cdist/conf/type/__network_interface/files/debian/manifest +++ b/cdist/conf/type/__network_interface/files/debian/manifest @@ -37,17 +37,20 @@ cat << DONE DONE if [ -f "$__object/parameter/comment" ]; then - cat "$__object/parameter/comment" | awk '{ print "# "$0 }' + awk '{ print "# "$0 }' < "$__object/parameter/comment" fi if [ -f "$__object/parameter/onboot" ]; then + # shellcheck disable=SC2154 printf "auto %s\n" "$name" elif [ -f "$__object/parameter/hotplug" ]; then + # shellcheck disable=SC2154 printf "allow-hotplug %s\n" "$name" fi ignored_parameters="linkdelay" manually_handled_parameters="name comment extra-config state method onboot hotplug nodns noroute no-network-wait-online symmetric-routing bond-slaves" +# shellcheck disable=SC2154 case "$method" in dhcp) printf "iface %s inet %s\n" "$name" "$method" @@ -62,7 +65,7 @@ case "$method" in ;; esac -for param in $(ls "$__object/parameter/"); do +for param in "$__object"/parameter/*; do if echo "$ignored_parameters" | grep -w -q "$param"; then continue fi @@ -71,14 +74,14 @@ for param in $(ls "$__object/parameter/"); do fi if [ -f "$type_files/name-map" ]; then - key="$(awk -v param=$param '{ if ($1 == param) {print $2;} else { print param;} }' "$type_files/name-map")" + key="$(awk -v param="$param" '{ if ($1 == param) {print $2;} else { print param;} }' "$type_files/name-map")" else key="$param" fi printf " %s %s\n" "$key" "$(cat "$__object/parameter/$param")" done -if [ -f "$__object/parameter/bond-mode" -o -f "$__object/parameter/bond-primary" ]; then +if [ -f "$__object/parameter/bond-mode" ] || [ -f "$__object/parameter/bond-primary" ]; then # Note: ifenslave is not needed when using ifupdown2 # install package required for bonding __package ifenslave @@ -112,7 +115,8 @@ if [ -f "$__object/parameter/symmetric-routing" ]; then printf ' symmetric-routing yes\n' fi -if [ -n "$vlan" -a -n "$device" ]; then +# shellcheck disable=SC2154 +if [ -n "$vlan" ] && [ -n "$device" ]; then # Explicit parent interface for vlans printf ' vlan-raw-device %s\n' "$device" fi @@ -147,6 +151,7 @@ require="__directory/etc/network" \ --group root \ --mode 644 +# shellcheck disable=SC2154 require="__file/etc/network/interfaces __directory/etc/network/interfaces.d" \ __file "/etc/network/interfaces.d/$interface_filename" \ --owner root \ @@ -156,7 +161,7 @@ require="__file/etc/network/interfaces __directory/etc/network/interfaces.d" \ --state "$state" -if [ "$method" = "dhcp" -a -f "$__object/parameter/noroute" ]; then +if [ "$method" = "dhcp" ] && [ -f "$__object/parameter/noroute" ]; then ( cat << DONE # Created by cdist ${__type##*/} @@ -183,7 +188,7 @@ __file "/etc/dhcp/dhclient-enter-hooks.d/cdist-__network_interface-${name}-norou --state "$state" fi # end noroute -if [ "$method" = "dhcp" -a -f "$__object/parameter/nodns" ]; then +if [ "$method" = "dhcp" ] && [ -f "$__object/parameter/nodns" ]; then ( cat << DONE # Created by cdist ${__type##*/} diff --git a/cdist/conf/type/__network_interface/files/redhat/manifest b/cdist/conf/type/__network_interface/files/redhat/manifest index 59f17818..1ed0098d 100755 --- a/cdist/conf/type/__network_interface/files/redhat/manifest +++ b/cdist/conf/type/__network_interface/files/redhat/manifest @@ -20,6 +20,7 @@ type_files="$__type/files/redhat" mkdir "$__object/files" +# shellcheck disable=SC2154 interface_filename="ifcfg-${name}" ( @@ -31,7 +32,7 @@ cat << DONE DONE if [ -f "$__object/parameter/comment" ]; then - cat "$__object/parameter/comment" | awk '{ print "# "$0 }' + awk '{ print "# "$0 }' < "$__object/parameter/comment" fi printf 'DEVICE="%s"\n' "$name" @@ -72,6 +73,7 @@ fi ignored_parameters="" manually_handled_parameters="name comment extra-config state method onboot hotplug nodns noroute no-network-wait-online symmetric-routing" +# shellcheck disable=SC2154 case "$method" in dhcp) printf 'BOOTPROTO=dhcp\n' @@ -86,7 +88,7 @@ case "$method" in ;; esac -for param in $(ls "$__object/parameter/"); do +for param in "$__object"/parameter/*; do if echo "$ignored_parameters" | grep -w -q "$param"; then continue fi @@ -103,7 +105,7 @@ for param in $(ls "$__object/parameter/"); do bond-*) key="$(echo "${param#*bond-}" | tr - _)" if [ "$param" = "bond-arp-ip-target" ]; then - value="$(cat "$__object/parameter/$param" | tr '\n' ,)" + value="$(tr '\n' , < "$__object/parameter/$param")" # strip trailing comma value="${value%,}" else @@ -114,7 +116,7 @@ for param in $(ls "$__object/parameter/"); do *) # check for redhat specific name for this parameter if [ -f "$type_files/name-map" ]; then - key="$(awk -v param=$param '{ if ($1 == param) {print $2;} else { print param;} }' "$type_files/name-map")" + key="$(awk -v param="$param" '{ if ($1 == param) {print $2;} else { print param;} }' "$type_files/name-map")" else key="$param" fi @@ -125,13 +127,14 @@ for param in $(ls "$__object/parameter/"); do esac done if [ -f "$__object/files/bonding_opts" ]; then - value="$(cat "$__object/files/bonding_opts" | tr '\n' ' ')" + value="$(tr '\n' ' ' < "$__object/files/bonding_opts")" # strip trailing space value="${value% }" printf 'BONDING_OPTS="%s"\n' "$value" fi -if [ -n "$vlan" -a -n "$device" ]; then +# shellcheck disable=SC2154 +if [ -n "$vlan" ] && [ -n "$device" ]; then # Enable vlan for this interface printf 'VLAN=yes\n' fi @@ -147,6 +150,7 @@ fi ) >> "$__object/files/$interface_filename" +# shellcheck disable=SC2154 __file "/etc/sysconfig/network-scripts/$interface_filename" \ --owner root \ --group root \ From 7408ddc13440e12477af3816ad8fe34476371ba1 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Thu, 23 Jan 2020 14:38:42 +0100 Subject: [PATCH 05/64] Rewrite man page in rst --- cdist/conf/type/__network_interface/man.rst | 198 +++++++++++++++++++ cdist/conf/type/__network_interface/man.text | 167 ---------------- 2 files changed, 198 insertions(+), 167 deletions(-) create mode 100644 cdist/conf/type/__network_interface/man.rst delete mode 100644 cdist/conf/type/__network_interface/man.text diff --git a/cdist/conf/type/__network_interface/man.rst b/cdist/conf/type/__network_interface/man.rst new file mode 100644 index 00000000..22cce84a --- /dev/null +++ b/cdist/conf/type/__network_interface/man.rst @@ -0,0 +1,198 @@ +cdist-type__network_interface(7) +================================ + +NAME +---- +cdist-type__network_interface - configure network interfaces + + +DESCRIPTION +----------- +Configures network interfaces on debian an redhat based systems. +Interface names containing a dot are assumed to be vlan tagged sub interfaces. +e.g. eth0.10 is vlan 10 on physical device eth0. + + +REQUIRED PARAMETERS +------------------- +None. + +OPTIONAL PARAMETERS +------------------- +name + The name of the physical or logical network device. + Defaults to __object_id. + +method + The method for determining an IP address for the interface. + 'dhcp', 'static' or 'manual'. + Defaults to 'dhcp'. + +address + The IP address of the network interface. + Only used if --method is not 'dhcp'. + +broadcast + Only used if --method is not 'dhcp'. + +comment + Comment. + +extra-config + Additional config that is added to the generated interfaces file verbatim. + +gateway + Default gateway (dotted quad). + Only used if --method is not 'dhcp'. + +netmask + The subnet mask to apply to the interface. + Only used if --method is not 'dhcp'. + +metric + Routing metric for the default gateway. + +mtu + The Maximum Transmission Unit size to use for the interface. + +state + 'present' or 'absent', defaults to 'present'. + +bond-arp-interval + Specifies (in milliseconds) how often ARP monitoring occurs. + +bond-arp-ip-target + Specifies the target IP address of ARP requests when the arp_interval parameter is enabled. + Can be specified up to 16 times. + +bond-master + The name of the master (bonding) interface to which this slave should be enslaved. + +bond-miimon + Specifies (in milliseconds) how often MII link monitoring occurs. + +bond-mode + Allows you to specify the bonding policy. The value can be one of: + + - balance-rr (0) + - active-backup (1) + - balance-xor (2) + - broadcast (3) + - 802.3ad (4) + - balance-tlb (5) + - balance-alb (6) + +bond-primary + Specifies the interface name, such as eth0, of the primary device. + +bond-slaves + The slave interfaces that form this bonding. + +linkdelay + Only useable on Redhat based systems. + Time in seconds that the system should pause after the specific interface + is enabled. This may be useful if one interface is connected to a + switch which has spanning tree enabled and must wait for STP to + converge before the interface should be considered usable. + +BOOLEAN PARAMETERS +------------------ +onboot + Whether to bring the interface up on boot. + +hotplug + Allow/disallow hotplug support for this interface. + +nodns + Do not configure nameservers in /etc/resolv.conf. + +noroute + Do not set default route. + +no-network-wait-online + Do not consider this network interface in the network-wait-online.service unit. + +symmetric-routing + Manage routing tables and rules to ensure symmetric routing. + + +EXAMPLES +-------- + +.. code-block:: sh + + __network_interface eth0 --onboot + + # Same thing, but explicitly define method + __network_interface eth0 --method dhcp --onboot + + __network_interface eth1 \ + --method static \ + --address 192.168.42.23 \ + --netmask 255.255.255.0 \ + --gateway 192.168.42.1 \ + --onboot + + __network_interface eth3 --method dhcp --hotplug + + # Don't wait for Infiniband interface to be up before reaching systemd network-online.target + __network_interface ib0 --method dhcp --no-network-wait-online + + # active-backup bonding with 2 slaves + __network_interface bond0 \ + --onboot \ + --method static \ + --bond-mode active-backup \ + --bond-miimon 500 \ + --bond-primary eth5 \ + --address 10.205.9.65 \ + --netmask 255.255.224.0 + + __network_interface eth5 \ + --onboot \ + --method manual \ + --bond-master bond0 + + __network_interface eth6 \ + --onboot \ + --method manual \ + --bond-master bond0 + + # extra config + __network_interface eth0 \ + --method dhcp \ + --extra-config - << DONE + post-up ip route add 10.205.0.0/19 via 10.205.161.1 + post-up ip route add 10.205.96.0/19 via 10.205.161.1 + pre-down ip route del 10.205.0.0/19 via 10.205.161.1 + pre-down ip route del 10.205.96.0/19 via 10.205.161.1 + DONE + + +SEE ALSO +-------- +Redhat bonding documentation: + +* https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/sec-Using_Channel_Bonding.html +* https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Networking_Guide/sec-Using_Channel_Bonding.html +* https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/s2-networkscripts-interfaces-chan.html + +Debian bonding documentation + +* /usr/share/doc/ifenslave-2.6/README.Debian.gz + +Symmetric routing + +* http://www.microhowto.info/howto/ensure_symmetric_routing_on_a_server_with_multiple_default_gateways.html + + +AUTHORS +------- +Steven Armstrong + +COPYING +------- +Copyright \(C) 2012-2016 Steven Armstrong. 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. diff --git a/cdist/conf/type/__network_interface/man.text b/cdist/conf/type/__network_interface/man.text deleted file mode 100644 index c9115e99..00000000 --- a/cdist/conf/type/__network_interface/man.text +++ /dev/null @@ -1,167 +0,0 @@ -cdist-type__network_interface(7) -================================ -Steven Armstrong - - -NAME ----- -cdist-type__network_interface - configure network interfaces - - -DESCRIPTION ------------ -Configures network interfaces on debian an redhat based systems. -Interface names containing a dot are assumed to be vlan tagged sub interfaces. -e.g. eth0.10 is vlan 10 on physical device eth0 - - -REQUIRED PARAMETERS -------------------- - - -OPTIONAL PARAMETERS -------------------- -name:: - The name of the physical or logical network device. - Defaults to __object_id. -method:: - The method for determining an IP address for the interface. - 'dhcp', 'static' or 'manual'. - Defaults to 'dhcp'. -address:: - The IP address of the network interface. - Only used if --method is not 'dhcp' -broadcast:: - Only used if --method is not 'dhcp' -comment:: -extra-config:: - additional config that is added to the generated interfaces file verbatim -gateway:: - Default gateway (dotted quad) - Only used if --method is not 'dhcp' -netmask:: - The subnet mask to apply to the interface - Only used if --method is not 'dhcp' -metric:: - Routing metric for the default gateway -mtu:: - The Maximum Transmission Unit size to use for the interface -state:: - 'present' or 'absent', defaults to 'present' -bond-arp-interval:: - Specifies (in milliseconds) how often ARP monitoring occurs. -bond-arp-ip-target:: - Specifies the target IP address of ARP requests when the arp_interval parameter is enabled. - Can be specified up to 16 times. -bond-master:: - The name of the master (bonding) interface to which this slave should be enslaved. -bond-miimon:: - Specifies (in milliseconds) how often MII link monitoring occurs. -bond-mode:: - Allows you to specify the bonding policy. The value can be one of: - balance-rr (0) - active-backup (1) - balance-xor (2) - broadcast (3) - 802.3ad (4) - balance-tlb (5) - balance-alb (6) -bond-primary:: - Specifies the interface name, such as eth0, of the primary device. -bond-slaves:: - The slave interfaces that form this bonding. -linkdelay:: - Only useable on Redhat based systems. - Time in seconds that the system should pause after the specific interface - is enabled. This may be useful if one interface is connected to a - switch which has spanning tree enabled and must wait for STP to - converge before the interface should be considered usable. - - -BOOLEAN PARAMETERS ------------------- -onboot: - Whether to bring the interface up on boot -hotplug:: - Allow/disallow hotplug support for this interface -nodns:: - Do not configure nameservers in /etc/resolv.conf. -noroute:: - Do not set default route. -no-network-wait-online:: - Do not consider this network interface in the network-wait-online.service unit. -symmetric-routing:: - Manage routing tables and rules to ensure symmetric routing. - - -EXAMPLES --------- - --------------------------------------------------------------------------------- -__network_interface eth0 --onboot -# Same thing, but explicitly define method -__network_interface eth0 --method dhcp --onboot - -__network_interface eth1 \ - --method static \ - --address 192.168.42.23 \ - --netmask 255.255.255.0 \ - --gateway 192.168.42.1 \ - --onboot - -__network_interface eth3 --method dhcp --hotplug - - -# Don't wait for Infiniband interface to be up before reaching systemd network-online.target -__network_interface ib0 --method dhcp --no-network-wait-online - -# active-backup bonding with 2 slaves -__network_interface bond0 \ - --onboot \ - --method static \ - --bond-mode active-backup \ - --bond-miimon 500 \ - --bond-primary eth5 \ - --address 10.205.9.65 \ - --netmask 255.255.224.0 - -__network_interface eth5 \ - --onboot \ - --method manual \ - --bond-master bond0 - -__network_interface eth6 \ - --onboot \ - --method manual \ - --bond-master bond0 - - -# extra config -__network_interface eth0 \ - --method dhcp \ - --extra-config - << DONE -post-up ip route add 10.205.0.0/19 via 10.205.161.1 -post-up ip route add 10.205.96.0/19 via 10.205.161.1 -pre-down ip route del 10.205.0.0/19 via 10.205.161.1 -pre-down ip route del 10.205.96.0/19 via 10.205.161.1 -DONE --------------------------------------------------------------------------------- - - -SEE ALSO --------- -- cdist-type(7) -- Redhat bonding documentation - https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/sec-Using_Channel_Bonding.html - https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Networking_Guide/sec-Using_Channel_Bonding.html - https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/s2-networkscripts-interfaces-chan.html -- Debian bonding documentation - /usr/share/doc/ifenslave-2.6/README.Debian.gz -- Symmetric routing - http://www.microhowto.info/howto/ensure_symmetric_routing_on_a_server_with_multiple_default_gateways.html - - -COPYING -------- -Copyright \(C) 2012-2016 Steven Armstrong. Free use of this software is -granted under the terms of the GNU General Public License version 3 (GPLv3). From 449426d362bac53a51bc94b681602079497052ec Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Thu, 23 Jan 2020 14:43:33 +0100 Subject: [PATCH 06/64] Note that type rewrites network interface files --- cdist/conf/type/__network_interface/man.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cdist/conf/type/__network_interface/man.rst b/cdist/conf/type/__network_interface/man.rst index 22cce84a..d502163a 100644 --- a/cdist/conf/type/__network_interface/man.rst +++ b/cdist/conf/type/__network_interface/man.rst @@ -12,6 +12,8 @@ Configures network interfaces on debian an redhat based systems. Interface names containing a dot are assumed to be vlan tagged sub interfaces. e.g. eth0.10 is vlan 10 on physical device eth0. +Note that this type rewrites network interface files. + REQUIRED PARAMETERS ------------------- From de1a421b68edeb2bf3660f2ed98e109db93e8d88 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 2 Oct 2019 15:39:30 +0200 Subject: [PATCH 07/64] [explorer/init] Support for Darwin and more BusyBox combinations --- cdist/conf/explorer/init | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/cdist/conf/explorer/init b/cdist/conf/explorer/init index a8a7857e..829d6ab8 100755 --- a/cdist/conf/explorer/init +++ b/cdist/conf/explorer/init @@ -23,14 +23,22 @@ # for example at linux this value is "init" or "systemd" in most cases # -uname_s="$(uname -s)" - -case "$uname_s" in +case $(uname -s) in Linux) - (pgrep -P0 -l | awk '/^1[ \t]/ {print $2;}') || true + if command -v pgrep >/dev/null + then + # BusyBox's version of ps does not support some options. + # On Linux systems, we prefer pgrep to get the name of PID1. + (pgrep -P0 -l | awk '/^1[ \t]/ {print $2;}') || true + else + ps -o comm= -p 1 2>/dev/null || cat /proc/1/comm + fi ;; FreeBSD|OpenBSD) - ps -o comm= -p 1 || true + ps -o comm= -p 1 2>/dev/null || true + ;; + Darwin) + basename "$(ps -o comm= -p 1 2>/dev/null)" ;; *) # return a empty string as unknown value From 4fe2dcba891ae52cccbe02553976be2bb7291fd1 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Thu, 30 Jan 2020 18:35:50 +0100 Subject: [PATCH 08/64] [explorer/init] Linux is a mess... --- cdist/conf/explorer/init | 44 +++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/cdist/conf/explorer/init b/cdist/conf/explorer/init index 829d6ab8..ceae2e9f 100755 --- a/cdist/conf/explorer/init +++ b/cdist/conf/explorer/init @@ -25,14 +25,48 @@ case $(uname -s) in Linux) - if command -v pgrep >/dev/null + if test -d /proc/1/ then - # BusyBox's version of ps does not support some options. - # On Linux systems, we prefer pgrep to get the name of PID1. - (pgrep -P0 -l | awk '/^1[ \t]/ {print $2;}') || true + comm_name=$(cat /proc/1/comm) else - ps -o comm= -p 1 2>/dev/null || cat /proc/1/comm + # BusyBox's versions of ps and pgrep do not support some options + # depending on which compile-time options have been used. + # Both pgrep and ps are tried to get the command name + comm_name=$( + pgrep -P0 -l 2>/dev/null | awk '/^1[ \t]/ { print $2 }' + || ps -o comm= -p 1 2>/dev/null) fi + + case $comm_name + in + systemd) + echo systemd + ;; + init) + # It could be anything... + + if test -h /proc/1/exe + then + init_exe=/proc/1/exe + else + init_exe=$(command -v "$comm_name") + fi + + test -x "$comm_exe" || exit 1 + + case $("$comm_exe" --version | head -n 1) + in + *SysV*) + echo init + ;; + *upstart*) + echo upstart + ;; + *) + echo "" + ;; + esac + esac ;; FreeBSD|OpenBSD) ps -o comm= -p 1 2>/dev/null || true From e5d86ffc9360767502469d00a0db1aca72d4f483 Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Sat, 1 Feb 2020 17:08:25 +0100 Subject: [PATCH 09/64] Fix to remove cronjobs when the cronjob expression did not match. --- cdist/conf/type/__cron/gencode-remote | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__cron/gencode-remote b/cdist/conf/type/__cron/gencode-remote index 59398058..8f3c92dc 100755 --- a/cdist/conf/type/__cron/gencode-remote +++ b/cdist/conf/type/__cron/gencode-remote @@ -42,8 +42,12 @@ fi mkdir "$__object/files" echo "$entry" > "$__object/files/entry" -if diff -q "$__object/files/entry" "$__object/explorer/entry" >/dev/null; then - state_is=present +if [ -s "$__object/explorer/entry" ]; then + if diff -q "$__object/files/entry" "$__object/explorer/entry" >/dev/null; then + state_is=present + else + state_is=modified + fi else state_is=absent fi From f3237e5d76c995d138bdf287c00a03d48f4ac742 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Mon, 3 Feb 2020 17:44:47 +0100 Subject: [PATCH 10/64] [consul agent] add support for Debian 10 --- cdist/conf/type/__consul_agent/manifest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/conf/type/__consul_agent/manifest b/cdist/conf/type/__consul_agent/manifest index ee682d72..e00f29ec 100755 --- a/cdist/conf/type/__consul_agent/manifest +++ b/cdist/conf/type/__consul_agent/manifest @@ -209,7 +209,7 @@ case "$os" in [567]) init_sysvinit debian ;; - [89]) + [89]|10) init_systemd ;; *) From 0f420993e1befd2692aca6cae43efb751a4a78de Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Mon, 3 Feb 2020 17:45:34 +0100 Subject: [PATCH 11/64] ++ changelog update --- docs/changelog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/changelog b/docs/changelog index 467c0f22..9f5e73bd 100644 --- a/docs/changelog +++ b/docs/changelog @@ -1,6 +1,9 @@ Changelog --------- +next: + * Type __consul_agent: Add Debian 10 support (Nico Schottelius) + 6.5.0: 2020-01-23 * Type __acl: Add --entry parameter to replace --acl, deprecate --acl (Ander Punnar) * Core: preos: Fix missing configuration file usage, support -g, --config-file option (Darko Poljak) From e82dd35869e00b2fb00b6907b5fc3a960981bc6e Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 30 Sep 2019 18:50:20 +0200 Subject: [PATCH 12/64] [__file] stat explorer patch for systems without stat(1) Some embedded systems (like OpenWrt) do not ship a stat(1) binary. This workaround parses the output of ls(1) and /etc/passwd, /etc/group to gather the information needed. --- cdist/conf/type/__file/explorer/stat | 64 ++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/cdist/conf/type/__file/explorer/stat b/cdist/conf/type/__file/explorer/stat index 13c1c208..91c8cc84 100755 --- a/cdist/conf/type/__file/explorer/stat +++ b/cdist/conf/type/__file/explorer/stat @@ -2,6 +2,7 @@ # # 2013 Steven Armstrong (steven-cdist armstrong.cc) # 2019 Nico Schottelius (nico-cdist at schottelius.org) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -21,29 +22,54 @@ destination="/$__object_id" +fallback() { + # Fallback: Patch the output together, manually. + + ls_line=$(ls -ldn "$destination") + + uid=$(echo "$ls_line" | awk '{ print $3 }') + gid=$(echo "$ls_line" | awk '{ print $4 }') + + owner=$(awk -F: -v uid="$uid" '$3 == uid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/passwd) + group=$(awk -F: -v uid="$uid" '$3 == uid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/group) + + mode_text=$(echo "$ls_line" | awk '{ print $1 }') + mode=$(echo "$mode_text" | awk '{ k=0; for (i=0; i<=8; i++) k += ((substr($1, i+2, 1) ~ /[rwx]/) * 2^(8-i)); printf("%0o", k) }') + + size=$(echo "$ls_line" | awk '{ print $5 }') + links=$(echo "$ls_line" | awk '{ print $2 }') + + printf 'type: %s\nowner: %d %s\ngroup: %d %s\nmode: %s %s\nsize: %d\nlinks: %d\n' \ + "$("$__type_explorer/type")" \ + "$uid" "$owner" \ + "$gid" "$group" \ + "$mode" "$mode_text" \ + "$size" \ + "$links" +} + + # nothing to work with, nothing we could do [ -e "$destination" ] || exit 0 -os=$("$__explorer/os") -case "$os" in - "freebsd"|"netbsd"|"openbsd"|"macosx") + +if ! command -v stat >/dev/null +then + fallback + exit +fi + + +case $("$__explorer/os") +in + freebsd|netbsd|openbsd|macosx) stat -f "type: %HT owner: %Du %Su group: %Dg %Sg mode: %Lp %Sp size: %Dz links: %Dl -" "$destination" | awk '/^type/ { print tolower($0); next; } { print; }' - ;; - alpine) - # busybox stat - stat -c "type: %F -owner: %u %U -group: %g %G -mode: %a %A -size: %s -links: %h -" "$destination" +" "$destination" | awk '/^type/ { print tolower($0); next } { print }' ;; solaris) ls1="$( ls -ld "$destination" )" @@ -77,12 +103,14 @@ links: %h echo "links: $( echo "$ls1" | awk '{print $2}' )" ;; *) - stat --printf="type: %F + # NOTE: Do not use --printf here as it is not supported by BusyBox stat. + # NOTE: BusyBox's stat might not support the "-c" option, in which case + # we fall through to the shell fallback. + stat -c "type: %F owner: %u %U group: %g %G mode: %a %A size: %s -links: %h -" "$destination" - ;; +links: %h" "$destination" 2>/dev/null || fallback + ;; esac From 3b5433d63af27f06f3c44b121b21d7e0520af7bf Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 3 Feb 2020 18:12:27 +0100 Subject: [PATCH 13/64] [__directory] stat explorer patch for systems without stat(1) Some embedded systems (like OpenWrt) do not ship a stat(1) binary. This workaround parses the output of ls(1) and /etc/passwd, /etc/group to gather the information needed. --- cdist/conf/type/__directory/explorer/stat | 48 +++++++++++++++++------ 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/cdist/conf/type/__directory/explorer/stat b/cdist/conf/type/__directory/explorer/stat index 03d466ba..105d894f 100755 --- a/cdist/conf/type/__directory/explorer/stat +++ b/cdist/conf/type/__directory/explorer/stat @@ -1,6 +1,7 @@ #!/bin/sh # # 2013 Steven Armstrong (steven-cdist armstrong.cc) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -20,24 +21,43 @@ destination="/$__object_id" +fallback() { + # Patch the output together, manually + + ls_line=$(ls -ldn "$destination") + + uid=$(echo "$ls_line" | awk '{ print $3 }') + gid=$(echo "$ls_line" | awk '{ print $4 }') + + owner=$(awk -F: -v uid="$uid" '$3 == uid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/passwd) + group=$(awk -F: -v uid="$uid" '$3 == uid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/group) + + mode_text=$(echo "$ls_line" | awk '{ print $1 }') + mode=$(echo "$mode_text" | awk '{ k=0; for (i=0; i<=8; i++) k += ((substr($1, i+2, 1) ~ /[rwx]/) * 2^(8-i)); printf("%0o", k) }') + + printf 'type: %s\nowner: %d %s\ngroup: %d %s\nmode: %s %s\n' \ + "$("$__type_explorer/type")" \ + "$uid" "$owner" \ + "$gid" "$group" \ + "$mode" "$mode_text" +} + # nothing to work with, nothing we could do [ -e "$destination" ] || exit 0 -os=$("$__explorer/os") -case "$os" in +if ! command -v stat >/dev/null +then + fallback + exit +fi + +case $("$__explorer/os") in "freebsd"|"netbsd"|"openbsd"|"macosx") stat -f "type: %HT owner: %Du %Su group: %Dg %Sg mode: %Lp %Sp -" "$destination" | awk '/^type/ { print tolower($0); next; } { print; }' - ;; - alpine) - stat -c "type: %F -owner: %u %U -group: %g %G -mode: %a %A -" "$destination" +" "$destination" | awk '/^type/ { print tolower($0); next } { print }' ;; solaris) ls1="$( ls -ld "$destination" )" @@ -69,10 +89,12 @@ mode: %a %A echo "mode: $octets $( echo "$ls1" | awk '{print $1}' )" ;; *) - stat --printf="type: %F + # NOTE: Do not use --printf here as it is not supported by BusyBox stat. + # NOTE: BusyBox's stat might not support the "-c" option, in which case + # we fall through to the shell fallback. + stat -c "type: %F owner: %u %U group: %g %G -mode: %a %A -" "$destination" +mode: %a %A" "$destination" 2>/dev/null || fallback ;; esac From 984e0dc8c4975904057a7ab0a8c9d357ed0b4fdf Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 3 Feb 2020 19:29:04 +0100 Subject: [PATCH 14/64] [explorer/os_release] Add fallbacks to /usr/lib/os-release and /var/run/os-release --- cdist/conf/explorer/os_release | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/cdist/conf/explorer/os_release b/cdist/conf/explorer/os_release index cfc01004..6489446b 100644 --- a/cdist/conf/explorer/os_release +++ b/cdist/conf/explorer/os_release @@ -1,6 +1,7 @@ #!/bin/sh # # 2018 Adam Dej (dejko.a at gmail.com) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -21,6 +22,17 @@ # See os-release(5) and http://0pointer.de/blog/projects/os-release -set +e +if test -f /etc/os-release +then + # Linux and FreeBSD (usually a symlink) + cat /etc/os-release +elif test -f /usr/lib/os-release +then + # systemd + cat /usr/lib/os-release +elif test -f /var/run/os-release +then + # FreeBSD (created by os-release service) + cat /var/run/os-release +fi -cat /etc/os-release || cat /usr/lib/os-release || true From 7a5d6d5a7d602863cd7d74bfb4e13a8bb59c5944 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Tue, 4 Feb 2020 07:45:04 +0100 Subject: [PATCH 15/64] ++changelog --- docs/changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog b/docs/changelog index 9f5e73bd..bf0a8777 100644 --- a/docs/changelog +++ b/docs/changelog @@ -3,6 +3,8 @@ Changelog next: * Type __consul_agent: Add Debian 10 support (Nico Schottelius) + * Explorer os_release: Add fallbacks (Dennis Camera) + * Types __file, __directory: Add fallback for systems without stat (Dennis Camera) 6.5.0: 2020-01-23 * Type __acl: Add --entry parameter to replace --acl, deprecate --acl (Ander Punnar) From 08d5814e2cc8ea6a204afca91bec7b831116112b Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Sun, 9 Feb 2020 20:37:06 +0200 Subject: [PATCH 16/64] __package_apt: update index cache, on installation, when it is older than one day --- cdist/conf/type/__package_apt/gencode-remote | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cdist/conf/type/__package_apt/gencode-remote b/cdist/conf/type/__package_apt/gencode-remote index 699eb0c9..b3184a9c 100755 --- a/cdist/conf/type/__package_apt/gencode-remote +++ b/cdist/conf/type/__package_apt/gencode-remote @@ -74,6 +74,11 @@ fi case "$state_should" in present) + cat << EOF +if [ -f /var/cache/apt/pkgcache.bin ] && [ "\$( stat --format %Y /var/cache/apt/pkgcache.bin )" -lt "\$( date +%s -d '-1 day' )" ] +then echo apt-get update > /dev/null 2>&1 || true +fi +EOF if [ -n "$version" ]; then name="${name}=${version}" fi From b3bad9468de78cf90e8ce92a59c8bb3d285883fe Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Sun, 9 Feb 2020 20:43:09 +0200 Subject: [PATCH 17/64] __package_apt: pkgcache.bin may not exist --- cdist/conf/type/__package_apt/gencode-remote | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/conf/type/__package_apt/gencode-remote b/cdist/conf/type/__package_apt/gencode-remote index b3184a9c..cb79e886 100755 --- a/cdist/conf/type/__package_apt/gencode-remote +++ b/cdist/conf/type/__package_apt/gencode-remote @@ -75,7 +75,7 @@ fi case "$state_should" in present) cat << EOF -if [ -f /var/cache/apt/pkgcache.bin ] && [ "\$( stat --format %Y /var/cache/apt/pkgcache.bin )" -lt "\$( date +%s -d '-1 day' )" ] +if [ ! -f /var/cache/apt/pkgcache.bin ] || [ "\$( stat --format %Y /var/cache/apt/pkgcache.bin )" -lt "\$( date +%s -d '-1 day' )" ] then echo apt-get update > /dev/null 2>&1 || true fi EOF From bcefeb240c81fd263763c794acc7f6ce0b8f6db0 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Mon, 10 Feb 2020 15:51:15 +0100 Subject: [PATCH 18/64] add note about IPv6, because people ask --- docs/src/index.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/src/index.rst b/docs/src/index.rst index 5e54d8fc..31c044dc 100644 --- a/docs/src/index.rst +++ b/docs/src/index.rst @@ -2,8 +2,9 @@ cdist - usable configuration management ======================================= cdist is a usable configuration management system. -It adheres to the KISS principle and +It adheres to the KISS principle and is being used in small up to enterprise grade environments. +It natively supports IPv6 since the first release. .. toctree:: From 710e99f240ef616c6c1978167749b877b3d1e8dc Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Thu, 13 Feb 2020 17:29:44 +0200 Subject: [PATCH 19/64] __mysql_privileges: fix quoting --- cdist/conf/type/__mysql_privileges/explorer/state | 2 +- cdist/conf/type/__mysql_privileges/gencode-remote | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/cdist/conf/type/__mysql_privileges/explorer/state b/cdist/conf/type/__mysql_privileges/explorer/state index 0cfbaacd..4f13a70c 100755 --- a/cdist/conf/type/__mysql_privileges/explorer/state +++ b/cdist/conf/type/__mysql_privileges/explorer/state @@ -30,7 +30,7 @@ host="$( cat "$__object/parameter/host" )" check_privileges="$( mysql -B -N -e "show grants for '$user'@'$host'" \ - | grep -Ei "^grant $privileges on .$database.\..$table. to " || true )" + | grep -Ei "^grant $privileges on .$database.\..?$table.? to " || true )" if [ -n "$check_privileges" ] then diff --git a/cdist/conf/type/__mysql_privileges/gencode-remote b/cdist/conf/type/__mysql_privileges/gencode-remote index bcd362e6..20975c50 100755 --- a/cdist/conf/type/__mysql_privileges/gencode-remote +++ b/cdist/conf/type/__mysql_privileges/gencode-remote @@ -37,13 +37,18 @@ user="$( cat "$__object/parameter/user" )" host="$( cat "$__object/parameter/host" )" +if [ "$table" != '*' ] +then + table="$( printf '`%s`' "$table" )" +fi + case "$state_should" in present) - echo "mysql -e 'grant $privileges on \`$database\`.\`$table\` to \`$user\`@\`$host\`'" + echo "mysql -e 'grant $privileges on \`$database\`.$table to \`$user\`@\`$host\`'" echo "grant $privileges on $database.$table to $user@$host" >> "$__messages_out" ;; absent) - echo "mysql -e 'revoke $privileges on \`$database\`.\`$table\` from \`$user\`@\`$host\`'" + echo "mysql -e 'revoke $privileges on \`$database\`.$table from \`$user\`@\`$host\`'" echo "revoke $privileges on $database.$table from $user@$host" >> "$__messages_out" ;; esac From b7483d73ebc5a95c96adc4a40173ce5015173eeb Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Thu, 13 Feb 2020 17:38:19 +0200 Subject: [PATCH 20/64] __mysql_privileges: fix shellcheck --- cdist/conf/type/__mysql_privileges/gencode-remote | 1 + 1 file changed, 1 insertion(+) diff --git a/cdist/conf/type/__mysql_privileges/gencode-remote b/cdist/conf/type/__mysql_privileges/gencode-remote index 20975c50..0656699f 100755 --- a/cdist/conf/type/__mysql_privileges/gencode-remote +++ b/cdist/conf/type/__mysql_privileges/gencode-remote @@ -39,6 +39,7 @@ host="$( cat "$__object/parameter/host" )" if [ "$table" != '*' ] then + # shellcheck disable=SC2016 table="$( printf '`%s`' "$table" )" fi From f771840178ed2586a4abc47f5e513da2309d5128 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Thu, 13 Feb 2020 17:38:34 +0200 Subject: [PATCH 21/64] __mysql_privileges: fix typo --- cdist/conf/type/__mysql_privileges/man.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/conf/type/__mysql_privileges/man.rst b/cdist/conf/type/__mysql_privileges/man.rst index 8208d7d4..b72c9eba 100644 --- a/cdist/conf/type/__mysql_privileges/man.rst +++ b/cdist/conf/type/__mysql_privileges/man.rst @@ -17,7 +17,7 @@ REQUIRED PARAMETERS database Name of database. -User +user Name of user. From e5f9d320049dea5acef6e505cc7a4966ecbd72c6 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Fri, 14 Feb 2020 16:07:06 +0100 Subject: [PATCH 22/64] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index bf0a8777..3f69899a 100644 --- a/docs/changelog +++ b/docs/changelog @@ -5,6 +5,7 @@ next: * Type __consul_agent: Add Debian 10 support (Nico Schottelius) * Explorer os_release: Add fallbacks (Dennis Camera) * Types __file, __directory: Add fallback for systems without stat (Dennis Camera) + * Type __mysql_privileges: Fix quoting (Ander Punnar) 6.5.0: 2020-01-23 * Type __acl: Add --entry parameter to replace --acl, deprecate --acl (Ander Punnar) From 1be5a9d3163fc5b8aa107764ea5aab41f46e860a Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Fri, 14 Feb 2020 19:19:12 +0200 Subject: [PATCH 23/64] __package_apt: add note about updating index --- cdist/conf/type/__package_apt/man.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cdist/conf/type/__package_apt/man.rst b/cdist/conf/type/__package_apt/man.rst index a3a70d91..a1691eac 100644 --- a/cdist/conf/type/__package_apt/man.rst +++ b/cdist/conf/type/__package_apt/man.rst @@ -11,6 +11,9 @@ DESCRIPTION apt-get is usually used on Debian and variants (like Ubuntu) to manage packages. +This type will also update package index, if it is older +than one day, to avoid missing package error messages. + REQUIRED PARAMETERS ------------------- From 869a38676f97b7863997b7d2c257447a63344368 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Fri, 14 Feb 2020 19:22:06 +0200 Subject: [PATCH 24/64] __package_apt: add comment about package index update --- cdist/conf/type/__package_apt/gencode-remote | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cdist/conf/type/__package_apt/gencode-remote b/cdist/conf/type/__package_apt/gencode-remote index cb79e886..e02564a2 100755 --- a/cdist/conf/type/__package_apt/gencode-remote +++ b/cdist/conf/type/__package_apt/gencode-remote @@ -74,6 +74,9 @@ fi case "$state_should" in present) + # following is bit ugly, but important hack. + # due to how cdist config run works, there isn't + # currently better way to do it :( cat << EOF if [ ! -f /var/cache/apt/pkgcache.bin ] || [ "\$( stat --format %Y /var/cache/apt/pkgcache.bin )" -lt "\$( date +%s -d '-1 day' )" ] then echo apt-get update > /dev/null 2>&1 || true From 48bff6656322eecd940a1e0a2c272fe2303268f6 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Fri, 14 Feb 2020 21:55:35 +0100 Subject: [PATCH 25/64] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index 3f69899a..734db7ea 100644 --- a/docs/changelog +++ b/docs/changelog @@ -6,6 +6,7 @@ next: * Explorer os_release: Add fallbacks (Dennis Camera) * Types __file, __directory: Add fallback for systems without stat (Dennis Camera) * Type __mysql_privileges: Fix quoting (Ander Punnar) + * Type __package_apt: Update package index if it is older than one day (Ander Punnar) 6.5.0: 2020-01-23 * Type __acl: Add --entry parameter to replace --acl, deprecate --acl (Ander Punnar) From a761d4842ca36688fd6355a63185da985528366a Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Sat, 15 Feb 2020 08:21:24 +0100 Subject: [PATCH 26/64] Add check for the state parameter in manifest. This only allow following cases: - present - absent else, it will abort with an error message. --- cdist/conf/type/__cron/manifest | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cdist/conf/type/__cron/manifest b/cdist/conf/type/__cron/manifest index 53973e07..3017e2fd 100755 --- a/cdist/conf/type/__cron/manifest +++ b/cdist/conf/type/__cron/manifest @@ -22,3 +22,12 @@ if [ -f "$__object/parameter/raw" ] && [ -f "$__object/parameter/raw_command" ]; echo "ERROR: both raw and raw_command specified" >&2 exit 1 fi + +case "$(cat "$__object/parameter/state" 2>/dev/null || echo "present")" in + present) ;; + absent) ;; + + *) + echo "ERROR: unkown cron state" >&2 + exit 2 +esac From 5e6e17b3e55ea5b53a3ad9fe28f1d1c422121369 Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Sat, 15 Feb 2020 09:46:23 +0100 Subject: [PATCH 27/64] Moved default parameter values from scripts to cdist parameter handling. For more generalisation, the default parameter values are now handled by cdist instead of trying to get a value and use a default if parameter is not given. It handles the default values in a more general way, instead of write one default in (possibly) multiple places. Problem occurred when checking the 'state' parameter, which required to set a default value in two places. --- cdist/conf/type/__cron/gencode-remote | 12 ++++++------ cdist/conf/type/__cron/manifest | 2 +- .../conf/type/__cron/parameter/default/day_of_month | 1 + cdist/conf/type/__cron/parameter/default/day_of_week | 1 + cdist/conf/type/__cron/parameter/default/hour | 1 + cdist/conf/type/__cron/parameter/default/minute | 1 + cdist/conf/type/__cron/parameter/default/month | 1 + cdist/conf/type/__cron/parameter/default/state | 1 + 8 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 cdist/conf/type/__cron/parameter/default/day_of_month create mode 100644 cdist/conf/type/__cron/parameter/default/day_of_week create mode 100644 cdist/conf/type/__cron/parameter/default/hour create mode 100644 cdist/conf/type/__cron/parameter/default/minute create mode 100644 cdist/conf/type/__cron/parameter/default/month create mode 100644 cdist/conf/type/__cron/parameter/default/state diff --git a/cdist/conf/type/__cron/gencode-remote b/cdist/conf/type/__cron/gencode-remote index 8f3c92dc..9debbc47 100755 --- a/cdist/conf/type/__cron/gencode-remote +++ b/cdist/conf/type/__cron/gencode-remote @@ -31,11 +31,11 @@ if [ -f "$__object/parameter/raw" ]; then elif [ -f "$__object/parameter/raw_command" ]; then entry="$command" else - minute="$(cat "$__object/parameter/minute" 2>/dev/null || echo "*")" - hour="$(cat "$__object/parameter/hour" 2>/dev/null || echo "*")" - day_of_month="$(cat "$__object/parameter/day_of_month" 2>/dev/null || echo "*")" - month="$(cat "$__object/parameter/month" 2>/dev/null || echo "*")" - day_of_week="$(cat "$__object/parameter/day_of_week" 2>/dev/null || echo "*")" + minute="$(cat "$__object/parameter/minute")" + hour="$(cat "$__object/parameter/hour")" + day_of_month="$(cat "$__object/parameter/day_of_month")" + month="$(cat "$__object/parameter/month")" + day_of_week="$(cat "$__object/parameter/day_of_week")" entry="$minute $hour $day_of_month $month $day_of_week $command # $name" fi @@ -52,7 +52,7 @@ else state_is=absent fi -state_should="$(cat "$__object/parameter/state" 2>/dev/null || echo "present")" +state_should="$(cat "$__object/parameter/state")" [ "$state_is" = "$state_should" ] && exit 0 diff --git a/cdist/conf/type/__cron/manifest b/cdist/conf/type/__cron/manifest index 3017e2fd..e7b51863 100755 --- a/cdist/conf/type/__cron/manifest +++ b/cdist/conf/type/__cron/manifest @@ -23,7 +23,7 @@ if [ -f "$__object/parameter/raw" ] && [ -f "$__object/parameter/raw_command" ]; exit 1 fi -case "$(cat "$__object/parameter/state" 2>/dev/null || echo "present")" in +case "$(cat "$__object/parameter/state")" in present) ;; absent) ;; diff --git a/cdist/conf/type/__cron/parameter/default/day_of_month b/cdist/conf/type/__cron/parameter/default/day_of_month new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/cdist/conf/type/__cron/parameter/default/day_of_month @@ -0,0 +1 @@ +* diff --git a/cdist/conf/type/__cron/parameter/default/day_of_week b/cdist/conf/type/__cron/parameter/default/day_of_week new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/cdist/conf/type/__cron/parameter/default/day_of_week @@ -0,0 +1 @@ +* diff --git a/cdist/conf/type/__cron/parameter/default/hour b/cdist/conf/type/__cron/parameter/default/hour new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/cdist/conf/type/__cron/parameter/default/hour @@ -0,0 +1 @@ +* diff --git a/cdist/conf/type/__cron/parameter/default/minute b/cdist/conf/type/__cron/parameter/default/minute new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/cdist/conf/type/__cron/parameter/default/minute @@ -0,0 +1 @@ +* diff --git a/cdist/conf/type/__cron/parameter/default/month b/cdist/conf/type/__cron/parameter/default/month new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/cdist/conf/type/__cron/parameter/default/month @@ -0,0 +1 @@ +* diff --git a/cdist/conf/type/__cron/parameter/default/state b/cdist/conf/type/__cron/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__cron/parameter/default/state @@ -0,0 +1 @@ +present From ef089d1c6114e840c4b8022d43322bdb18b96e8f Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Mon, 6 Jan 2020 10:42:12 +0100 Subject: [PATCH 28/64] [__systemd_service] new type to manage the state of systemd services --- .../type/__systemd_service/explorer/state | 43 +++++++ .../type/__systemd_service/gencode-remote | 98 ++++++++++++++++ cdist/conf/type/__systemd_service/man.rst | 110 ++++++++++++++++++ .../type/__systemd_service/parameter/boolean | 1 + .../__systemd_service/parameter/default/state | 1 + .../type/__systemd_service/parameter/optional | 3 + 6 files changed, 256 insertions(+) create mode 100755 cdist/conf/type/__systemd_service/explorer/state create mode 100755 cdist/conf/type/__systemd_service/gencode-remote create mode 100644 cdist/conf/type/__systemd_service/man.rst create mode 100644 cdist/conf/type/__systemd_service/parameter/boolean create mode 100644 cdist/conf/type/__systemd_service/parameter/default/state create mode 100644 cdist/conf/type/__systemd_service/parameter/optional diff --git a/cdist/conf/type/__systemd_service/explorer/state b/cdist/conf/type/__systemd_service/explorer/state new file mode 100755 index 00000000..f5f751d4 --- /dev/null +++ b/cdist/conf/type/__systemd_service/explorer/state @@ -0,0 +1,43 @@ +#!/bin/sh -e +# explorer/state +# +# 2020 Matthias Stecher +# +# 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 . +# + +# Check if the service is running or stopped. +# +# The explorer must check before if the service exist, because 'systemctl is-active' +# will return "inactive" even if there is no service there: +# systemctl cat foo # does not exist +# systemctl is-active foo # is "inactive" + + +# get name of the service +if [ -f "$__object/parameter/name" ]; then + name="$(cat "$__object/parameter/name")" +else + name="$__object_id" +fi + + +# check if the service exist, else exit without output (also if systemd doesn't exist) +# do not exit here with an error code, will be done in the gencode-remote script +systemctl cat "$name" > /dev/null 2>&1 || exit 0 + +# print if the service is running or not +systemctl is-active -q "$name" && printf "running" || printf "stopped" diff --git a/cdist/conf/type/__systemd_service/gencode-remote b/cdist/conf/type/__systemd_service/gencode-remote new file mode 100755 index 00000000..c867ff22 --- /dev/null +++ b/cdist/conf/type/__systemd_service/gencode-remote @@ -0,0 +1,98 @@ +#!/bin/sh -e +# gencode-remote +# +# 2020 Matthias Stecher +# +# 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 . +# + +# Checks the given state of the service and set it to the given +# state. Optionally, it executes the action if service running. + + +# get name of the service +name="$__object/parameter/name" +if [ -f "$name" ]; then + name="$(cat "$name")" +else + name="$__object_id" +fi + + +# read current status and parameters +state="$(cat "$__object/explorer/state")" +should="$(cat "$__object/parameter/state")" + +# if systemd/service does not exist +if [ -z "$state" ]; then + printf "systemd or service '%s' does not exist!\n" "$name" >&2 + exit 1 +fi + + +# save the action required +required_action="" + +# check the state of the service that should be +if [ "$state" != "$should" ]; then + # select what to do to get the $should state + case "$should" in + running) + if [ "$state" = "stopped" ]; then required_action="start"; fi + ;; + + stopped) + if [ "$state" = "running" ]; then required_action="stop"; fi + ;; + esac +fi + +# check if the action can be achieved if given +if [ -f "$__object/parameter/action" ] \ + && [ -z "$required_action" ] && [ "$state" = "running" ]; then + + # there must be an action + action="$(cat "$__object/parameter/action")" + + # select the action to the required element + case "$action" in + restart) + required_action="restart" + ;; + + reload) + required_action="reload" + ;; + + *) + printf "action '%s' does not exist!" "$action" >&2 + exit 2 + esac + + # Make a special check: only do this action if a dependency did something + # it is required that the dependencies write there action to $__messages_in + if [ -f "$__object/parameter/if-required" ]; then + # exit here if there are no changes from the dependencies affected (nothing to do) + if ! grep -q -f "$__object/require" "$__messages_in"; then exit 0; fi + fi +fi + +# print the execution command if a action given +if [ -n "$required_action" ]; then + # also print it as message + echo "$required_action" >> "$__messages_out" + echo "systemctl $required_action '$name'" +fi diff --git a/cdist/conf/type/__systemd_service/man.rst b/cdist/conf/type/__systemd_service/man.rst new file mode 100644 index 00000000..678cee29 --- /dev/null +++ b/cdist/conf/type/__systemd_service/man.rst @@ -0,0 +1,110 @@ +cdist-type__systemd-service(7) +============================== + +NAME +---- +cdist-type__systemd-service - Controls a systemd service state + +DESCRIPTION +----------- +This type controls systemd services to define a state of the service, +or an action like reloading or restarting. It is useful to reload a +service after configuration applied or shutdown one service. + +The activation or deactivation is out of scope. Look for the +:strong:`cdist-type__systemd_util`\ (7) type instead. + +REQUIRED PARAMETERS +------------------- + +None. + +OPTIONAL PARAMETERS +------------------- + +name + String which will used as name instead of the object id. + +state + The state which the service should be in: + + running + Service should run (default) + + stoppend + Service should stopped + +action + Executes an action on on the service. It will only execute it if the + service keeps the state **running**. There are following actions, where: + + reload + Reloads the service + + restart + Restarts the service + +BOOLEAN PARAMETERS +----------------- + +if-required + Only execute the action if minimum one required type outputs a message to + **$__messages_out**. Through this, the action should only executed if a + dependency did something. The action will not executed if no dependencies + given. + +MESSAGES +-------- + +start + Started the service + +stop + Stopped the service + +restart + Restarted the service + +reload + Reloaded the service + +ABORTS +------ +Aborts in following cases: + +systemd or the service does not exist + +EXAMPLES +-------- +.. code-block:: sh + + # service must run + __systemd_service nginx + + # service must stopped + __systemd_service sshd \ + --state stopped + + # restart the service + __systemd_service apache2 \ + --action restart + + # makes sure the service exist with an alternative name + __systemd_service foo \ + --name sshd + + # reload the service for a modified configuration file + # only reloads the service if the file really changed + require="__config_file/etc/foo.conf" __systemd_service foo \ + --action reload --if-required + +AUTHORS +------- +Matthias Stecher + +COPYRIGHT +--------- +Copyright \(C) 2020 Matthias Stecher. 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. diff --git a/cdist/conf/type/__systemd_service/parameter/boolean b/cdist/conf/type/__systemd_service/parameter/boolean new file mode 100644 index 00000000..a4bccb66 --- /dev/null +++ b/cdist/conf/type/__systemd_service/parameter/boolean @@ -0,0 +1 @@ +if-required diff --git a/cdist/conf/type/__systemd_service/parameter/default/state b/cdist/conf/type/__systemd_service/parameter/default/state new file mode 100644 index 00000000..a2ae71b3 --- /dev/null +++ b/cdist/conf/type/__systemd_service/parameter/default/state @@ -0,0 +1 @@ +running diff --git a/cdist/conf/type/__systemd_service/parameter/optional b/cdist/conf/type/__systemd_service/parameter/optional new file mode 100644 index 00000000..fc78265f --- /dev/null +++ b/cdist/conf/type/__systemd_service/parameter/optional @@ -0,0 +1,3 @@ +name +state +action From 58841fc4bfd8dbeb82717fe3638b3bb4d2ed017b Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sat, 15 Feb 2020 12:20:41 +0100 Subject: [PATCH 29/64] ++changelog --- docs/changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog b/docs/changelog index 734db7ea..f687e5ed 100644 --- a/docs/changelog +++ b/docs/changelog @@ -7,6 +7,8 @@ next: * Types __file, __directory: Add fallback for systems without stat (Dennis Camera) * Type __mysql_privileges: Fix quoting (Ander Punnar) * Type __package_apt: Update package index if it is older than one day (Ander Punnar) + * Type __cron: Fix job removal if 'is' and 'should' don't match (Matthias Stecher) + * New type: __systemd_service (Matthias Stecher) 6.5.0: 2020-01-23 * Type __acl: Add --entry parameter to replace --acl, deprecate --acl (Ander Punnar) From a1536933ab066671e09aaf47a3c6101a68a6b60f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Floure?= Date: Sat, 15 Feb 2020 08:51:29 +0100 Subject: [PATCH 30/64] Fix password command synthax in __postgres_role --- cdist/conf/type/__postgres_role/gencode-remote | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/conf/type/__postgres_role/gencode-remote b/cdist/conf/type/__postgres_role/gencode-remote index 977832c9..282294c9 100755 --- a/cdist/conf/type/__postgres_role/gencode-remote +++ b/cdist/conf/type/__postgres_role/gencode-remote @@ -54,7 +54,7 @@ case "$state_should" in [ -n "$password" ] && password="PASSWORD '$password'" cat << EOF -su - '$postgres_user' -c "psql postgres -wc 'CREATE ROLE \"$name\" WITH $password $booleans;'" +su - '$postgres_user' -c "psql postgres -wc \"CREATE ROLE \\\\\"$name\\\\\" WITH $password $booleans;\"" EOF ;; absent) From cda77e5e8a44eabde7e39396c39fd34daba1c702 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sat, 15 Feb 2020 14:35:29 +0100 Subject: [PATCH 31/64] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index f687e5ed..d5ed1b06 100644 --- a/docs/changelog +++ b/docs/changelog @@ -9,6 +9,7 @@ next: * Type __package_apt: Update package index if it is older than one day (Ander Punnar) * Type __cron: Fix job removal if 'is' and 'should' don't match (Matthias Stecher) * New type: __systemd_service (Matthias Stecher) + * Type __postgres_role: Fix password command synthax (Timothée Floure) 6.5.0: 2020-01-23 * Type __acl: Add --entry parameter to replace --acl, deprecate --acl (Ander Punnar) From 9f3747cf3f664ba5cc2f74ec356d833e7eda2621 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sat, 15 Feb 2020 14:36:26 +0100 Subject: [PATCH 32/64] Release 6.5.1 --- docs/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog b/docs/changelog index d5ed1b06..9f1e6245 100644 --- a/docs/changelog +++ b/docs/changelog @@ -1,7 +1,7 @@ Changelog --------- -next: +6.5.1: 2020-02-15 * Type __consul_agent: Add Debian 10 support (Nico Schottelius) * Explorer os_release: Add fallbacks (Dennis Camera) * Types __file, __directory: Add fallback for systems without stat (Dennis Camera) From 0640b02f90d92e11f6a4f8b7c0110d9b5a9bfb89 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sat, 15 Feb 2020 14:59:12 +0100 Subject: [PATCH 33/64] Fix too short title underline --- cdist/conf/type/__systemd_service/man.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/conf/type/__systemd_service/man.rst b/cdist/conf/type/__systemd_service/man.rst index 678cee29..7eca398b 100644 --- a/cdist/conf/type/__systemd_service/man.rst +++ b/cdist/conf/type/__systemd_service/man.rst @@ -45,7 +45,7 @@ action Restarts the service BOOLEAN PARAMETERS ------------------ +------------------ if-required Only execute the action if minimum one required type outputs a message to From c09165d1228e887e2fb4dad456c6b1409211a499 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sat, 15 Feb 2020 21:05:24 +0100 Subject: [PATCH 34/64] Fix spelling --- docs/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog b/docs/changelog index 9f1e6245..bd767b9d 100644 --- a/docs/changelog +++ b/docs/changelog @@ -9,7 +9,7 @@ Changelog * Type __package_apt: Update package index if it is older than one day (Ander Punnar) * Type __cron: Fix job removal if 'is' and 'should' don't match (Matthias Stecher) * New type: __systemd_service (Matthias Stecher) - * Type __postgres_role: Fix password command synthax (Timothée Floure) + * Type __postgres_role: Fix password command syntax (Timothée Floure) 6.5.0: 2020-01-23 * Type __acl: Add --entry parameter to replace --acl, deprecate --acl (Ander Punnar) From 70200cd28fe9b35670f574e77d49e747f23072f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Floure?= Date: Tue, 21 Jan 2020 10:06:09 +0100 Subject: [PATCH 35/64] Refactor __consul_agent type to support distribution packages --- cdist/conf/type/__consul_agent/man.rst | 3 + cdist/conf/type/__consul_agent/manifest | 373 +++++++++++------- .../type/__consul_agent/parameter/boolean | 1 + 3 files changed, 225 insertions(+), 152 deletions(-) diff --git a/cdist/conf/type/__consul_agent/man.rst b/cdist/conf/type/__consul_agent/man.rst index 966abc60..62ee70bb 100644 --- a/cdist/conf/type/__consul_agent/man.rst +++ b/cdist/conf/type/__consul_agent/man.rst @@ -116,6 +116,9 @@ verify-incoming verify-outgoing enforce the use of TLS and verify the peers authenticity on outgoing connections +use-distribution-package + uses distribution package instead of upstream binary + EXAMPLES -------- diff --git a/cdist/conf/type/__consul_agent/manifest b/cdist/conf/type/__consul_agent/manifest index e00f29ec..599f15b4 100755 --- a/cdist/conf/type/__consul_agent/manifest +++ b/cdist/conf/type/__consul_agent/manifest @@ -2,6 +2,7 @@ # # 2015 Steven Armstrong (steven-cdist at armstrong.cc) # 2015-2019 Nico Schottelius (nico-cdist at schottelius.org) +# 2019 Timothée Floure (timothee.floure at ungleich.ch) # # This file is part of cdist. # @@ -19,133 +20,64 @@ # along with cdist. If not, see . # - os=$(cat "$__global/explorer/os") -case "$os" in - alpine|scientific|centos|debian|devuan|redhat|ubuntu) - # whitelist safeguard - : - ;; - *) - 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 - ;; -esac +### +# Type parameters. state="$(cat "$__object/parameter/state")" user="$(cat "$__object/parameter/user")" group="$(cat "$__object/parameter/group")" +release=$(cat "$__global/explorer/lsb_release") +if [ -f "$__object/parameter/use-distribution-package" ]; then + use_distribution_package=1 +fi + +### +# Those are default that might be overriden by os-specific logic. + data_dir="/var/lib/consul" conf_dir="/etc/consul/conf.d" conf_file="config.json" +tls_dir="$conf_dir/tls" -# FIXME: there has got to be a better way to handle the dependencies in this case -case "$state" in - present) - __group "$group" --system --state "$state" - require="__group/$group" \ - __user "$user" --system --gid "$group" \ - --home "$data_dir" --state "$state" - export require="__user/consul" - ;; - absent) - echo "Sorry, state=absent currently not supported :-(" >&2 - exit 1 - require="$__object_name" \ - __user "$user" --system --gid "$group" --state "$state" - require="__user/$user" \ - __group "$group" --system --state "$state" - ;; -esac +### +# Sane deployment, based on distribution package when available. -__directory /etc/consul \ - --owner root --group "$group" --mode 750 --state "$state" -require="__directory/etc/consul" \ - __directory "$conf_dir" \ - --owner root --group "$group" --mode 750 --state "$state" +distribution_setup () { + case "$os" in + debian) + # consul is only available starting Debian 10 (buster). + # See https://packages.debian.org/buster/consul + if [ $release -lt 10 ]; then + echo "Consul is not available for your debian release." >&2 + echo "Please use the 'manual' (i.e. non-package) installation or \ + upgrade the target system." >&2 + exit 1 + fi -if [ -f "$__object/parameter/ca-file-source" ] || [ -f "$__object/parameter/cert-file-source" ] || [ -f "$__object/parameter/key-file-source" ]; then - # create directory for ssl certs - require="__directory/etc/consul" \ - __directory /etc/consul/ssl \ - --owner root --group "$group" --mode 750 --state "$state" -fi + # Override previously defined environment to match debian packaging. + conf_dir='/etc/consul.d' + user='consul' + grou='consul' + ;; + *) + echo "Your operating system ($os) is currently not supported with the \ + --use-distribution-package flag (${__type##*/})." >&2 + echo "Please use non-package installation or contribute an \ + implementation for if you can." >&2 + exit 1 + ;; + esac -__directory "$data_dir" \ - --owner "$user" --group "$group" --mode 770 --state "$state" + # Install consul package. + __package consul --state $state + export config_deployment_requires="__package/consul" +} -# Generate json config file -( -echo "{" - -# parameters we define ourself -printf ' "data_dir": "%s"\n' "$data_dir" - -cd "$__object/parameter/" -for param in *; do - case "$param" in - state|user|group|json-config) continue ;; - ca-file-source|cert-file-source|key-file-source) - source="$(cat "$__object/parameter/$param")" - destination="/etc/consul/ssl/${source##*/}" - require="__directory/etc/consul/ssl" \ - __file "$destination" \ - --owner root --group consul --mode 640 \ - --source "$source" \ - --state "$state" - key="$(echo "${param%-*}" | tr '-' '_')" - printf ' ,"%s": "%s"\n' "$key" "$destination" - ;; - disable-remote-exec|disable-update-check|leave-on-terminate|rejoin-after-leave|server|enable-syslog|verify-incoming|verify-outgoing) - # handle boolean parameters - key="$(echo "$param" | tr '-' '_')" - printf ' ,"%s": true\n' "$key" - ;; - retry-join) - # join multiple parameters into json array - retry_join="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join")" - # remove trailing , - printf ' ,"retry_join": [%s]\n' "${retry_join%*,}" - ;; - retry-join-wan) - # join multiple parameters into json array over wan - retry_join_wan="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join-wan")" - # remove trailing , - printf ' ,"retry_join_wan": [%s]\n' "${retry_join_wan%*,}" - ;; - bootstrap-expect) - # integer key=value parameters - key="$(echo "$param" | tr '-' '_')" - printf ' ,"%s": %s\n' "$key" "$(cat "$__object/parameter/$param")" - ;; - *) - # string key=value parameters - key="$(echo "$param" | tr '-' '_')" - printf ' ,"%s": "%s"\n' "$key" "$(cat "$__object/parameter/$param")" - ;; - esac -done -if [ -f "$__object/parameter/json-config" ]; then - json_config="$(cat "$__object/parameter/json-config")" - if [ "$json_config" = "-" ]; then - json_config="$__object/stdin" - fi - # remove leading and trailing whitespace and commas from first and last line - # indent each line with 3 spaces for consistency - json=$(sed -e 's/^[ \t]*/ /' -e '1s/^[ \t,]*//' -e '$s/[ \t,]*$//' "$json_config") - printf ' ,%s\n' "$json" -fi -echo "}" -) | \ -require="__directory${conf_dir}" \ - __config_file "${conf_dir}/${conf_file}" \ - --owner root --group "$group" --mode 640 \ - --state "$state" \ - --onchange 'service consul status >/dev/null && service consul reload || true' \ - --source - +### +# LEGACY manual deployment, kept for compatibility reasons. init_sysvinit() { @@ -179,47 +111,184 @@ init_upstart() require="__file/etc/init/consul.conf" __start_on_boot consul } -# Install init script to start on boot -case "$os" in - devuan) - init_sysvinit debian - ;; - centos|redhat) - os_version="$(sed 's/[^0-9.]//g' "$__global/explorer/os_version")" - major_version="${os_version%%.*}" - case "$major_version" in - [456]) - init_sysvinit redhat - ;; - 7) - init_systemd - ;; - *) - echo "Unsupported CentOS/Redhat version: $os_version" >&2 - exit 1 - ;; - esac - ;; +manual_setup () { + case "$os" in + alpine|scientific|centos|debian|devuan|redhat|ubuntu) + # whitelist safeguard + : + ;; + *) + 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 + ;; + esac - debian) - os_version=$(cat "$__global/explorer/os_version") - major_version="${os_version%%.*}" + # FIXME: there has got to be a better way to handle the dependencies in this case + case "$state" in + present) + __group "$group" --system --state "$state" + require="__group/$group" __user "$user" \ + --system --gid "$group" --home "$data_dir" --state "$state" + ;; + *) + echo "The $state state is not (yet?) supported by this type." >&2 + exit 1 + ;; + esac - case "$major_version" in - [567]) - init_sysvinit debian - ;; - [89]|10) - init_systemd - ;; - *) - echo "Unsupported Debian version $os_version" >&2 - exit 1 - ;; - esac - ;; + # Create data directory. + require="__user/consul"__directory "$data_dir" \ + --owner "$user" --group "$group" --mode 770 --state "$state" - ubuntu) - init_upstart + # Create config directory. + require="__user/consul" __directory "$conf_dir" \ + --parents --owner root --group "$group" --mode 750 --state "$state" + + # Install init script to start on boot + case "$os" in + devuan) + init_sysvinit debian + ;; + centos|redhat) + os_version="$(sed 's/[^0-9.]//g' "$__global/explorer/os_version")" + major_version="${os_version%%.*}" + case "$major_version" in + [456]) + init_sysvinit redhat + ;; + 7) + init_systemd + ;; + *) + echo "Unsupported CentOS/Redhat version: $os_version" >&2 + exit 1 + ;; + esac + ;; + + debian) + os_version=$(cat "$__global/explorer/os_version") + major_version="${os_version%%.*}" + + case "$major_version" in + [567]) + init_sysvinit debian + ;; + [89]|10) + init_systemd + ;; + *) + echo "Unsupported Debian version $os_version" >&2 + exit 1 + ;; + esac + ;; + + ubuntu) + init_upstart + ;; + esac + + config_deployment_requires="__user/consul __directory/$conf_dir" +} + +### +# Trigger requested installation method. +if [ $use_distribution_package ]; then + distribution_setup +else + manual_setup +fi + +### +# Generate and deploy configuration. +json_configuration=$( + echo "{" + + # parameters we define ourself + printf ' "data_dir": "%s"\n' "$data_dir" + + cd "$__object/parameter/" + for param in *; do + case "$param" in + state|user|group|json-config|use-distribution-package) continue ;; + ca-file-source|cert-file-source|key-file-source) + source="$(cat "$__object/parameter/$param")" + destination="/etc/consul/ssl/${source##*/}" + require="__directory/etc/consul/ssl" \ + __file "$destination" \ + --owner root --group consul --mode 640 \ + --source "$source" \ + --state "$state" + key="$(echo "${param%-*}" | tr '-' '_')" + printf ' ,"%s": "%s"\n' "$key" "$destination" ;; -esac + disable-remote-exec|disable-update-check|leave-on-terminate\ + |rejoin-after-leave|server|enable-syslog|verify-incoming|verify-outgoing) + # handle boolean parameters + key="$(echo "$param" | tr '-' '_')" + printf ' ,"%s": true\n' "$key" + ;; + retry-join) + # join multiple parameters into json array + retry_join="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join")" + # remove trailing , + printf ' ,"retry_join": [%s]\n' "${retry_join%*,}" + ;; + retry-join-wan) + # join multiple parameters into json array over wan + retry_join_wan="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join-wan")" + # remove trailing , + printf ' ,"retry_join_wan": [%s]\n' "${retry_join_wan%*,}" + ;; + bootstrap-expect) + # integer key=value parameters + key="$(echo "$param" | tr '-' '_')" + printf ' ,"%s": %s\n' "$key" "$(cat "$__object/parameter/$param")" + ;; + *) + # string key=value parameters + key="$(echo "$param" | tr '-' '_')" + printf ' ,"%s": "%s"\n' "$key" "$(cat "$__object/parameter/$param")" + ;; + esac + done + if [ -f "$__object/parameter/json-config" ]; then + json_config="$(cat "$__object/parameter/json-config")" + if [ "$json_config" = "-" ]; then + json_config="$__object/stdin" + fi + # remove leading and trailing whitespace and commas from first and last line + # indent each line with 3 spaces for consistency + json=$(sed -e 's/^[ \t]*/ /' -e '1s/^[ \t,]*//' -e '$s/[ \t,]*$//' "$json_config") + printf ' ,%s\n' "$json" + fi + echo "}" +) +echo "$json_configuration" | require="$config_deployment_requires" \ + __file "$conf_dir/$conf_file" \ + --owner root --group "$group" --mode 640 \ + --state "$state" \ + --source - + +# Set configuration deployment as requirement for service restart. +restart_requires="__file/$conf_dir/$conf_file" + +### +# Install TLS certificates. +if [ -f "$__object/parameter/ca-file-source" ] || \ + [ -f "$__object/parameter/cert-file-source" ] || \ + [ -f "$__object/parameter/key-file-source" ]; then + + requires="__file/$conf_dir/$conf_file" __directory $conf_dir/tls \ + --owner root --group "$group" --mode 750 --state "$state" + + # Append to service restart requirements. + restart_requires="$restart_requires __directory/$conf_dir/tls" +fi + +### +# Restart consul agent after everything else. +require="$restart_requires" __service consul --action restart diff --git a/cdist/conf/type/__consul_agent/parameter/boolean b/cdist/conf/type/__consul_agent/parameter/boolean index 91f7f17e..c86853c3 100644 --- a/cdist/conf/type/__consul_agent/parameter/boolean +++ b/cdist/conf/type/__consul_agent/parameter/boolean @@ -6,3 +6,4 @@ server enable-syslog verify-incoming verify-outgoing +use-distribution-package From f595664924b3ae2ad190f9469fdf0be3b38d8a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Floure?= Date: Tue, 21 Jan 2020 10:07:21 +0100 Subject: [PATCH 36/64] Patch __consul_* to discover remote consul configuration dir --- cdist/conf/type/__consul_check/explorer/conf-dir | 1 + cdist/conf/type/__consul_check/manifest | 2 +- .../conf/type/__consul_service/explorer/conf-dir | 15 +++++++++++++++ cdist/conf/type/__consul_service/manifest | 5 ++--- .../type/__consul_watch_checks/explorer/conf-dir | 1 + cdist/conf/type/__consul_watch_checks/manifest | 2 +- .../type/__consul_watch_event/explorer/conf-dir | 1 + cdist/conf/type/__consul_watch_event/manifest | 2 +- .../type/__consul_watch_key/explorer/conf-dir | 1 + cdist/conf/type/__consul_watch_key/manifest | 2 +- .../__consul_watch_keyprefix/explorer/conf-dir | 1 + cdist/conf/type/__consul_watch_keyprefix/manifest | 2 +- .../type/__consul_watch_nodes/explorer/conf-dir | 1 + cdist/conf/type/__consul_watch_nodes/manifest | 2 +- .../type/__consul_watch_service/explorer/conf-dir | 1 + cdist/conf/type/__consul_watch_service/manifest | 2 +- .../__consul_watch_services/explorer/conf-dir | 1 + cdist/conf/type/__consul_watch_services/manifest | 2 +- 18 files changed, 33 insertions(+), 11 deletions(-) create mode 120000 cdist/conf/type/__consul_check/explorer/conf-dir create mode 100644 cdist/conf/type/__consul_service/explorer/conf-dir create mode 120000 cdist/conf/type/__consul_watch_checks/explorer/conf-dir create mode 120000 cdist/conf/type/__consul_watch_event/explorer/conf-dir create mode 120000 cdist/conf/type/__consul_watch_key/explorer/conf-dir create mode 120000 cdist/conf/type/__consul_watch_keyprefix/explorer/conf-dir create mode 120000 cdist/conf/type/__consul_watch_nodes/explorer/conf-dir create mode 120000 cdist/conf/type/__consul_watch_service/explorer/conf-dir create mode 120000 cdist/conf/type/__consul_watch_services/explorer/conf-dir diff --git a/cdist/conf/type/__consul_check/explorer/conf-dir b/cdist/conf/type/__consul_check/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_check/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_check/manifest b/cdist/conf/type/__consul_check/manifest index c9f7add9..522aa1a9 100755 --- a/cdist/conf/type/__consul_check/manifest +++ b/cdist/conf/type/__consul_check/manifest @@ -19,7 +19,7 @@ # name="$(cat "$__object/parameter/name" 2>/dev/null || echo "$__object_id")" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="check_${name}.json" state="$(cat "$__object/parameter/state")" diff --git a/cdist/conf/type/__consul_service/explorer/conf-dir b/cdist/conf/type/__consul_service/explorer/conf-dir new file mode 100644 index 00000000..6e94f781 --- /dev/null +++ b/cdist/conf/type/__consul_service/explorer/conf-dir @@ -0,0 +1,15 @@ +# Determine the configuration directory used by consul. + +check_dir () { + if [ -d "$1" ]; then + echo -n "$1" + exit + fi +} + +check_dir '/etc/consul/conf.d' +check_dir '/etc/consul.d' +check_dir '/etc/consul' + +echo 'Could not determine consul configuration dir. Exiting.' >&2 +exit 1 diff --git a/cdist/conf/type/__consul_service/manifest b/cdist/conf/type/__consul_service/manifest index 60397db7..d16f18e0 100755 --- a/cdist/conf/type/__consul_service/manifest +++ b/cdist/conf/type/__consul_service/manifest @@ -19,7 +19,7 @@ # name="$(cat "$__object/parameter/name" 2>/dev/null || echo "$__object_id")" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="service_${name}.json" state="$(cat "$__object/parameter/state")" @@ -45,7 +45,7 @@ printf ' "name": "%s"\n' "$name" cd "$__object/parameter/" for param in *; do case "$param" in - state|name|check-interval) continue ;; + state|name|check-interval|conf-dir) continue ;; check-script) printf ' ,"check": {\n' printf ' "script": "%s"\n' "$(cat "$__object/parameter/check-script")" @@ -86,7 +86,6 @@ echo " }" # end json file echo "}" ) | \ -require="__directory${conf_dir}" \ __config_file "${conf_dir}/${conf_file}" \ --owner root --group consul --mode 640 \ --state "$state" \ diff --git a/cdist/conf/type/__consul_watch_checks/explorer/conf-dir b/cdist/conf/type/__consul_watch_checks/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_watch_checks/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_watch_checks/manifest b/cdist/conf/type/__consul_watch_checks/manifest index 5fdd7a74..4976b25a 100755 --- a/cdist/conf/type/__consul_watch_checks/manifest +++ b/cdist/conf/type/__consul_watch_checks/manifest @@ -20,7 +20,7 @@ cdist_type="${__type##*/}" watch_type="${cdist_type##*_}" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="watch_${watch_type}_${__object_id}.json" state="$(cat "$__object/parameter/state")" diff --git a/cdist/conf/type/__consul_watch_event/explorer/conf-dir b/cdist/conf/type/__consul_watch_event/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_watch_event/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_watch_event/manifest b/cdist/conf/type/__consul_watch_event/manifest index 61934656..b17680c1 100755 --- a/cdist/conf/type/__consul_watch_event/manifest +++ b/cdist/conf/type/__consul_watch_event/manifest @@ -20,7 +20,7 @@ cdist_type="${__type##*/}" watch_type="${cdist_type##*_}" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="watch_${watch_type}_${__object_id}.json" state="$(cat "$__object/parameter/state")" diff --git a/cdist/conf/type/__consul_watch_key/explorer/conf-dir b/cdist/conf/type/__consul_watch_key/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_watch_key/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_watch_key/manifest b/cdist/conf/type/__consul_watch_key/manifest index 61934656..b17680c1 100755 --- a/cdist/conf/type/__consul_watch_key/manifest +++ b/cdist/conf/type/__consul_watch_key/manifest @@ -20,7 +20,7 @@ cdist_type="${__type##*/}" watch_type="${cdist_type##*_}" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="watch_${watch_type}_${__object_id}.json" state="$(cat "$__object/parameter/state")" diff --git a/cdist/conf/type/__consul_watch_keyprefix/explorer/conf-dir b/cdist/conf/type/__consul_watch_keyprefix/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_watch_keyprefix/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_watch_keyprefix/manifest b/cdist/conf/type/__consul_watch_keyprefix/manifest index 61934656..b17680c1 100755 --- a/cdist/conf/type/__consul_watch_keyprefix/manifest +++ b/cdist/conf/type/__consul_watch_keyprefix/manifest @@ -20,7 +20,7 @@ cdist_type="${__type##*/}" watch_type="${cdist_type##*_}" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="watch_${watch_type}_${__object_id}.json" state="$(cat "$__object/parameter/state")" diff --git a/cdist/conf/type/__consul_watch_nodes/explorer/conf-dir b/cdist/conf/type/__consul_watch_nodes/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_watch_nodes/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_watch_nodes/manifest b/cdist/conf/type/__consul_watch_nodes/manifest index 61934656..b17680c1 100755 --- a/cdist/conf/type/__consul_watch_nodes/manifest +++ b/cdist/conf/type/__consul_watch_nodes/manifest @@ -20,7 +20,7 @@ cdist_type="${__type##*/}" watch_type="${cdist_type##*_}" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="watch_${watch_type}_${__object_id}.json" state="$(cat "$__object/parameter/state")" diff --git a/cdist/conf/type/__consul_watch_service/explorer/conf-dir b/cdist/conf/type/__consul_watch_service/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_watch_service/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_watch_service/manifest b/cdist/conf/type/__consul_watch_service/manifest index db38eb18..e8d18328 100755 --- a/cdist/conf/type/__consul_watch_service/manifest +++ b/cdist/conf/type/__consul_watch_service/manifest @@ -20,7 +20,7 @@ cdist_type="${__type##*/}" watch_type="${cdist_type##*_}" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="watch_${watch_type}_${__object_id}.json" state="$(cat "$__object/parameter/state")" diff --git a/cdist/conf/type/__consul_watch_services/explorer/conf-dir b/cdist/conf/type/__consul_watch_services/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_watch_services/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_watch_services/manifest b/cdist/conf/type/__consul_watch_services/manifest index 61934656..b17680c1 100755 --- a/cdist/conf/type/__consul_watch_services/manifest +++ b/cdist/conf/type/__consul_watch_services/manifest @@ -20,7 +20,7 @@ cdist_type="${__type##*/}" watch_type="${cdist_type##*_}" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="watch_${watch_type}_${__object_id}.json" state="$(cat "$__object/parameter/state")" From 31ad1bdaad701720303054d668cf9635987edf1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Floure?= Date: Sun, 26 Jan 2020 15:13:12 +0100 Subject: [PATCH 37/64] Fix various typos and styling errors in __consul_agent, conf-dir explorer --- cdist/conf/type/__consul_agent/manifest | 40 ++++++++++--------- .../type/__consul_service/explorer/conf-dir | 2 +- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/cdist/conf/type/__consul_agent/manifest b/cdist/conf/type/__consul_agent/manifest index 599f15b4..40667002 100755 --- a/cdist/conf/type/__consul_agent/manifest +++ b/cdist/conf/type/__consul_agent/manifest @@ -49,7 +49,7 @@ distribution_setup () { debian) # consul is only available starting Debian 10 (buster). # See https://packages.debian.org/buster/consul - if [ $release -lt 10 ]; then + if [ "$release" -lt 10 ]; then echo "Consul is not available for your debian release." >&2 echo "Please use the 'manual' (i.e. non-package) installation or \ upgrade the target system." >&2 @@ -59,7 +59,7 @@ distribution_setup () { # Override previously defined environment to match debian packaging. conf_dir='/etc/consul.d' user='consul' - grou='consul' + group='consul' ;; *) echo "Your operating system ($os) is currently not supported with the \ @@ -71,7 +71,7 @@ distribution_setup () { esac # Install consul package. - __package consul --state $state + __package consul --state "$state" export config_deployment_requires="__package/consul" } @@ -139,7 +139,7 @@ manual_setup () { esac # Create data directory. - require="__user/consul"__directory "$data_dir" \ + require="__user/consul" __directory "$data_dir" \ --owner "$user" --group "$group" --mode 770 --state "$state" # Create config directory. @@ -202,8 +202,23 @@ else manual_setup fi +### +# Install TLS certificates. + +if [ -f "$__object/parameter/ca-file-source" ] || \ + [ -f "$__object/parameter/cert-file-source" ] || \ + [ -f "$__object/parameter/key-file-source" ]; then + + requires="$config_deployment_requires" __directory $tls_dir \ + --owner root --group "$group" --mode 750 --state "$state" + + # Append to service restart requirements. + restart_requires="$restart_requires __directory/$conf_dir/tls" +fi + ### # Generate and deploy configuration. + json_configuration=$( echo "{" @@ -216,8 +231,8 @@ json_configuration=$( state|user|group|json-config|use-distribution-package) continue ;; ca-file-source|cert-file-source|key-file-source) source="$(cat "$__object/parameter/$param")" - destination="/etc/consul/ssl/${source##*/}" - require="__directory/etc/consul/ssl" \ + destination="$tls_dir/${source##*/}" + require="__directory/$tls_dir" \ __file "$destination" \ --owner root --group consul --mode 640 \ --source "$source" \ @@ -276,19 +291,6 @@ echo "$json_configuration" | require="$config_deployment_requires" \ # Set configuration deployment as requirement for service restart. restart_requires="__file/$conf_dir/$conf_file" -### -# Install TLS certificates. -if [ -f "$__object/parameter/ca-file-source" ] || \ - [ -f "$__object/parameter/cert-file-source" ] || \ - [ -f "$__object/parameter/key-file-source" ]; then - - requires="__file/$conf_dir/$conf_file" __directory $conf_dir/tls \ - --owner root --group "$group" --mode 750 --state "$state" - - # Append to service restart requirements. - restart_requires="$restart_requires __directory/$conf_dir/tls" -fi - ### # Restart consul agent after everything else. require="$restart_requires" __service consul --action restart diff --git a/cdist/conf/type/__consul_service/explorer/conf-dir b/cdist/conf/type/__consul_service/explorer/conf-dir index 6e94f781..0fc9ef84 100644 --- a/cdist/conf/type/__consul_service/explorer/conf-dir +++ b/cdist/conf/type/__consul_service/explorer/conf-dir @@ -2,7 +2,7 @@ check_dir () { if [ -d "$1" ]; then - echo -n "$1" + printf '%s' "$1" exit fi } From 09540dc6bd63cb338ed8dc27bf69e2cc3547f02f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Floure?= Date: Mon, 17 Feb 2020 11:18:36 +0100 Subject: [PATCH 38/64] Add simple __service type --- .../type/__service/explorer/service-manager | 8 +++ cdist/conf/type/__service/gencode-remote | 9 ++++ cdist/conf/type/__service/man.rst | 51 +++++++++++++++++++ cdist/conf/type/__service/manifest | 15 ++++++ cdist/conf/type/__service/parameter/required | 1 + 5 files changed, 84 insertions(+) create mode 100755 cdist/conf/type/__service/explorer/service-manager create mode 100755 cdist/conf/type/__service/gencode-remote create mode 100644 cdist/conf/type/__service/man.rst create mode 100644 cdist/conf/type/__service/manifest create mode 100644 cdist/conf/type/__service/parameter/required diff --git a/cdist/conf/type/__service/explorer/service-manager b/cdist/conf/type/__service/explorer/service-manager new file mode 100755 index 00000000..55a873fa --- /dev/null +++ b/cdist/conf/type/__service/explorer/service-manager @@ -0,0 +1,8 @@ +#!/bin/sh + +# Assume systemd if systemctl is in PATH. +if [ "$(command -v systemctl)" ]; then + printf "systemd" +else + printf "unknown" +fi diff --git a/cdist/conf/type/__service/gencode-remote b/cdist/conf/type/__service/gencode-remote new file mode 100755 index 00000000..ac62e05f --- /dev/null +++ b/cdist/conf/type/__service/gencode-remote @@ -0,0 +1,9 @@ +#!/bin/sh + +manager="$(cat "$__object/explorer/service-manager")" +name=$__object_id +action="$(cat "$__object/parameter/action")" + +if [ "$manager" = "unknown" ]; then + echo "service '$name' '$action'" +fi diff --git a/cdist/conf/type/__service/man.rst b/cdist/conf/type/__service/man.rst new file mode 100644 index 00000000..f9b23d5b --- /dev/null +++ b/cdist/conf/type/__service/man.rst @@ -0,0 +1,51 @@ +cdist-type__service(7) +====================== + +NAME +---- +cdist-type__service - Run action on a system service + + +DESCRIPTION +----------- +This type allows you to run an action against a system service. + + +REQUIRED PARAMETERS +------------------- +action + Arbitrary parameter passed as action. Usually 'start', 'stop', 'reload' or 'restart'. + +OPTIONAL PARAMETERS +------------------- +None. + + +BOOLEAN PARAMETERS +------------------ +None. + + +EXAMPLES +-------- + +.. code-block:: sh + + # Restart nginx service. + __service nginx --action restart + + # Stop postfix service. + __service postfix --action stop + + +AUTHORS +------- +Timothée Floure + + +COPYING +------- +Copyright \(C) 2019 Timothée Floure. 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. diff --git a/cdist/conf/type/__service/manifest b/cdist/conf/type/__service/manifest new file mode 100644 index 00000000..cb5af234 --- /dev/null +++ b/cdist/conf/type/__service/manifest @@ -0,0 +1,15 @@ +#!/bin/sh + +manager="$(cat "$__object/explorer/service-manager")" + +name=$__object_id +action="$(cat "$__object/parameter/action")" + +case "$manager" in + systemd) + __systemd_service "$name" --action "$action" + ;; + *) + # Unknown: handled by `service $NAME $action` in gencode-remote. + ;; +esac diff --git a/cdist/conf/type/__service/parameter/required b/cdist/conf/type/__service/parameter/required new file mode 100644 index 00000000..a9f84d41 --- /dev/null +++ b/cdist/conf/type/__service/parameter/required @@ -0,0 +1 @@ +action From b891bb05d5751fe0f80829d7fe54cd56468d5e51 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Wed, 19 Feb 2020 12:58:22 +0200 Subject: [PATCH 39/64] __update_alternatives: add state explorer --- cdist/conf/type/__update_alternatives/explorer/state | 8 ++++++++ cdist/conf/type/__update_alternatives/gencode-remote | 4 ++++ 2 files changed, 12 insertions(+) create mode 100755 cdist/conf/type/__update_alternatives/explorer/state diff --git a/cdist/conf/type/__update_alternatives/explorer/state b/cdist/conf/type/__update_alternatives/explorer/state new file mode 100755 index 00000000..04a78aaa --- /dev/null +++ b/cdist/conf/type/__update_alternatives/explorer/state @@ -0,0 +1,8 @@ +#!/bin/sh -e +path="$(cat "$__object/parameter/path")" +name="$__object_id" +link="$(readlink "/etc/alternatives/$name")" +if [ "$path" = "$link" ] +then echo present +else echo absent +fi diff --git a/cdist/conf/type/__update_alternatives/gencode-remote b/cdist/conf/type/__update_alternatives/gencode-remote index 0e7b0d89..b632deb2 100755 --- a/cdist/conf/type/__update_alternatives/gencode-remote +++ b/cdist/conf/type/__update_alternatives/gencode-remote @@ -21,6 +21,10 @@ # Setup alternative - no standard way to create, always set # +if [ "$(cat "$__object/explorer/state")" = 'present' ] +then exit 0 +fi + path="$(cat "$__object/parameter/path")" name="$__object_id" echo "update-alternatives --quiet --set '$name' '$path'" From a3bc8f94075e23d8c0032fc8322aba5eebebd41e Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Wed, 19 Feb 2020 12:59:14 +0200 Subject: [PATCH 40/64] __update_alternatives: remove expired comment --- cdist/conf/type/__update_alternatives/gencode-remote | 3 --- 1 file changed, 3 deletions(-) diff --git a/cdist/conf/type/__update_alternatives/gencode-remote b/cdist/conf/type/__update_alternatives/gencode-remote index b632deb2..c0b49814 100755 --- a/cdist/conf/type/__update_alternatives/gencode-remote +++ b/cdist/conf/type/__update_alternatives/gencode-remote @@ -17,9 +17,6 @@ # You should have received a copy of the GNU General Public License # along with cdist. If not, see . # -# -# Setup alternative - no standard way to create, always set -# if [ "$(cat "$__object/explorer/state")" = 'present' ] then exit 0 From 1b0caeda13ddfc3d941332ea912983aba01b4819 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Wed, 19 Feb 2020 14:49:35 +0100 Subject: [PATCH 41/64] ++changelog --- docs/changelog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/changelog b/docs/changelog index bd767b9d..6410d36d 100644 --- a/docs/changelog +++ b/docs/changelog @@ -1,6 +1,9 @@ Changelog --------- +next: + * Type __update_alternatives: Add state explorer (Ander Punnar) + 6.5.1: 2020-02-15 * Type __consul_agent: Add Debian 10 support (Nico Schottelius) * Explorer os_release: Add fallbacks (Dennis Camera) From 28d3760e29aaf8cdb30390f7e78c2334d7af8bc4 Mon Sep 17 00:00:00 2001 From: Jin-Guk Kwon Date: Thu, 20 Feb 2020 09:40:55 +0100 Subject: [PATCH 42/64] [cdist]Update os_version for alpine --- cdist/conf/explorer/os_version | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cdist/conf/explorer/os_version b/cdist/conf/explorer/os_version index 4c41695b..1d54ea60 100755 --- a/cdist/conf/explorer/os_version +++ b/cdist/conf/explorer/os_version @@ -70,4 +70,7 @@ case "$("$__explorer/os")" in ubuntu) lsb_release -sr ;; -esac + alpine) + cat /etc/alpine-release + ;; +esac \ No newline at end of file From ceddbd15a04327489916b61e58fdf2d7a7728427 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Thu, 20 Feb 2020 10:15:34 +0100 Subject: [PATCH 43/64] ++changes --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index 6410d36d..b0ebf789 100644 --- a/docs/changelog +++ b/docs/changelog @@ -3,6 +3,7 @@ Changelog next: * Type __update_alternatives: Add state explorer (Ander Punnar) + * Explorer os_version: Add support for Alpine Linux (Jin-Guk Kwon) 6.5.1: 2020-02-15 * Type __consul_agent: Add Debian 10 support (Nico Schottelius) From 21c9e3db1852eebb88be5454137ceb23159f7dc0 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 3 Feb 2020 22:12:21 +0100 Subject: [PATCH 44/64] [explorer/init] Support more init systems --- cdist/conf/explorer/init | 225 ++++++++++++++++++++++++++++++--------- 1 file changed, 174 insertions(+), 51 deletions(-) diff --git a/cdist/conf/explorer/init b/cdist/conf/explorer/init index ceae2e9f..bf1736cd 100755 --- a/cdist/conf/explorer/init +++ b/cdist/conf/explorer/init @@ -1,7 +1,8 @@ -#!/bin/sh +#!/bin/sh -e # # 2016 Daniel Heule (hda at sfs.biz) # Copyright 2017, Philippe Gregoire +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -23,59 +24,181 @@ # for example at linux this value is "init" or "systemd" in most cases # +set -e + +# Expected values: +# Linux: +# Gentoo: +# sysvinit, openrc-init + +# GNU: +# Debian: +# hurd-init, sysvinit + +# [root@fedora-12 ~]# readlink /proc/1/exe +# /sbin/init (deleted) +# [root@fedora-12 ~]# ls -l /proc/1/exe +# lrwxrwxrwx. 1 root root 0 2020-01-30 23:00 /proc/1/exe -> /sbin/init (deleted) + +# inspired by https://stackoverflow.com/a/33266819 +shreadlink() ( + CDPATH= + target=$1 fname= targetDir= + + # Resolve potential symlinks until the ultimate target is found. + while : + do + if ! test -e "$target" + then + printf 'ERROR: %s does not exist.\n' "'$target'" >&2 + return 1 + fi + + # Change to target dir; necessary for correct resolution of target path. + cd "$(dirname -- "$target")" + + fname=$(basename -- "$target") # Extract filename. + [ "$fname" = '/' ] && fname='' # !! curiously, `basename /` returns '/' + + [ -L "$fname" ] || break + + # Extract [next] target path, which may be defined + # *relative* to the symlink's own directory. + # Note: We parse `ls -l` output to find the symlink target + # which is the only POSIX-compliant, albeit somewhat fragile, way. + # FIXME: Will break if one of the filenames contain ’ -> ’ + target=$(ls -l "$fname" | sed -e 's/^.* -> //') + done + + # Get canonical dir. path + targetDir=$(pwd -P) + + # Output the ultimate target's canonical path. + # Note that we manually resolve paths ending in /. and /.. to make sure we have a normalized path. + if test "$fname" = '.' + then + printf '%s\n' "${targetDir%/}" + elif test "$fname" = '..' + then + # Caveat: something like /var/.. will resolve to /private (assuming /var@ -> /private/var), i.e. the '..' is applied + # AFTER canonicalization. + printf '%s\n' "$(dirname -- "${targetDir}")" + else + printf '%s/%s\n' "${targetDir%/}" "$fname" + fi +) + + case $(uname -s) in - Linux) - if test -d /proc/1/ - then - comm_name=$(cat /proc/1/comm) - else - # BusyBox's versions of ps and pgrep do not support some options - # depending on which compile-time options have been used. - # Both pgrep and ps are tried to get the command name - comm_name=$( - pgrep -P0 -l 2>/dev/null | awk '/^1[ \t]/ { print $2 }' - || ps -o comm= -p 1 2>/dev/null) - fi + Linux|GNU) + # if test -f /proc/1/comm + # then + # comm_name=$(cat /proc/1/comm) + # else + # BusyBox's versions of ps and pgrep do not support some options + # depending on which compile-time options have been used. + # Both pgrep and ps are tried to get the command name + # comm_name=$( + # pgrep -P0 -l 2>/dev/null | awk '/^1[ \t]/ { print $2 }' + # || ps -o comm= -p 1 2>/dev/null) + # fi - case $comm_name - in - systemd) - echo systemd - ;; - init) - # It could be anything... + init_exe=$(shreadlink /proc/1/exe) - if test -h /proc/1/exe - then - init_exe=/proc/1/exe - else - init_exe=$(command -v "$comm_name") - fi + if ! test -x "$init_exe" + then + # On some rare occasions it can happen that the + # running init's binary has been replaced. In this + # case Linux adjusts the symlink to "X (deleted)" + case $init_exe + in + *' (deleted)') + init_exe=${init_exe% (deleted)} + test -x "$init_exe" || exit 1 + ;; + *) + exit 1 + ;; + esac + fi - test -x "$comm_exe" || exit 1 + if test "$init_exe" = '/hurd/init' + then + # XXX: Could maybe be removed + echo hurd-init + exit 0 + fi - case $("$comm_exe" --version | head -n 1) - in - *SysV*) - echo init - ;; - *upstart*) - echo upstart - ;; - *) - echo "" - ;; - esac - esac - ;; - FreeBSD|OpenBSD) - ps -o comm= -p 1 2>/dev/null || true - ;; - Darwin) - basename "$(ps -o comm= -p 1 2>/dev/null)" - ;; - *) - # return a empty string as unknown value - echo "" - ;; + comm_name=$(basename "$init_exe") + case $comm_name + in + init) + : # handled below + ;; + systemd) + # NOTE: sd_booted(3) + if test -d /run/systemd/system/ + then + echo systemd + exit 0 + fi + # otherwise: treat like "init" + ;; + *) + echo "$comm_name" + exit 0 + ;; + esac + + # init: it could be anything... + case $("$init_exe" --version 2>/dev/null | head -n 1) + in + SysV*) + # This is a little bit more specific than init + echo sysvinit + exit 0 + ;; + *'GNU Hurd'*) + echo hurd-init + ;; + *upstart*) + echo upstart + exit 0 + ;; + esac + case $("$init_exe" --help 2>/dev/null | head -n 1) + in + BusyBox*) + echo busybox + exit 0 + ;; + esac + + echo init + ;; + FreeBSD|OpenBSD) + ps -o comm= -p 1 2>/dev/null || true + ;; + Darwin) + basename "$(ps -o comm= -p 1 2>/dev/null)" + ;; + SunOS) + comm_name=$(ps -o comm= -p 1 2>/dev/null) + if test "$(basename "$comm_name")" != 'init' + then + echo "${comm_name}" + exit 0 + fi + + # XXX: Is this the correct way?? + if test -f /etc/svc/volatile/svc_nonpersist.db + then + echo smf + exit 0 + fi + ;; + *) + # return a empty string as unknown value + echo "" + ;; esac From d895bb0e87f524e8a64a802e6ff1922e52860ffa Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Tue, 18 Feb 2020 01:24:41 +0100 Subject: [PATCH 45/64] [explorer/init] Clean up --- cdist/conf/explorer/init | 399 ++++++++++++++++++++++++--------------- 1 file changed, 246 insertions(+), 153 deletions(-) diff --git a/cdist/conf/explorer/init b/cdist/conf/explorer/init index bf1736cd..2d4f07c1 100755 --- a/cdist/conf/explorer/init +++ b/cdist/conf/explorer/init @@ -20,185 +20,278 @@ # along with cdist. If not, see . # # -# Returns the process name of pid 1 ( normaly the init system ) -# for example at linux this value is "init" or "systemd" in most cases +# Returns the name of the init system (PID 1) # - -set -e - # Expected values: # Linux: +# Adélie Linux: +# sysvinit+openrc +# Alpine Linux: +# busybox-init+openrc +# ArchLinux: +# systemd, sysvinit +# CRUX: +# sysvinit +# Debian: +# systemd, upstart, sysvinit, openrc, ??? +# Devuan: +# sysvinit, ??? # Gentoo: -# sysvinit, openrc-init - +# sysvinit+openrc, openrc-init, systemd +# OpenBMC: +# systemd +# OpenWrt: +# procd, init?? +# RedHat (RHEL, CentOS, Fedora, RedHat Linux, ...): +# systemd, upstart, sysvinit +# Slackware: +# sysvinit +# SuSE: +# systemd, sysvinit +# Ubuntu: +# systemd, upstart, sysvinit +# # GNU: -# Debian: -# hurd-init, sysvinit +# Debian: +# hurd-init, sysvinit +# +# BSD: +# {Free,Open,Net}BSD: +# init +# +# Mac OS X: +# launchd, init +# +# Solaris/Illumos: +# smf, init + # [root@fedora-12 ~]# readlink /proc/1/exe # /sbin/init (deleted) # [root@fedora-12 ~]# ls -l /proc/1/exe # lrwxrwxrwx. 1 root root 0 2020-01-30 23:00 /proc/1/exe -> /sbin/init (deleted) -# inspired by https://stackoverflow.com/a/33266819 -shreadlink() ( - CDPATH= - target=$1 fname= targetDir= +set -e +#set -x # DEBUG - # Resolve potential symlinks until the ultimate target is found. - while : - do - if ! test -e "$target" - then - printf 'ERROR: %s does not exist.\n' "'$target'" >&2 - return 1 - fi - - # Change to target dir; necessary for correct resolution of target path. - cd "$(dirname -- "$target")" - - fname=$(basename -- "$target") # Extract filename. - [ "$fname" = '/' ] && fname='' # !! curiously, `basename /` returns '/' - - [ -L "$fname" ] || break - - # Extract [next] target path, which may be defined - # *relative* to the symlink's own directory. - # Note: We parse `ls -l` output to find the symlink target - # which is the only POSIX-compliant, albeit somewhat fragile, way. - # FIXME: Will break if one of the filenames contain ’ -> ’ - target=$(ls -l "$fname" | sed -e 's/^.* -> //') - done - - # Get canonical dir. path - targetDir=$(pwd -P) - - # Output the ultimate target's canonical path. - # Note that we manually resolve paths ending in /. and /.. to make sure we have a normalized path. - if test "$fname" = '.' +validate_busybox_init() { + # It is quite common to use SysVinit to stack other init systemd + # (like OpenRC) on top of it. So we check for that, too. + if stacked=$(validate_openrc) then - printf '%s\n' "${targetDir%/}" - elif test "$fname" = '..' - then - # Caveat: something like /var/.. will resolve to /private (assuming /var@ -> /private/var), i.e. the '..' is applied - # AFTER canonicalization. - printf '%s\n' "$(dirname -- "${targetDir}")" + echo "busybox-init+${stacked}" else - printf '%s/%s\n' "${targetDir%/}" "$fname" + echo busybox-init fi -) +} +validate_hurd_init() { + # FIXME: Test me! + test -x /hurd/init || return 1 + grep -q 'GNU Hurd' /hurd/init || return 1 + echo hurd-init +} -case $(uname -s) in - Linux|GNU) - # if test -f /proc/1/comm - # then - # comm_name=$(cat /proc/1/comm) - # else - # BusyBox's versions of ps and pgrep do not support some options - # depending on which compile-time options have been used. - # Both pgrep and ps are tried to get the command name - # comm_name=$( - # pgrep -P0 -l 2>/dev/null | awk '/^1[ \t]/ { print $2 }' - # || ps -o comm= -p 1 2>/dev/null) - # fi +validate_openrc() { + test -f /run/openrc/softlevel || return 1 + echo openrc +} - init_exe=$(shreadlink /proc/1/exe) +validate_procd() { + grep -q 'procd' /sbin/procd || return 1 + echo procd +} - if ! test -x "$init_exe" - then - # On some rare occasions it can happen that the - # running init's binary has been replaced. In this - # case Linux adjusts the symlink to "X (deleted)" - case $init_exe - in - *' (deleted)') - init_exe=${init_exe% (deleted)} - test -x "$init_exe" || exit 1 - ;; - *) - exit 1 - ;; - esac - fi +validate_runit() { + test -d /run/runit || return 1 + echo runit +} - if test "$init_exe" = '/hurd/init' - then - # XXX: Could maybe be removed - echo hurd-init - exit 0 - fi +validate_smf() { + # XXX: Is this the correct way?? + test -f /etc/svc/volatile/svc_nonpersist.db || return 1 + echo smf +} - comm_name=$(basename "$init_exe") - case $comm_name +validate_systemd() { + # NOTE: sd_booted(3) + test -d /run/systemd/system/ || return 1 + # systemctl --version | sed -e '/^systemd/!d;s/^systemd //' + echo systemd +} + +validate_sysvinit() { + test -x /sbin/init \ + && grep -q 'INIT_VERSION=sysvinit-[0-9.]*' /sbin/init \ + || return 1 + + # It is quite common to use SysVinit to stack other init systemd + # (like OpenRC) on top of it. So we check for that, too. + if stacked=$(validate_openrc) + then + echo "sysvinit+${stacked}" + else + echo sysvinit + fi + unset stacked +} + +validate_upstart() { + test -x "$(command -v initctl)" || return 1 + case $(initctl version) + in + *'(upstart '*')') + # if type -d /etc/init + # then + # # modern (DBus-based?) upstart >= 0.5 + # : + # elif type -d /etc/events.d + # then + # # ancient upstart + # : + # fi + echo upstart + ;; + *) + return 1 + ;; + esac +} + +find_init_procfs() ( + # First, check if the required file in procfs exists... + test -h /proc/1/exe || return 1 + + # Find init executable + init_exe=$(ls -l /proc/1/exe 2>/dev/null) + init_exe=${init_exe#* -> } + + if ! test -x "$init_exe" + then + # On some rare occasions it can happen that the + # running init's binary has been replaced. In this + # case Linux adjusts the symlink to "X (deleted)" + case $init_exe in - init) - : # handled below - ;; - systemd) - # NOTE: sd_booted(3) - if test -d /run/systemd/system/ - then - echo systemd - exit 0 - fi - # otherwise: treat like "init" + *' (deleted)') + init_exe=${init_exe% (deleted)} + test -x "$init_exe" || exit 1 ;; *) - echo "$comm_name" - exit 0 + exit 1 ;; esac + fi - # init: it could be anything... - case $("$init_exe" --version 2>/dev/null | head -n 1) - in - SysV*) - # This is a little bit more specific than init - echo sysvinit - exit 0 - ;; - *'GNU Hurd'*) - echo hurd-init - ;; - *upstart*) - echo upstart - exit 0 - ;; - esac - case $("$init_exe" --help 2>/dev/null | head -n 1) - in - BusyBox*) - echo busybox - exit 0 - ;; - esac + echo "${init_exe}" +) - echo init - ;; - FreeBSD|OpenBSD) - ps -o comm= -p 1 2>/dev/null || true - ;; - Darwin) - basename "$(ps -o comm= -p 1 2>/dev/null)" - ;; - SunOS) - comm_name=$(ps -o comm= -p 1 2>/dev/null) - if test "$(basename "$comm_name")" != 'init' - then - echo "${comm_name}" - exit 0 - fi +# BusyBox's versions of ps and pgrep do not support some options +# depending on which compile-time options have been used. - # XXX: Is this the correct way?? - if test -f /etc/svc/volatile/svc_nonpersist.db - then - echo smf - exit 0 - fi - ;; - *) - # return a empty string as unknown value - echo "" - ;; -esac +find_init_pgrep() { + pgrep -P0 -fl 2>/dev/null | awk -F '[[:blank:]]' '$1 == 1 { print $2 }' +} + +find_init_ps() { + case $(uname -s) + in + Darwin|NetBSD) + ps -o ucomm= -p 1 2>/dev/null + ;; + FreeBSD) + ps -o command= -p 1 2>/dev/null | cut -d ' ' -f 1 + ;; + OpenBSD) + ps -o command -p 1 2>/dev/null | tail -n +2 | cut -d ' ' -f 1 + ;; + *) + ps -o comm= -p 1 2>/dev/null + ;; + esac +} + +find_init() { + case $(uname -s) + in + Linux|GNU|NetBSD) + find_init_procfs || find_init_pgrep || find_init_ps + ;; + FreeBSD) + find_init_procfs || find_init_ps + ;; + OpenBSD) + find_init_pgrep || find_init_ps + ;; + Darwin|FreeBSD|SunOS) + find_init_ps + ;; + *) + echo "Don't know how to determine init." >&2 + echo 'Please send a patch.' >&2 + exit 1 + esac +} + +validate_by_comm_name() { + case $1 + in + busybox) + validate_busybox_init + ;; + init) + # FIXME: Do some more magic here! + echo init + ;; + openrc-init) + validate_openrc >/dev/null && echo openrc-init + ;; + runit) + validate_runit + ;; + systemd) + validate_systemd + ;; + *) + # Run validate function by comm name if available. + # Fall back to comm name if either it does not exist or + # returns non-zero. + type "validate_$1" >/dev/null && "validate_$1" || echo $1 + esac +} + +try_all() { + # init: it could be anything... + # We try some approaches to gather more information about init without + # calling it! On some init systemd this triggers a reinitialisation of + # the system which we don't want (e.g. embedded systems). + + validate_sysvinit || \ + validate_openrc || \ + validate_runit || \ + validate_smf || \ + validate_upstart || \ + validate_hurd_init || \ + echo init # fallback +} + +init=$(find_init) + +if test -x "${init}" +then + case $init + in + /hurd/init) + # FIXME: Create validate function + echo hurd-init + ;; + */init) + try_all + ;; + *) + validate_by_comm_name "$(basename "${init}")" + ;; + esac +else + validate_by_comm_name "${init}" +fi From 364340c8d5a1bcb6492d6c8cdfbbd808b13b5024 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Thu, 20 Feb 2020 21:34:21 +0100 Subject: [PATCH 46/64] [explorer/init] Refactor and testing --- cdist/conf/explorer/init | 392 ++++++++++++++++++++++++++------------- 1 file changed, 267 insertions(+), 125 deletions(-) diff --git a/cdist/conf/explorer/init b/cdist/conf/explorer/init index 2d4f07c1..db417a14 100755 --- a/cdist/conf/explorer/init +++ b/cdist/conf/explorer/init @@ -21,7 +21,7 @@ # # # Returns the name of the init system (PID 1) -# + # Expected values: # Linux: # Adélie Linux: @@ -35,122 +35,221 @@ # Debian: # systemd, upstart, sysvinit, openrc, ??? # Devuan: -# sysvinit, ??? +# sysvinit, sysvinit+openrc # Gentoo: # sysvinit+openrc, openrc-init, systemd # OpenBMC: # systemd # OpenWrt: -# procd, init?? +# procd, init??? # RedHat (RHEL, CentOS, Fedora, RedHat Linux, ...): -# systemd, upstart, sysvinit +# systemd, upstart, upstart-legacy, sysvinit # Slackware: # sysvinit # SuSE: # systemd, sysvinit # Ubuntu: -# systemd, upstart, sysvinit +# systemd, upstart, upstart-legacy, sysvinit +# VoidLinux: +# runit # # GNU: # Debian: -# hurd-init, sysvinit +# sysvinit, hurd-init # # BSD: # {Free,Open,Net}BSD: # init # # Mac OS X: -# launchd, init +# launchd, init+SystemStarter # # Solaris/Illumos: -# smf, init +# smf, init??? +# NOTE: init systems can be stacked. This is popular to run OpenRC on top of +# sysvinit (Gentoo) or busybox-init (Alpine), but can also be used to run runit +# as a systemd service. This makes init system detection very complicated +# (which result is expected?) This script tries to untangle some combinations, +# OpenRC on top of sysv or busybox (X+openrc), but will ignore others (runit as +# a systemd service) + +# NOTE: When we have no idea, nothing will be printed! + +# NOTE: +# When trying to gather information about the init system make sure to do so +# without calling the binary! On some systems this triggers a reinitialisation +# of the system which we don't want (e.g. embedded systems). -# [root@fedora-12 ~]# readlink /proc/1/exe -# /sbin/init (deleted) -# [root@fedora-12 ~]# ls -l /proc/1/exe -# lrwxrwxrwx. 1 root root 0 2020-01-30 23:00 /proc/1/exe -> /sbin/init (deleted) set -e -#set -x # DEBUG -validate_busybox_init() { - # It is quite common to use SysVinit to stack other init systemd +KERNEL_NAME=$(uname -s) + +KNOWN_INIT_SYSTEMS=$(cat </dev/null 2>&1 || return 1 + launchctl getenv PATH >/dev/null || return 1 + echo launchd +} + +check_openrc() { test -f /run/openrc/softlevel || return 1 echo openrc } -validate_procd() { - grep -q 'procd' /sbin/procd || return 1 +check_procd() ( + procd_path=${1:-/sbin/procd} + test -x "${procd_path}" || return 1 + grep -q 'procd' "${procd_path}" || return 1 echo procd -} +) -validate_runit() { +check_runit() { test -d /run/runit || return 1 echo runit } -validate_smf() { +check_smf() { # XXX: Is this the correct way?? test -f /etc/svc/volatile/svc_nonpersist.db || return 1 echo smf } -validate_systemd() { +check_systemd() { # NOTE: sd_booted(3) test -d /run/systemd/system/ || return 1 # systemctl --version | sed -e '/^systemd/!d;s/^systemd //' echo systemd } -validate_sysvinit() { - test -x /sbin/init \ - && grep -q 'INIT_VERSION=sysvinit-[0-9.]*' /sbin/init \ - || return 1 +check_systemstarter() { + test -d /System/Library/StartupItems/ || return 1 + test -f /System/Library/StartupItems/LoginWindow/StartupParameters.plist || return 1 + echo init+SystemStarter +} + +check_sysvinit() ( + init_path=${1:-/sbin/init} + grep -q 'INIT_VERSION=sysvinit-[0-9.]*' "${init_path}" || return 1 # It is quite common to use SysVinit to stack other init systemd # (like OpenRC) on top of it. So we check for that, too. - if stacked=$(validate_openrc) + if stacked=$(check_openrc) then echo "sysvinit+${stacked}" else echo sysvinit fi unset stacked -} +) -validate_upstart() { +check_upstart() { test -x "$(command -v initctl)" || return 1 case $(initctl version) in *'(upstart '*')') - # if type -d /etc/init - # then - # # modern (DBus-based?) upstart >= 0.5 - # : - # elif type -d /etc/events.d - # then - # # ancient upstart - # : - # fi - echo upstart + if test -d /etc/init + then + # modern (DBus-based?) upstart >= 0.5 + echo upstart + elif test -d /etc/event.d + then + # ancient upstart + echo upstart-legacy + else + # whatever... + echo upstart + fi ;; *) return 1 @@ -163,7 +262,7 @@ find_init_procfs() ( test -h /proc/1/exe || return 1 # Find init executable - init_exe=$(ls -l /proc/1/exe 2>/dev/null) + init_exe=$(ls -l /proc/1/exe 2>/dev/null) || return 1 init_exe=${init_exe#* -> } if ! test -x "$init_exe" @@ -171,21 +270,100 @@ find_init_procfs() ( # On some rare occasions it can happen that the # running init's binary has been replaced. In this # case Linux adjusts the symlink to "X (deleted)" - case $init_exe - in - *' (deleted)') - init_exe=${init_exe% (deleted)} - test -x "$init_exe" || exit 1 - ;; - *) - exit 1 - ;; - esac + + # [root@fedora-12 ~]# readlink /proc/1/exe + # /sbin/init (deleted) + # [root@fedora-12 ~]# ls -l /proc/1/exe + # lrwxrwxrwx. 1 root root 0 2020-01-30 23:00 /proc/1/exe -> /sbin/init (deleted) + + init_exe=${init_exe% (deleted)} + test -x "$init_exe" || return 1 fi echo "${init_exe}" ) +guess_by_path() { + case $1 + in + /bin/busybox) + check_busybox_init "$1" && return + ;; + /lib/systemd/systemd) + check_systemd "$1" && return + ;; + /hurd/init) + check_hurd_init "$1" && return + ;; + /sbin/launchd) + check_launchd "$1" && return + ;; + /usr/bin/runit|/sbin/runit) + check_runit "$1" && return + ;; + /sbin/openrc-init) + if check_openrc "$1" >/dev/null + then + echo openrc-init + return + fi + ;; + /sbin/procd) + check_procd && return + ;; + /sbin/init|*/init) + # init: it could be anything -> (explicit) no match + return 1 + ;; + esac + + # No match + return 1 +} + +guess_by_comm_name() { + case $1 + in + busybox) + check_busybox_init && return + ;; + openrc-init) + if check_openrc >/dev/null + then + echo openrc-init + return 0 + fi + ;; + init) + # init could be anything -> no match + return 1 + ;; + *) + # Run check function by comm name if available. + # Fall back to comm name if either it does not exist or + # returns non-zero. + if type "check_$1" >/dev/null + then + "check_$1" && return + else + echo "$1" ; return 0 + fi + esac + + return 1 +} + +check_list() ( + # List must be a multi-line input on stdin (one name per line) + while read init + do + "check_${init}" || continue + return 0 + done + return 1 +) + + # BusyBox's versions of ps and pgrep do not support some options # depending on which compile-time options have been used. @@ -194,25 +372,31 @@ find_init_pgrep() { } find_init_ps() { - case $(uname -s) + case $KERNEL_NAME in - Darwin|NetBSD) - ps -o ucomm= -p 1 2>/dev/null + Darwin) + ps -o command -p 1 2>/dev/null | tail -n +2 ;; FreeBSD) - ps -o command= -p 1 2>/dev/null | cut -d ' ' -f 1 + ps -o args= -p 1 2>/dev/null | cut -d ' ' -f 1 ;; - OpenBSD) - ps -o command -p 1 2>/dev/null | tail -n +2 | cut -d ' ' -f 1 - ;; - *) + Linux) ps -o comm= -p 1 2>/dev/null ;; - esac + NetBSD) + ps -o comm= -p 1 2>/dev/null + ;; + OpenBSD) + ps -o args -p 1 2>/dev/null | tail -n +2 | cut -d ' ' -f 1 + ;; + *) + ps -o args= -p 1 2>/dev/null + ;; + esac | trim # trim trailing whitespace (some ps like Darwin add it) } find_init() { - case $(uname -s) + case $KERNEL_NAME in Linux|GNU|NetBSD) find_init_procfs || find_init_pgrep || find_init_ps @@ -233,65 +417,23 @@ find_init() { esac } -validate_by_comm_name() { - case $1 - in - busybox) - validate_busybox_init - ;; - init) - # FIXME: Do some more magic here! - echo init - ;; - openrc-init) - validate_openrc >/dev/null && echo openrc-init - ;; - runit) - validate_runit - ;; - systemd) - validate_systemd - ;; - *) - # Run validate function by comm name if available. - # Fall back to comm name if either it does not exist or - # returns non-zero. - type "validate_$1" >/dev/null && "validate_$1" || echo $1 - esac -} - -try_all() { - # init: it could be anything... - # We try some approaches to gather more information about init without - # calling it! On some init systemd this triggers a reinitialisation of - # the system which we don't want (e.g. embedded systems). - - validate_sysvinit || \ - validate_openrc || \ - validate_runit || \ - validate_smf || \ - validate_upstart || \ - validate_hurd_init || \ - echo init # fallback -} +# ----- init=$(find_init) -if test -x "${init}" -then - case $init - in - /hurd/init) - # FIXME: Create validate function - echo hurd-init - ;; - */init) - try_all - ;; - *) - validate_by_comm_name "$(basename "${init}")" - ;; - esac -else - validate_by_comm_name "${init}" -fi +# If we got a path, guess by the path first (fall back to file name if no match) +# else guess by file name directly. +{ + test -x "${init}" \ + && guess_by_path "${init}" \ + || guess_by_comm_name "$(basename "${init}")" +} && exit 0 || true + + +# Guessing based on the file path and name didn’t lead to a definitive result. +# +# We go through all of the checks until we find a match. To speed up the +# process, common cases will be checked first based on the underlying kernel. + +{ common_candidates_by_kernel; echo "${KNOWN_INIT_SYSTEMS}"; } \ + | unique | check_list From 0d84c91b4047d3da0571d0262b4b5d9a8f9796b9 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Thu, 20 Feb 2020 22:55:46 +0100 Subject: [PATCH 47/64] [explorer/init] Fix unique() for Solaris --- cdist/conf/explorer/init | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cdist/conf/explorer/init b/cdist/conf/explorer/init index db417a14..0f04a0ee 100755 --- a/cdist/conf/explorer/init +++ b/cdist/conf/explorer/init @@ -135,7 +135,8 @@ trim() { unique() { # Delete duplicate lines (keeping input order) - awk '!x[$0]++' + # NOTE: Solaris AWK breaks without if/print construct. + awk '{ if (!x[$0]++) print }' } From 0d6bc8e8f8166a3f61dd4da4a0e499499d3702c4 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Thu, 20 Feb 2020 23:29:21 +0100 Subject: [PATCH 48/64] [explorer/init] Make shellcheck happy --- cdist/conf/explorer/init | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cdist/conf/explorer/init b/cdist/conf/explorer/init index 0f04a0ee..1b921c68 100755 --- a/cdist/conf/explorer/init +++ b/cdist/conf/explorer/init @@ -310,7 +310,7 @@ guess_by_path() { fi ;; /sbin/procd) - check_procd && return + check_procd "$1" && return ;; /sbin/init|*/init) # init: it could be anything -> (explicit) no match @@ -356,7 +356,7 @@ guess_by_comm_name() { check_list() ( # List must be a multi-line input on stdin (one name per line) - while read init + while read -r init do "check_${init}" || continue return 0 @@ -408,7 +408,7 @@ find_init() { OpenBSD) find_init_pgrep || find_init_ps ;; - Darwin|FreeBSD|SunOS) + Darwin|SunOS) find_init_ps ;; *) @@ -424,6 +424,7 @@ init=$(find_init) # If we got a path, guess by the path first (fall back to file name if no match) # else guess by file name directly. +# shellcheck disable=SC2015 { test -x "${init}" \ && guess_by_path "${init}" \ From 49fc21ec47d665155edac73bdbae4fed9258f382 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sun, 23 Feb 2020 09:32:03 +0100 Subject: [PATCH 49/64] ++changelog --- docs/changelog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/changelog b/docs/changelog index b0ebf789..8463bb89 100644 --- a/docs/changelog +++ b/docs/changelog @@ -4,6 +4,9 @@ Changelog next: * Type __update_alternatives: Add state explorer (Ander Punnar) * Explorer os_version: Add support for Alpine Linux (Jin-Guk Kwon) + * Explorer init: Rewrite and support more init systems (Dennis Camera) + * New type: __service (Timothée Floure) + * Types __consul_*: Add optional parameter for using distribution packages (Timothée Floure) 6.5.1: 2020-02-15 * Type __consul_agent: Add Debian 10 support (Nico Schottelius) From c6aba8d189c2efc7c88f9c595acba7ceae5a4e00 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 23 Feb 2020 22:59:41 +0100 Subject: [PATCH 50/64] [explorer/disks] Fix for NetBSD When connecting over SSH and running /bin/sh, the PATH is missing sbin locations. sysctl is located at /sbin/sysctl on NetBSD. --- cdist/conf/explorer/disks | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/cdist/conf/explorer/disks b/cdist/conf/explorer/disks index 87a6b5c6..08290bc7 100755 --- a/cdist/conf/explorer/disks +++ b/cdist/conf/explorer/disks @@ -1,14 +1,20 @@ -#!/bin/sh +#!/bin/sh -e uname_s="$(uname -s)" -case "${uname_s}" in +case $uname_s in FreeBSD) sysctl -n kern.disks ;; - OpenBSD|NetBSD) + OpenBSD) sysctl -n hw.disknames | grep -Eo '[lsw]d[0-9]+' | xargs ;; + NetBSD) + PATH="${PATH}:/usr/local/sbin:/usr/sbin:/sbin" + sysctl -n hw.disknames \ + | awk 'BEGIN { RS = " " } /^[lsw]d[0-9]+/' \ + | xargs + ;; Linux) if command -v lsblk > /dev/null then @@ -23,5 +29,3 @@ case "${uname_s}" in printf "Don't know how to list disks for %s operating system, if you can please submit a patch\n" "${uname_s}" >&2 ;; esac - -exit 0 From e6f683b88633fa0722b3787e3daa39db640ce0f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Floure?= Date: Mon, 24 Feb 2020 09:20:49 +0100 Subject: [PATCH 51/64] Add support for alpine (edge) package to __consul_agent --- cdist/conf/type/__consul_agent/manifest | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cdist/conf/type/__consul_agent/manifest b/cdist/conf/type/__consul_agent/manifest index 40667002..0d819d45 100755 --- a/cdist/conf/type/__consul_agent/manifest +++ b/cdist/conf/type/__consul_agent/manifest @@ -61,6 +61,17 @@ distribution_setup () { user='consul' group='consul' ;; + alpine) + # consul is only available starting Alpine 3.12 (= edge during the 3.11 cycle). + # See https://pkgs.alpinelinux.org/packages?name=consul&branch=edge + + # Override previously defined environment to match alpine packaging. + conf_dir='/etc/consul' + conf_file='server.json' + data_dir='/var/consul' + user='consul' + group='consul' + ;; *) echo "Your operating system ($os) is currently not supported with the \ --use-distribution-package flag (${__type##*/})." >&2 From d3bd2669ec49fb861016e614893dac280ed5fd35 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 23 Feb 2020 23:07:40 +0100 Subject: [PATCH 52/64] [explorer/disks] Support Linux without lsblk (fallback to sysfs) --- cdist/conf/explorer/disks | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/cdist/conf/explorer/disks b/cdist/conf/explorer/disks index 08290bc7..0fabc95f 100755 --- a/cdist/conf/explorer/disks +++ b/cdist/conf/explorer/disks @@ -16,16 +16,33 @@ case $uname_s in | xargs ;; Linux) - if command -v lsblk > /dev/null + # list of major device numbers toexclude: + # ram disks, floppies, cdroms + # https://www.kernel.org/doc/Documentation/admin-guide/devices.txt + ign_majors='1 2 11' + + if command -v lsblk >/dev/null 2>&1 then - # exclude ram disks, floppies and cdroms - # https://www.kernel.org/doc/Documentation/admin-guide/devices.txt - lsblk -e 1,2,11 -dno name | xargs + lsblk -e "$(echo "$ign_majors" | tr ' ' ',')" -dno name | xargs + elif test -d /sys/block/ + then + # shellcheck disable=SC2012 + ls -1 /sys/block/ \ + | awk -v ign_majors="$(echo "$ign_majors" | tr ' ' '|')" ' + { + devfile = "/sys/block/" $0 "/dev" + getline devno < devfile + close(devfile) + if (devno !~ "^(" ign_majors "):") print + }' \ + | xargs else - printf "Don't know how to list disks for %s operating system without lsblk, if you can please submit a patch\n" "${uname_s}" >&2 + echo "Don't know how to list disks on Linux without lsblk and sysfs." >&2 + echo 'If you can, please submit a patch.'>&2 fi ;; *) - printf "Don't know how to list disks for %s operating system, if you can please submit a patch\n" "${uname_s}" >&2 + printf "Don't know how to list disks for %s operating system.\n" "${uname_s}" >&2 + printf 'If you can please submit a patch\n' >&2 ;; esac From 1ef126e16f95e822562978abd895a3c036f7d5c4 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 23 Feb 2020 23:08:40 +0100 Subject: [PATCH 53/64] [explorer/disks] Move xargs call to the bottom --- cdist/conf/explorer/disks | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/cdist/conf/explorer/disks b/cdist/conf/explorer/disks index 0fabc95f..ed1afce4 100755 --- a/cdist/conf/explorer/disks +++ b/cdist/conf/explorer/disks @@ -7,13 +7,12 @@ case $uname_s in sysctl -n kern.disks ;; OpenBSD) - sysctl -n hw.disknames | grep -Eo '[lsw]d[0-9]+' | xargs + sysctl -n hw.disknames | grep -Eo '[lsw]d[0-9]+' ;; NetBSD) PATH="${PATH}:/usr/local/sbin:/usr/sbin:/sbin" sysctl -n hw.disknames \ - | awk 'BEGIN { RS = " " } /^[lsw]d[0-9]+/' \ - | xargs + | awk 'BEGIN { RS = " " } /^[lsw]d[0-9]+/' ;; Linux) # list of major device numbers toexclude: @@ -23,7 +22,7 @@ case $uname_s in if command -v lsblk >/dev/null 2>&1 then - lsblk -e "$(echo "$ign_majors" | tr ' ' ',')" -dno name | xargs + lsblk -e "$(echo "$ign_majors" | tr ' ' ',')" -dno name elif test -d /sys/block/ then # shellcheck disable=SC2012 @@ -34,8 +33,7 @@ case $uname_s in getline devno < devfile close(devfile) if (devno !~ "^(" ign_majors "):") print - }' \ - | xargs + }' else echo "Don't know how to list disks on Linux without lsblk and sysfs." >&2 echo 'If you can, please submit a patch.'>&2 @@ -45,4 +43,5 @@ case $uname_s in printf "Don't know how to list disks for %s operating system.\n" "${uname_s}" >&2 printf 'If you can please submit a patch\n' >&2 ;; -esac +esac \ +| xargs From 6db6dc4ac0950579ce13252dcca6d0f61f5533c6 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 23 Feb 2020 23:14:14 +0100 Subject: [PATCH 54/64] [explorer/disks] Add license header --- cdist/conf/explorer/disks | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/cdist/conf/explorer/disks b/cdist/conf/explorer/disks index ed1afce4..24540601 100755 --- a/cdist/conf/explorer/disks +++ b/cdist/conf/explorer/disks @@ -1,4 +1,24 @@ #!/bin/sh -e +# +# based on previous work by other people, modified by: +# 2020 Dennis Camera +# +# 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 . +# +# Finds disks of the system (excl. ram disks, floppy, cdrom) uname_s="$(uname -s)" From b2db864eaf95a50e7e0d31be52f86ab1d0bea480 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Wed, 26 Feb 2020 13:01:29 +0100 Subject: [PATCH 55/64] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index 8463bb89..35590655 100644 --- a/docs/changelog +++ b/docs/changelog @@ -7,6 +7,7 @@ next: * Explorer init: Rewrite and support more init systems (Dennis Camera) * New type: __service (Timothée Floure) * Types __consul_*: Add optional parameter for using distribution packages (Timothée Floure) + * Explorer disks: Fix NetBSD, support Linux w/o lsblk (Dennis Camera) 6.5.1: 2020-02-15 * Type __consul_agent: Add Debian 10 support (Nico Schottelius) From 6b4b6534a1187e2533f627ff485873aeac7c4a32 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 26 Feb 2020 16:12:21 +0100 Subject: [PATCH 56/64] [__directory] Give more precise error message when --state pre-exists --- cdist/conf/type/__directory/gencode-remote | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/cdist/conf/type/__directory/gencode-remote b/cdist/conf/type/__directory/gencode-remote index e1ab69d7..a1a32ea2 100755 --- a/cdist/conf/type/__directory/gencode-remote +++ b/cdist/conf/type/__directory/gencode-remote @@ -109,10 +109,24 @@ case "$state_should" in done ;; pre-exists) - if [ "$type" != "directory" ]; then - echo "Directory \"$destination\" does not exist" >&2 - exit 1 - fi + case $type in + directory) + # all good + exit 0 + ;; + none) + printf 'Directory "%s" does not exist\n' "$destination" >&2 + exit 1 + ;; + file|symlink) + printf 'File "%s" exists and is a %s, but should be a directory\n' "$destination" "$type" >&2 + exit 1 + ;; + *) + printf 'File or directory "%s" is in an unknown state\n' "$destination" >&2 + exit 1 + ;; + esac ;; absent) if [ "$type" = "directory" ]; then From 046f7d0663fb6e117f76747bf71c7976abc90962 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Wed, 26 Feb 2020 16:32:03 +0100 Subject: [PATCH 57/64] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index 35590655..4fdfcd68 100644 --- a/docs/changelog +++ b/docs/changelog @@ -8,6 +8,7 @@ next: * New type: __service (Timothée Floure) * Types __consul_*: Add optional parameter for using distribution packages (Timothée Floure) * Explorer disks: Fix NetBSD, support Linux w/o lsblk (Dennis Camera) + * Type __directory: Add 'exists' and 'pre-exists' states (Dennis Camera) 6.5.1: 2020-02-15 * Type __consul_agent: Add Debian 10 support (Nico Schottelius) From 46d2487f08e04d3f6f3cbd434404dda006e83276 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 26 Feb 2020 16:40:53 +0100 Subject: [PATCH 58/64] [__file] Give more precise error message when --state pre-exists --- cdist/conf/type/__file/gencode-local | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/cdist/conf/type/__file/gencode-local b/cdist/conf/type/__file/gencode-local index fb9f9a92..231b6927 100755 --- a/cdist/conf/type/__file/gencode-local +++ b/cdist/conf/type/__file/gencode-local @@ -31,12 +31,24 @@ if [ "$state_should" = "pre-exists" ]; then exit 1 fi - if [ "$type" = "file" ]; then - exit 0 # nothing to do - else - echo "File \"$destination\" does not exist" - exit 1 - fi + case $type in + file) + # nothing to do + exit 0 + ;; + none) + printf 'File "%s" does not exist\n' "$destination" >&2 + exit 1 + ;; + directory|symlink) + printf 'File "%s" exists and is a %s, but should be a regular file\n' "$destination" "$type" >&2 + exit 1 + ;; + *) + printf 'File or directory "%s" is in an unknown state\n' "$destination" >&2 + exit 1 + ;; + esac fi upload_file= From 9eacba06bb218bd0627ef633b363495331ac6c5b Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 26 Feb 2020 16:48:14 +0100 Subject: [PATCH 59/64] [__file] Treat pre-exists as a special case in gencode-remote as it should never get there --- cdist/conf/type/__file/gencode-remote | 56 ++++++++++++++------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/cdist/conf/type/__file/gencode-remote b/cdist/conf/type/__file/gencode-remote index b04c471e..815593bd 100755 --- a/cdist/conf/type/__file/gencode-remote +++ b/cdist/conf/type/__file/gencode-remote @@ -55,37 +55,41 @@ set_owner() { } set_mode() { - echo "chmod '$1' '$destination'" - echo "chmod '$1'" >> "$__messages_out" - fire_onchange=1 + echo "chmod '$1' '$destination'" + echo "chmod '$1'" >> "$__messages_out" + fire_onchange=1 } case "$state_should" in - present|exists|pre-exists) - # Note: Mode - needs to happen last as a chown/chgrp can alter mode by - # clearing S_ISUID and S_ISGID bits (see chown(2)) - for attribute in group owner mode; do - if [ -f "$__object/parameter/$attribute" ]; then - value_should="$(cat "$__object/parameter/$attribute")" + present|exists) + # Note: Mode - needs to happen last as a chown/chgrp can alter mode by + # clearing S_ISUID and S_ISGID bits (see chown(2)) + for attribute in group owner mode; do + if [ -f "$__object/parameter/$attribute" ]; then + value_should="$(cat "$__object/parameter/$attribute")" - # change 0xxx format to xxx format => same as stat returns - if [ "$attribute" = mode ]; then - value_should="$(echo "$value_should" | sed 's/^0\(...\)/\1/')" - fi - - value_is="$(get_current_value "$attribute" "$value_should")" - if [ -f "$__object/files/set-attributes" ] || [ "$value_should" != "$value_is" ]; then - "set_$attribute" "$value_should" + # change 0xxx format to xxx format => same as stat returns + if [ "$attribute" = mode ]; then + value_should="$(echo "$value_should" | sed 's/^0\(...\)/\1/')" + fi + + value_is="$(get_current_value "$attribute" "$value_should")" + if [ -f "$__object/files/set-attributes" ] || [ "$value_should" != "$value_is" ]; then + "set_$attribute" "$value_should" + fi fi + done + if [ -f "$__object/files/set-attributes" ]; then + # set-attributes is created if file is created or uploaded in gencode-local + fire_onchange=1 fi - done - if [ -f "$__object/files/set-attributes" ]; then - # set-attributes is created if file is created or uploaded in gencode-local - fire_onchange=1 - fi - ;; + pre-exists) + # pre-exists should never reach gencode-remote… + exit 1 + ;; + absent) if [ "$type" = "file" ]; then echo "rm -f '$destination'" @@ -101,7 +105,7 @@ case "$state_should" in esac if [ -f "$__object/parameter/onchange" ]; then - if [ -n "$fire_onchange" ]; then - cat "$__object/parameter/onchange" - fi + if [ -n "$fire_onchange" ]; then + cat "$__object/parameter/onchange" + fi fi From da6ccf808ef4417b90e0882abd042f0a40f28a8e Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Wed, 26 Feb 2020 21:48:08 +0100 Subject: [PATCH 60/64] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index 4fdfcd68..9075cf3f 100644 --- a/docs/changelog +++ b/docs/changelog @@ -9,6 +9,7 @@ next: * Types __consul_*: Add optional parameter for using distribution packages (Timothée Floure) * Explorer disks: Fix NetBSD, support Linux w/o lsblk (Dennis Camera) * Type __directory: Add 'exists' and 'pre-exists' states (Dennis Camera) + * Type __file: Improve error messages for pre-exists state (Dennis Camera) 6.5.1: 2020-02-15 * Type __consul_agent: Add Debian 10 support (Nico Schottelius) From 213f1b049c55205ffe233de22e68c4a4738c8b82 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Thu, 27 Feb 2020 20:23:04 +0100 Subject: [PATCH 61/64] Release 6.5.2 --- docs/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog b/docs/changelog index 9075cf3f..64b124e8 100644 --- a/docs/changelog +++ b/docs/changelog @@ -1,7 +1,7 @@ Changelog --------- -next: +6.5.2: 2020-02-27 * Type __update_alternatives: Add state explorer (Ander Punnar) * Explorer os_version: Add support for Alpine Linux (Jin-Guk Kwon) * Explorer init: Rewrite and support more init systems (Dennis Camera) From fb32d6ed3f9421d515b0ec2eabe9ab4fcc6ccacb Mon Sep 17 00:00:00 2001 From: llnu Date: Sun, 8 Mar 2020 16:04:02 +0100 Subject: [PATCH 62/64] alpine uses a different getent lib which doesnt support: getent shadow --- cdist/conf/type/__user/explorer/shadow | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/conf/type/__user/explorer/shadow b/cdist/conf/type/__user/explorer/shadow index 73ce0e29..63d38f0d 100755 --- a/cdist/conf/type/__user/explorer/shadow +++ b/cdist/conf/type/__user/explorer/shadow @@ -24,7 +24,7 @@ name=$__object_id case $("$__explorer/os") in - 'freebsd'|'netbsd'|'openbsd') + 'freebsd'|'netbsd'|'openbsd'|'alpine') database='passwd' ;; # Default to using shadow passwords From f7d5f5bc974fff858c9999752badce3c6e8ba72e Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Mon, 9 Mar 2020 08:02:18 +0100 Subject: [PATCH 63/64] ++changelog --- docs/changelog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/changelog b/docs/changelog index 64b124e8..93df32a2 100644 --- a/docs/changelog +++ b/docs/changelog @@ -1,6 +1,9 @@ Changelog --------- +next: + * Type __user: Fix missing shadow for alpine (llnu) + 6.5.2: 2020-02-27 * Type __update_alternatives: Add state explorer (Ander Punnar) * Explorer os_version: Add support for Alpine Linux (Jin-Guk Kwon) From f00e4af5f0f1f49ab93be001468327ea90df6bd0 Mon Sep 17 00:00:00 2001 From: Andrew Schleifer Date: Thu, 26 Mar 2020 21:17:32 +0800 Subject: [PATCH 64/64] fix typo --- cdist/conf/type/__letsencrypt_cert/man.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cdist/conf/type/__letsencrypt_cert/man.rst b/cdist/conf/type/__letsencrypt_cert/man.rst index c4ffc6bc..85eb88ea 100644 --- a/cdist/conf/type/__letsencrypt_cert/man.rst +++ b/cdist/conf/type/__letsencrypt_cert/man.rst @@ -59,13 +59,13 @@ MESSAGES -------- change - Certificte was changed. + Certificate was changed. create - Certificte was created. + Certificate was created. remove - Certificte was removed. + Certificate was removed. EXAMPLES --------