From 6b63b3c369a5003f184442a0e2ed86c92104f145 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 19 Jan 2020 18:06:03 +0100 Subject: [PATCH 01/29] [__interface*] Add draft --- cdist/conf/type/__interface/man.rst | 49 +++++++ cdist/conf/type/__interface/manifest | 68 ++++++++++ cdist/conf/type/__interface/parameter/boolean | 4 + .../type/__interface/parameter/default/state | 1 + .../conf/type/__interface/parameter/optional | 5 + .../__interface/parameter/optional_multiple | 1 + .../__interface_ifupdown.d/gencode-remote | 20 +++ .../conf/type/__interface_ifupdown.d/man.rst | 57 ++++++++ .../conf/type/__interface_ifupdown.d/manifest | 126 ++++++++++++++++++ .../__interface_ifupdown.d/parameter/boolean | 4 + .../parameter/default/state | 1 + .../__interface_ifupdown.d/parameter/optional | 2 + .../parameter/optional_multiple | 1 + .../__interface_ifupdown.d/parameter/required | 2 + 14 files changed, 341 insertions(+) create mode 100644 cdist/conf/type/__interface/man.rst create mode 100755 cdist/conf/type/__interface/manifest create mode 100644 cdist/conf/type/__interface/parameter/boolean create mode 100644 cdist/conf/type/__interface/parameter/default/state create mode 100644 cdist/conf/type/__interface/parameter/optional create mode 100644 cdist/conf/type/__interface/parameter/optional_multiple create mode 100755 cdist/conf/type/__interface_ifupdown.d/gencode-remote create mode 100644 cdist/conf/type/__interface_ifupdown.d/man.rst create mode 100755 cdist/conf/type/__interface_ifupdown.d/manifest create mode 100644 cdist/conf/type/__interface_ifupdown.d/parameter/boolean create mode 100644 cdist/conf/type/__interface_ifupdown.d/parameter/default/state create mode 100644 cdist/conf/type/__interface_ifupdown.d/parameter/optional create mode 100644 cdist/conf/type/__interface_ifupdown.d/parameter/optional_multiple create mode 100644 cdist/conf/type/__interface_ifupdown.d/parameter/required diff --git a/cdist/conf/type/__interface/man.rst b/cdist/conf/type/__interface/man.rst new file mode 100644 index 00000000..17a92bdc --- /dev/null +++ b/cdist/conf/type/__interface/man.rst @@ -0,0 +1,49 @@ +cdist-type__interface(7) +======================== + +NAME +---- +cdist-type__interface - Manage network interfaces + + +DESCRIPTION +----------- +This cdist type allows you to manage network interfaces on the target. +It dispatches the actual work to the interface management system specific types. + + +REQUIRED PARAMETERS +------------------- +None. + + +OPTIONAL PARAMETERS +------------------- +None. + + +BOOLEAN PARAMETERS +------------------ +None. + + +EXAMPLES +-------- + +.. code-block:: sh + + # TODO + __interface + + +AUTHORS +------- +Dennis Camera + + +COPYING +------- +Copyright \(C) 2020 Dennis Camera. 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/__interface/manifest b/cdist/conf/type/__interface/manifest new file mode 100755 index 00000000..fbc5f988 --- /dev/null +++ b/cdist/conf/type/__interface/manifest @@ -0,0 +1,68 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +os=$(cat "${__global}/explorer/os") + +if test -f "${__object}/parameter/type" +then + type=$(cat "${__object}/parameter/type") +else + # Guess the type based on the operating system + case $os + in + debian) + os_major=$(grep -o '^[0-9][0-9]*' "${__global}/explorer/os_version") + if test "${os_major}" -ge 7 + then + type=ifupdown.d + else + echo 'Debian versions older than 7 (wheezy) are not (currently) supported' >&2 + exit 1 + fi + ;; + devuan) + type=ifupdown.d + ;; + *) + echo "Don't know how to manage interfaces on: ${os}" >&2 + exit 1 + ;; + esac +fi + +state=$(cat "${__object}/parameter/state") + +set -- "$@" "${__object_id}" --state "${state}" + +cd "${__object}/parameter" +for param in * +do + if [ "${param}" != 'type' ] && [ "${param}" != 'state' ] + then + set -- "$@" --"${param}" + if ! grep -q "^${param}$" "${__type}/parameter/boolean" + then + set -- "$@" "$(cat "${param}")" + fi + fi +done + + +__interface_$type "$@" diff --git a/cdist/conf/type/__interface/parameter/boolean b/cdist/conf/type/__interface/parameter/boolean new file mode 100644 index 00000000..ff58a1af --- /dev/null +++ b/cdist/conf/type/__interface/parameter/boolean @@ -0,0 +1,4 @@ +hotplug +no-auto +no-auto-down +no-scripts diff --git a/cdist/conf/type/__interface/parameter/default/state b/cdist/conf/type/__interface/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__interface/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__interface/parameter/optional b/cdist/conf/type/__interface/parameter/optional new file mode 100644 index 00000000..a85a910a --- /dev/null +++ b/cdist/conf/type/__interface/parameter/optional @@ -0,0 +1,5 @@ +family +method +name +state +type diff --git a/cdist/conf/type/__interface/parameter/optional_multiple b/cdist/conf/type/__interface/parameter/optional_multiple new file mode 100644 index 00000000..01925a15 --- /dev/null +++ b/cdist/conf/type/__interface/parameter/optional_multiple @@ -0,0 +1 @@ +option diff --git a/cdist/conf/type/__interface_ifupdown.d/gencode-remote b/cdist/conf/type/__interface_ifupdown.d/gencode-remote new file mode 100755 index 00000000..77ad9d25 --- /dev/null +++ b/cdist/conf/type/__interface_ifupdown.d/gencode-remote @@ -0,0 +1,20 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera@ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + diff --git a/cdist/conf/type/__interface_ifupdown.d/man.rst b/cdist/conf/type/__interface_ifupdown.d/man.rst new file mode 100644 index 00000000..f297f1da --- /dev/null +++ b/cdist/conf/type/__interface_ifupdown.d/man.rst @@ -0,0 +1,57 @@ +cdist-type__interface_ifupdown.d(7) +=================================== + +NAME +---- +cdist-type__interface_ifupdown.d - Manage network interfaces using ifupdown +using the interfaces.d directory + + +DESCRIPTION +----------- +This space intentionally left blank. + +NOTE: Only interfaces declared by cdist are removed when using --state absent. + Moreover, the interface declaration is identified by the object_id, + not by the interface's IP address or the like. + +REQUIRED PARAMETERS +------------------- +None. + + +OPTIONAL PARAMETERS +------------------- +None. + + +BOOLEAN PARAMETERS +------------------ +None. + + +EXAMPLES +-------- + +.. code-block:: sh + + # TODO + __interface_ifupdown.d + + +SEE ALSO +-------- +:strong:`TODO`\ (7) + + +AUTHORS +------- +Dennis Camera + + +COPYING +------- +Copyright \(C) 2020 Dennis Camera. 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/__interface_ifupdown.d/manifest b/cdist/conf/type/__interface_ifupdown.d/manifest new file mode 100755 index 00000000..4180db93 --- /dev/null +++ b/cdist/conf/type/__interface_ifupdown.d/manifest @@ -0,0 +1,126 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera@ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +INTERFACES_FILE=/etc/network/interfaces +INTERFACES_D_PATH=/etc/network/interfaces.d + +os=$(cat "$__global/explorer/os") + +state=$(cat "${__object}/parameter/state") + +case $os +in + debian) + os_major=$(grep -o '^[0-9][0-9]*' "${__global}/explorer/os_version") + if test "${os_major}" -lt 7 + then + # Old versions do not support "source" + printf 'Debian versions older than 7 (wheezy) are not supported by this type (%s)\n' "${__type##*/}" >&2 + exit 1 + fi + + if test "${state}" = 'present' + then + __package ifupdown --state present + export require=__package/ifupdown + fi + ;; + devuan) + if test "${state}" = 'present' + then + __package ifupdown --state present + export require=__package/ifupdown + fi + ;; + *) + printf 'Your operating system (%s) is currently not supported by this type (%s)\n' "$os" "${__type##*/}" >&2 + printf "Please contribute an implementation for it if you can.\n" >&2 + exit 1 + ;; +esac + + +name=$(test -s "${__object}/parameter/name" && cat "${__object}/parameter/name" || echo "${__object_id}") +addrfam=$(cat "${__object}/parameter/family") +method=$(cat "${__object}/parameter/method") + +options=$(test -s "${__object}/parameter/option" && cat "${__object}/parameter/option" || true) + +file_path="${INTERFACES_D_PATH}/${name}" + + +if test "${state}" = 'present' +then + # If state is present, ensure that the interfaces.d directory is sourced in + # the main interfaces file + __line "${INTERFACES_FILE}:source_interfaces.d" --state present \ + --file "${INTERFACES_FILE}" \ + --before '^#?[:blank:]*(auto|no-auto-down|no-scripts|allow-|iface|mapping|rename|source|source-directory)|^#[[:blank:]]*The .* interface$' \ + --line "source ${INTERFACES_D_PATH}/*" + + # FIXME: State should be --pre-exists... + __directory "${INTERFACES_D_PATH}" --owner root --mode 0644 --state present + + # NOTE: No file ending is used not to break the source-directory stanza (if + # used and at least for normal interface names) + # FIXME: The file will be left there when --state absent. It should be + # deleted if empty (could be non-empty if user has manual + # configuration) + require=__directory/"${INTERFACES_D_PATH}" + __file "${file_path}" --state exists --owner root --mode 0644 + export require="__file/${file_path}" +fi + + +# Put together the "allow" lines (these are the line(s) usually preceeding the +# iface line in the config) +allow='' +if ! test -f "${__object}/parameter/no-auto" +then + allow="${allow}auto ${name} +" +fi +if test -f "${__object}/parameter/hotplug" +then + allow="${allow}allow-hotplug ${name} +" +fi +if test -f "${__object}/parameter/no-auto-down" +then + allow="${allow}no-auto-down ${name} +" +fi +if test -f "${__object}/parameter/no-scripts" +then + allow="${allow}no-scripts ${name} +" +fi + + +# Construct file + +__block "${__object_id}" --state "${state}" \ + --file "${file_path}" \ + --prefix "#cdist:${__type##*/}/${__object_id}" \ + --suffix "#/cdist:${__type##*/}/${__object_id}" \ + --text - < Date: Wed, 29 Jan 2020 18:12:53 +0100 Subject: [PATCH 02/29] [type/__interface_ifupdown.d] Major refactor --- .../__interface_ifupdown.d/files/interfaces | 11 ++ .../__interface_ifupdown.d/gencode-remote | 20 --- .../conf/type/__interface_ifupdown.d/man.rst | 69 +++++++- .../conf/type/__interface_ifupdown.d/manifest | 160 +++++++++++------- .../__interface_ifupdown.d/parameter/boolean | 2 +- .../parameter/default/onchange | 1 + .../__interface_ifupdown.d/parameter/optional | 3 + 7 files changed, 181 insertions(+), 85 deletions(-) create mode 100644 cdist/conf/type/__interface_ifupdown.d/files/interfaces delete mode 100755 cdist/conf/type/__interface_ifupdown.d/gencode-remote create mode 100644 cdist/conf/type/__interface_ifupdown.d/parameter/default/onchange diff --git a/cdist/conf/type/__interface_ifupdown.d/files/interfaces b/cdist/conf/type/__interface_ifupdown.d/files/interfaces new file mode 100644 index 00000000..084df231 --- /dev/null +++ b/cdist/conf/type/__interface_ifupdown.d/files/interfaces @@ -0,0 +1,11 @@ +# Managed by cdist +# Changes will be overwritten. + +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +source /etc/network/interfaces.d/* + +# The loopback network interface +auto lo +iface lo inet loopback diff --git a/cdist/conf/type/__interface_ifupdown.d/gencode-remote b/cdist/conf/type/__interface_ifupdown.d/gencode-remote deleted file mode 100755 index 77ad9d25..00000000 --- a/cdist/conf/type/__interface_ifupdown.d/gencode-remote +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -e -# -# 2020 Dennis Camera (dennis.camera@ssrq-sds-fds.ch) -# -# This file is part of cdist. -# -# cdist is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# cdist is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with cdist. If not, see . -# - diff --git a/cdist/conf/type/__interface_ifupdown.d/man.rst b/cdist/conf/type/__interface_ifupdown.d/man.rst index f297f1da..3050b7c0 100644 --- a/cdist/conf/type/__interface_ifupdown.d/man.rst +++ b/cdist/conf/type/__interface_ifupdown.d/man.rst @@ -17,17 +17,70 @@ NOTE: Only interfaces declared by cdist are removed when using --state absent. REQUIRED PARAMETERS ------------------- -None. +family + The name of the address family that the interface uses. + Available options are: 'inet', 'ipx', 'inet6', 'can'. +method + The name of the method used to configure the interface. + Available options depend on the address family and are, for + inet: + 'loopback', 'static', 'manual', 'dhcp', 'bootp', 'tunnel', 'ppp', + 'wvdial', and 'ip4ll'. + ipx: + 'static', and 'dynamic'. + inet6: + 'auto', 'loopback', 'static', 'manual', 'dhcp', 'v4tunnel', '6to4'. + can: + 'static'. OPTIONAL PARAMETERS ------------------- -None. +name + The name of the logical interface to configure (usually equivalent to the + physical interface). + Defaults to __object_id. +comment + If supplied, the value will be inserted at the top of the configuration file + as a comment. + If comment is '-', what was written to stdin is used as the comment. +rename + If supplied, the given interface renaming spefication will be added to the + config file. + This option can e.g. be used to generate predictable interface names based on + the interface's MAC address. +state + Either present or absent. Defaults to present. +option + Additional option that is added to the generated interface configuration + verbatim. +onchange + The action to perform if the interface configuration has changed. + Available options are: + leave (default) + Do nothing. + up + Bring the interface up if it is down. + down + Bring the interface down if it is up. + refresh + Refresh the interface (down && up). BOOLEAN PARAMETERS ------------------ -None. +auto + If supplied, the interface will be marked "auto" and brought up during boot. +hotplug + Allow hotplug support for this interface. + The interface will be brought up when udev detects it, this can be during + boot or later. +no-auto-down + If supplied, the interface will not be brought down by the command + "ifdown -a". +no-scripts + If supplied, scripts in '/etc/network/if-*.d/' will not be run when this + interface is brought up or down. EXAMPLES @@ -35,13 +88,17 @@ EXAMPLES .. code-block:: sh - # TODO - __interface_ifupdown.d + # Configure interface eth0 to use DHCP. + __interface_ifupdown.d eth0 --family inet --method dhcp + + # Rename interface with MAC 00:11:22:33:44:55 to eth1 and use DHCP. + __interface_ifupdown.d eth1 --rename mac/00:11:22:33:44:55=eth1 \ + --family inet --method dhcp SEE ALSO -------- -:strong:`TODO`\ (7) +:strong:`interfaces`\ (5) AUTHORS diff --git a/cdist/conf/type/__interface_ifupdown.d/manifest b/cdist/conf/type/__interface_ifupdown.d/manifest index 4180db93..91ac3e82 100755 --- a/cdist/conf/type/__interface_ifupdown.d/manifest +++ b/cdist/conf/type/__interface_ifupdown.d/manifest @@ -21,10 +21,35 @@ INTERFACES_FILE=/etc/network/interfaces INTERFACES_D_PATH=/etc/network/interfaces.d -os=$(cat "$__global/explorer/os") +os=$(cat "${__global}/explorer/os") +name=$(test -s "${__object}/parameter/name" && cat "${__object}/parameter/name" || echo "${__object_id}") state=$(cat "${__object}/parameter/state") + +onchange_action() { + case $(cat "${__object}/parameter/onchange") + in + refresh) + printf "ifdown --force '%s' ; ifup '%s'\n" "${name}" "${name}" + ;; + up) + printf "ifup '%s'\n" "${name}" + ;; + down) + printf "ifdown --force '%s'\n" "${name}" + ;; + leave) + : # ignore + ;; + *) + printf 'Invalid option "%s" for --onchange!' "$(cat "${__object}/parameter/onchange")" >&2 + exit 1 + ;; + esac +} + + case $os in debian) @@ -57,70 +82,89 @@ in esac -name=$(test -s "${__object}/parameter/name" && cat "${__object}/parameter/name" || echo "${__object_id}") -addrfam=$(cat "${__object}/parameter/family") -method=$(cat "${__object}/parameter/method") - -options=$(test -s "${__object}/parameter/option" && cat "${__object}/parameter/option" || true) - -file_path="${INTERFACES_D_PATH}/${name}" - - if test "${state}" = 'present' then - # If state is present, ensure that the interfaces.d directory is sourced in - # the main interfaces file - __line "${INTERFACES_FILE}:source_interfaces.d" --state present \ - --file "${INTERFACES_FILE}" \ - --before '^#?[:blank:]*(auto|no-auto-down|no-scripts|allow-|iface|mapping|rename|source|source-directory)|^#[[:blank:]]*The .* interface$' \ - --line "source ${INTERFACES_D_PATH}/*" + if test "${IFUPDOWND_LEAVE_EXISTING_CONFIG:-0}" -eq 0 + then + # The /etc/network/interfaces file is overwritten with a basic example. + __file "${INTERFACES_FILE}" --state present --owner root --mode 0644 \ + --source "${__type}/files/interfaces" + else + # If state is present and IFUPDOWND_LEAVE_EXISTING_CONFIG is set, + # ensure that the interfaces.d directory is sourced in the main + # interfaces file, being as minimally invasive as possible. + __line "${INTERFACES_FILE}:source_interfaces.d" --state present \ + --file "${INTERFACES_FILE}" \ + --before '^#?[:blank:]*(auto|no-auto-down|no-scripts|allow-|iface|mapping|rename|source|source-directory)|^#[[:blank:]]*The .* interface$' \ + --line "source ${INTERFACES_D_PATH}/*" + fi # FIXME: State should be --pre-exists... - __directory "${INTERFACES_D_PATH}" --owner root --mode 0644 --state present - - # NOTE: No file ending is used not to break the source-directory stanza (if - # used and at least for normal interface names) - # FIXME: The file will be left there when --state absent. It should be - # deleted if empty (could be non-empty if user has manual - # configuration) - require=__directory/"${INTERFACES_D_PATH}" - __file "${file_path}" --state exists --owner root --mode 0644 - export require="__file/${file_path}" + __directory "${INTERFACES_D_PATH}" --owner root --mode 0755 --state present + export require="__directory/${INTERFACES_D_PATH}" fi -# Put together the "allow" lines (these are the line(s) usually preceeding the -# iface line in the config) -allow='' -if ! test -f "${__object}/parameter/no-auto" -then - allow="${allow}auto ${name} -" -fi -if test -f "${__object}/parameter/hotplug" -then - allow="${allow}allow-hotplug ${name} -" -fi -if test -f "${__object}/parameter/no-auto-down" -then - allow="${allow}no-auto-down ${name} -" -fi -if test -f "${__object}/parameter/no-scripts" -then - allow="${allow}no-scripts ${name} -" -fi +# Construct interface config file +( + cat <<-EOF + # Managed by cdist (${__type##*/}) + # Do not change. Changes will be overwritten. -# Construct file + EOF -__block "${__object_id}" --state "${state}" \ - --file "${file_path}" \ - --prefix "#cdist:${__type##*/}/${__object_id}" \ - --suffix "#/cdist:${__type##*/}/${__object_id}" \ - --text - < Date: Tue, 23 Jun 2020 12:59:29 +0200 Subject: [PATCH 03/29] [type/__interface] Partial implementation of type for ifupdown.d --- .../files/backends/ifupdown.d/manifest | 52 ++++++++++++ cdist/conf/type/__interface/man.rst | 48 ++++++++++- cdist/conf/type/__interface/manifest | 81 +++++++++++-------- cdist/conf/type/__interface/parameter/boolean | 6 +- .../__interface/parameter/default/bootproto | 1 + .../conf/type/__interface/parameter/optional | 6 +- .../__interface/parameter/optional_multiple | 3 +- 7 files changed, 157 insertions(+), 40 deletions(-) create mode 100755 cdist/conf/type/__interface/files/backends/ifupdown.d/manifest create mode 100644 cdist/conf/type/__interface/parameter/default/bootproto diff --git a/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest b/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest new file mode 100755 index 00000000..ecf7652b --- /dev/null +++ b/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest @@ -0,0 +1,52 @@ +#!/bin/sh -e +# -*- mode: sh; indent-tabs-mode: t -*- +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +set -- --state "${__object}/parameter/state" + +if test -f "${__object}/parameter/onboot" +then + set -- "$@" --auto +fi +if test -f "${__object}/parameter/hotplug" +then + set -- "$@" --hotplug +fi + +# Generate appropriate parameters for backend type +bootproto=$(cat "${__object}/parameter/bootproto") +case $bootproto +in + (dhcp) + # TODO + ;; + (static) + # TODO + ;; + (manual) + # TODO + ;; + (*) + exit 1 + ;; +esac + +# Instantiate backend type +__interface_ifupdown.d "@" diff --git a/cdist/conf/type/__interface/man.rst b/cdist/conf/type/__interface/man.rst index 17a92bdc..fc0772cf 100644 --- a/cdist/conf/type/__interface/man.rst +++ b/cdist/conf/type/__interface/man.rst @@ -10,6 +10,8 @@ DESCRIPTION ----------- This cdist type allows you to manage network interfaces on the target. It dispatches the actual work to the interface management system specific types. +Only TCP/IP is supported. For other protocol stacks, use the specific types for +your OS. REQUIRED PARAMETERS @@ -19,12 +21,54 @@ None. OPTIONAL PARAMETERS ------------------- -None. +state + 'present', 'absent', 'exists' or 'pre-exists', defaults to 'present' where: + + present + the file is exactly the one from source + absent + the file does not exist + exists + the file from source but only if it doesn't already exist + pre-exists + check that the file exists and is a regular file, but do not + create or modify it +name + The name of the physical or logical network device to configure. + Defaults to __object_id. +bootproto + The boot protocol to use. + Acceptable values are 'dhcp', 'static', 'manual'. + Defaults to 'dhcp'. +address + The IP address to assign to the network interface. + Can be repeated to assign multiple IP addresses. +gateway + The default gateway to assign to this interface (optional). +netmask + The netmask. +comment + A comment to be stored in the configuration file. +type + The backend to use to store the interface configuration. + Default is to auto detect. +extra-config + Other options to be passed to the implementation type verbatim. + Using this option makes the configuration non-portable to other backends. + If this option is used extensively, it is recommended to use the respective + backend type directly. BOOLEAN PARAMETERS ------------------ -None. +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. EXAMPLES diff --git a/cdist/conf/type/__interface/manifest b/cdist/conf/type/__interface/manifest index fbc5f988..f7c0816f 100755 --- a/cdist/conf/type/__interface/manifest +++ b/cdist/conf/type/__interface/manifest @@ -1,4 +1,5 @@ #!/bin/sh -e +# -*- mode: sh; indent-tabs-mode: t -*- # # 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # @@ -18,51 +19,67 @@ # along with cdist. If not, see . # +die() { echo "$*" >&2; exit 1; } +dief() { die "$(printf "$@")"; } +invalid_param() { die "$@"; } +invalid_paramf() { dief "$@"; } + + os=$(cat "${__global}/explorer/os") +# Parameters +state=$(cat "${__object}/parameter/state") +comment=$(cat "${__object}/parameter/comment") +bootproto=$(cat "${__object}/parameter/bootproto") + +case $bootproto +in + (dhcp) + # Check parameters + ! test -f "${__object}/parameter/address" \ + || invalid_param '--address is invalid for --bootproto dhcp' + ! test -f "${__object}/parameter/gateway" \ + || invalid_param '--gateway is invalid for --bootproto dhcp' + ! test -f "${__object}/parameter/netmask" \ + || invalid_param '--netmask is invalid for --bootproto dhcp' + ;; + (static) + # TODO + ;; + (manual) + # TODO + ;; + (*) + invalid_paramf 'Unknown --bootproto: %s\n' "${bootproto}" + ;; +esac + if test -f "${__object}/parameter/type" then - type=$(cat "${__object}/parameter/type") + impl_type=$(cat "${__object}/parameter/type") else # Guess the type based on the operating system case $os in - debian) + (debian) os_major=$(grep -o '^[0-9][0-9]*' "${__global}/explorer/os_version") - if test "${os_major}" -ge 7 - then - type=ifupdown.d - else - echo 'Debian versions older than 7 (wheezy) are not (currently) supported' >&2 - exit 1 - fi + test "${os_major}" -ge 7 \ + || die 'Debian versions older than 7 (wheezy) are not supported' + + impl_type=ifupdown.d ;; - devuan) - type=ifupdown.d + (devuan) + impl_type=ifupdown.d ;; - *) - echo "Don't know how to manage interfaces on: ${os}" >&2 - exit 1 + (*) + die "Don't know how to manage interfaces on: ${os}" ;; esac fi -state=$(cat "${__object}/parameter/state") +# Hand over to backend-specific implementation +manifest_file="${__type}/files/backends/${impl_type}/manifest" +test -x "${manifest_file}" || dief 'Unknown type: %s\n' "${impl_type}" -set -- "$@" "${__object_id}" --state "${state}" - -cd "${__object}/parameter" -for param in * -do - if [ "${param}" != 'type' ] && [ "${param}" != 'state' ] - then - set -- "$@" --"${param}" - if ! grep -q "^${param}$" "${__type}/parameter/boolean" - then - set -- "$@" "$(cat "${param}")" - fi - fi -done - - -__interface_$type "$@" +# Run backend-specific script +"${manifest_file}" "$@" diff --git a/cdist/conf/type/__interface/parameter/boolean b/cdist/conf/type/__interface/parameter/boolean index ff58a1af..fb0b6b4e 100644 --- a/cdist/conf/type/__interface/parameter/boolean +++ b/cdist/conf/type/__interface/parameter/boolean @@ -1,4 +1,4 @@ hotplug -no-auto -no-auto-down -no-scripts +nodns +noroute +onboot diff --git a/cdist/conf/type/__interface/parameter/default/bootproto b/cdist/conf/type/__interface/parameter/default/bootproto new file mode 100644 index 00000000..72ab18f1 --- /dev/null +++ b/cdist/conf/type/__interface/parameter/default/bootproto @@ -0,0 +1 @@ +dhcp diff --git a/cdist/conf/type/__interface/parameter/optional b/cdist/conf/type/__interface/parameter/optional index a85a910a..c17ca504 100644 --- a/cdist/conf/type/__interface/parameter/optional +++ b/cdist/conf/type/__interface/parameter/optional @@ -1,5 +1,7 @@ -family -method +bootproto +comment +gateway name +netmask state type diff --git a/cdist/conf/type/__interface/parameter/optional_multiple b/cdist/conf/type/__interface/parameter/optional_multiple index 01925a15..5bb11f03 100644 --- a/cdist/conf/type/__interface/parameter/optional_multiple +++ b/cdist/conf/type/__interface/parameter/optional_multiple @@ -1 +1,2 @@ -option +address +extra-config From bd14d074a0c9e1c05f6a34953bc23b935d9d02ed Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Tue, 23 Jun 2020 13:02:01 +0200 Subject: [PATCH 04/29] [type/__interface] Add backend stubs for RedHat, systemd, UCI --- .../type/__interface/explorer/has_networkctl | 24 +++++++++++++++++++ .../files/backends/redhat/manifest | 22 +++++++++++++++++ .../files/backends/systemd/manifest | 22 +++++++++++++++++ .../__interface/files/backends/uci/manifest | 22 +++++++++++++++++ cdist/conf/type/__interface/manifest | 13 +++++++++- 5 files changed, 102 insertions(+), 1 deletion(-) create mode 100755 cdist/conf/type/__interface/explorer/has_networkctl create mode 100755 cdist/conf/type/__interface/files/backends/redhat/manifest create mode 100755 cdist/conf/type/__interface/files/backends/systemd/manifest create mode 100755 cdist/conf/type/__interface/files/backends/uci/manifest diff --git a/cdist/conf/type/__interface/explorer/has_networkctl b/cdist/conf/type/__interface/explorer/has_networkctl new file mode 100755 index 00000000..dd247ae8 --- /dev/null +++ b/cdist/conf/type/__interface/explorer/has_networkctl @@ -0,0 +1,24 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# +# Check whether system has networkctl. +# + +command -v networkctl 2>/dev/null || true diff --git a/cdist/conf/type/__interface/files/backends/redhat/manifest b/cdist/conf/type/__interface/files/backends/redhat/manifest new file mode 100755 index 00000000..79156e40 --- /dev/null +++ b/cdist/conf/type/__interface/files/backends/redhat/manifest @@ -0,0 +1,22 @@ +#!/bin/sh -e +# -*- mode: sh; indent-tabs-mode: t -*- +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +# TODO diff --git a/cdist/conf/type/__interface/files/backends/systemd/manifest b/cdist/conf/type/__interface/files/backends/systemd/manifest new file mode 100755 index 00000000..79156e40 --- /dev/null +++ b/cdist/conf/type/__interface/files/backends/systemd/manifest @@ -0,0 +1,22 @@ +#!/bin/sh -e +# -*- mode: sh; indent-tabs-mode: t -*- +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +# TODO diff --git a/cdist/conf/type/__interface/files/backends/uci/manifest b/cdist/conf/type/__interface/files/backends/uci/manifest new file mode 100755 index 00000000..79156e40 --- /dev/null +++ b/cdist/conf/type/__interface/files/backends/uci/manifest @@ -0,0 +1,22 @@ +#!/bin/sh -e +# -*- mode: sh; indent-tabs-mode: t -*- +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +# TODO diff --git a/cdist/conf/type/__interface/manifest b/cdist/conf/type/__interface/manifest index f7c0816f..cd790976 100755 --- a/cdist/conf/type/__interface/manifest +++ b/cdist/conf/type/__interface/manifest @@ -71,8 +71,19 @@ else (devuan) impl_type=ifupdown.d ;; + (centos|redhat) + impl_type=redhat + ;; + (openwrt) + impl_type=uci + ;; (*) - die "Don't know how to manage interfaces on: ${os}" + if test -s "${__object}/explorer/has_networkctl" + then + impl_type=systemd + else + die "Don't know how to manage interfaces on: ${os}" + fi ;; esac fi From 2478881a3e427863d659c06f2c532b82179c585f Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 24 Jun 2020 11:52:08 +0200 Subject: [PATCH 05/29] [type/__interface_ifupdown.d] Lint --- .../conf/type/__interface_ifupdown.d/man.rst | 78 +++---- .../conf/type/__interface_ifupdown.d/manifest | 196 ++++++++++-------- 2 files changed, 143 insertions(+), 131 deletions(-) diff --git a/cdist/conf/type/__interface_ifupdown.d/man.rst b/cdist/conf/type/__interface_ifupdown.d/man.rst index 3050b7c0..205c6d64 100644 --- a/cdist/conf/type/__interface_ifupdown.d/man.rst +++ b/cdist/conf/type/__interface_ifupdown.d/man.rst @@ -18,69 +18,69 @@ NOTE: Only interfaces declared by cdist are removed when using --state absent. REQUIRED PARAMETERS ------------------- family - The name of the address family that the interface uses. - Available options are: 'inet', 'ipx', 'inet6', 'can'. + The name of the address family that the interface uses. + Available options are: 'inet', 'ipx', 'inet6', 'can'. method - The name of the method used to configure the interface. - Available options depend on the address family and are, for - inet: + The name of the method used to configure the interface. + Available options depend on the address family and are, for + inet: 'loopback', 'static', 'manual', 'dhcp', 'bootp', 'tunnel', 'ppp', 'wvdial', and 'ip4ll'. - ipx: + ipx: 'static', and 'dynamic'. - inet6: + inet6: 'auto', 'loopback', 'static', 'manual', 'dhcp', 'v4tunnel', '6to4'. - can: + can: 'static'. OPTIONAL PARAMETERS ------------------- name - The name of the logical interface to configure (usually equivalent to the - physical interface). - Defaults to __object_id. + The name of the logical interface to configure (usually equivalent to the + physical interface). + Defaults to __object_id. comment - If supplied, the value will be inserted at the top of the configuration file - as a comment. - If comment is '-', what was written to stdin is used as the comment. + If supplied, the value will be inserted at the top of the configuration file + as a comment. + If comment is '-', what was written to stdin is used as the comment. rename - If supplied, the given interface renaming spefication will be added to the - config file. - This option can e.g. be used to generate predictable interface names based on - the interface's MAC address. + If supplied, the given interface renaming spefication will be added to the + config file. + This option can e.g. be used to generate predictable interface names based + on the interface's MAC address. state - Either present or absent. Defaults to present. + Either present or absent. Defaults to present. option - Additional option that is added to the generated interface configuration - verbatim. + Option that is added to the generated interface configuration verbatim. + Can be used multiple times so add more than one option. onchange - The action to perform if the interface configuration has changed. - Available options are: - leave (default) - Do nothing. - up - Bring the interface up if it is down. - down - Bring the interface down if it is up. - refresh - Refresh the interface (down && up). + The action to perform if the interface configuration has changed. + Available options are: + leave (default) + Do nothing. + up + Bring the interface up if it is down. + down + Bring the interface down if it is up. + refresh + Refresh the interface (down && up). BOOLEAN PARAMETERS ------------------ auto - If supplied, the interface will be marked "auto" and brought up during boot. + If supplied, the interface will be marked "auto" and brought up during boot. hotplug - Allow hotplug support for this interface. - The interface will be brought up when udev detects it, this can be during - boot or later. + Allow hotplug support for this interface. + The interface will be brought up when udev detects it, this can be during + boot or later. no-auto-down - If supplied, the interface will not be brought down by the command - "ifdown -a". + If supplied, the interface will not be brought down by the command + "ifdown -a". no-scripts - If supplied, scripts in '/etc/network/if-*.d/' will not be run when this - interface is brought up or down. + If supplied, scripts in '/etc/network/if-*.d/' will not be run when this + interface is brought up or down. EXAMPLES diff --git a/cdist/conf/type/__interface_ifupdown.d/manifest b/cdist/conf/type/__interface_ifupdown.d/manifest index 91ac3e82..3f99e32d 100755 --- a/cdist/conf/type/__interface_ifupdown.d/manifest +++ b/cdist/conf/type/__interface_ifupdown.d/manifest @@ -23,27 +23,36 @@ INTERFACES_D_PATH=/etc/network/interfaces.d os=$(cat "${__global}/explorer/os") -name=$(test -s "${__object}/parameter/name" && cat "${__object}/parameter/name" || echo "${__object_id}") +if test -s "${__object}/parameter/name" +then + name=$(cat "${__object}/parameter/name") +else + name=$__object_id +fi +onchange_action=$(cat "${__object}/parameter/onchange") state=$(cat "${__object}/parameter/state") +# NOTE: No file ending is used not to break the source-directory stanza +# (if used and at least for normal interface names) +iface_file="${INTERFACES_D_PATH}/${__object_id}" onchange_action() { - case $(cat "${__object}/parameter/onchange") + case $onchange_action in - refresh) + (refresh) printf "ifdown --force '%s' ; ifup '%s'\n" "${name}" "${name}" ;; - up) + (up) printf "ifup '%s'\n" "${name}" ;; - down) + (down) printf "ifdown --force '%s'\n" "${name}" ;; - leave) - : # ignore + (leave) + # ignore ;; - *) - printf 'Invalid option "%s" for --onchange!' "$(cat "${__object}/parameter/onchange")" >&2 + (*) + printf 'Invalid --onchange: %s\n' "${onchange_action}" >&2 exit 1 ;; esac @@ -52,7 +61,7 @@ onchange_action() { case $os in - debian) + (debian) os_major=$(grep -o '^[0-9][0-9]*' "${__global}/explorer/os_version") if test "${os_major}" -lt 7 then @@ -67,104 +76,107 @@ in export require=__package/ifupdown fi ;; - devuan) + (devuan) if test "${state}" = 'present' then __package ifupdown --state present export require=__package/ifupdown fi ;; - *) + (*) printf 'Your operating system (%s) is currently not supported by this type (%s)\n' "$os" "${__type##*/}" >&2 printf "Please contribute an implementation for it if you can.\n" >&2 exit 1 ;; esac - -if test "${state}" = 'present' -then - if test "${IFUPDOWND_LEAVE_EXISTING_CONFIG:-0}" -eq 0 - then - # The /etc/network/interfaces file is overwritten with a basic example. - __file "${INTERFACES_FILE}" --state present --owner root --mode 0644 \ - --source "${__type}/files/interfaces" - else - # If state is present and IFUPDOWND_LEAVE_EXISTING_CONFIG is set, - # ensure that the interfaces.d directory is sourced in the main - # interfaces file, being as minimally invasive as possible. - __line "${INTERFACES_FILE}:source_interfaces.d" --state present \ - --file "${INTERFACES_FILE}" \ - --before '^#?[:blank:]*(auto|no-auto-down|no-scripts|allow-|iface|mapping|rename|source|source-directory)|^#[[:blank:]]*The .* interface$' \ - --line "source ${INTERFACES_D_PATH}/*" - fi - - # FIXME: State should be --pre-exists... - __directory "${INTERFACES_D_PATH}" --owner root --mode 0755 --state present - export require="__directory/${INTERFACES_D_PATH}" -fi - - -# Construct interface config file - -( - cat <<-EOF - # Managed by cdist (${__type##*/}) - # Do not change. Changes will be overwritten. - - EOF - - if test -f "${__object}/parameter/comment" - then - # Prefix lines with # and append trailing empty line. - - comment_file="${__object}/parameter/comment" - if test "$(cat "${comment_file}")" = '-' +case $state +in + (present) + if test "${IFUPDOWND_LEAVE_EXISTING_CONFIG:-0}" -eq 0 then - comment_file="${__object}/stdin" + # The /etc/network/interfaces file is overwritten with a basic example. + __file "${INTERFACES_FILE}" --state present --owner root --mode 0644 \ + --source "${__type}/files/interfaces" + else + # If state is present and IFUPDOWND_LEAVE_EXISTING_CONFIG is set, + # ensure that the interfaces.d directory is sourced in the main + # interfaces file, being as minimally invasive as possible. + __line "${INTERFACES_FILE}:source_interfaces.d" --state present \ + --file "${INTERFACES_FILE}" \ + --before '^#?[:blank:]*(auto|no-auto-down|no-scripts|allow-|iface|mapping|rename|source|source-directory)|^#[[:blank:]]*The .* interface$' \ + --line "source ${INTERFACES_D_PATH}/*" fi - # shellcheck disable=SC2016 - sed -e 's/^/# /;$G' "${comment_file}" - unset comment_file - fi + __directory "${INTERFACES_D_PATH}" --state pre-exists \ + --owner root --mode 0755 + export require="__directory/${INTERFACES_D_PATH}" - # Put together rename line - if test -s "${__object}/parameter/rename" - then - printf 'rename %s\n' "$(cat "${__object}/parameter/rename")" - fi + # Construct interface config file + ( + cat <<-EOF + # Managed by cdist (${__type##*/}) + # Do not change. Changes will be overwritten. - # Put together the "allow" lines (these are the line(s) usually preceeding - # the iface line in the config). - if test -f "${__object}/parameter/onboot" - then - printf 'auto %s\n' "$name" - fi - if test -f "${__object}/parameter/hotplug" - then - printf 'allow-hotplug %s\n' "$name" - fi - if test -f "${__object}/parameter/no-auto-down" - then - printf 'no-auto-down %s\n' "$name" - fi - if test -f "${__object}/parameter/no-scripts" - then - printf 'no-scripts %s\n' "$name" - fi + EOF - addrfam=$(cat "${__object}/parameter/family") - method=$(cat "${__object}/parameter/method") - printf 'iface %s %s %s\n' "$name" "$addrfam" "$method" + if test -s "${__object}/parameter/comment" + then + # Prefix lines with # and append trailing empty line. + # shellcheck disable=SC2016 + { + if test "$(cat "${__object}/parameter/comment")" = '-' + then + cat "${__object}/stdin" + else + cat "${__object}/parameter/comment" + fi + } | sed -e 's/^/# /;$G' + fi - while read -r opt - do - printf '\t%s\n' "$opt" - done <"${__object}/parameter/option" -) | \ -# NOTE: No file ending is used not to break the source-directory stanza (if -# used and at least for normal interface names) -__file "${INTERFACES_D_PATH}/${__object_id}" --state "$state" \ - --owner root --mode 0644 --source - \ - --onchange "$(onchange_action)" + # Put together rename line + if test -s "${__object}/parameter/rename" + then + printf 'rename %s\n' "$(cat "${__object}/parameter/rename")" + fi + + # Put together the "allow" lines (these are the line(s) usually + # preceeding the iface line in the config). + if test -f "${__object}/parameter/auto" + then + printf 'auto %s\n' "${name}" + fi + if test -f "${__object}/parameter/hotplug" + then + printf 'allow-hotplug %s\n' "${name}" + fi + if test -f "${__object}/parameter/no-auto-down" + then + printf 'no-auto-down %s\n' "${name}" + fi + if test -f "${__object}/parameter/no-scripts" + then + printf 'no-scripts %s\n' "${name}" + fi + + addrfam=$(cat "${__object}/parameter/family") + method=$(cat "${__object}/parameter/method") + printf 'iface %s %s %s\n' "${name}" "${addrfam}" "${method}" + + while read -r _opt + do + printf '\t%s\n' "${_opt}" + done <"${__object}/parameter/option" + unset _opt + ) | __file "${iface_file}" --state present --owner root --mode 0644 \ + --onchange "$(onchange_action)" --source - + ;; + (absent) + __file "${iface_file}" --state absent \ + --onchange "$(onchange_action)" + ;; + (*) + printf 'Invalid --state: %s\n' "${state}" >&2 + exit 1 + ;; +esac From 48ba42f49c914ec37130767544dfcb1edbe477cd Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 24 Jun 2020 12:51:05 +0200 Subject: [PATCH 06/29] [type/__interface] Use exec to run backend script --- cdist/conf/type/__interface/manifest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/conf/type/__interface/manifest b/cdist/conf/type/__interface/manifest index cd790976..607c9cb0 100755 --- a/cdist/conf/type/__interface/manifest +++ b/cdist/conf/type/__interface/manifest @@ -93,4 +93,4 @@ manifest_file="${__type}/files/backends/${impl_type}/manifest" test -x "${manifest_file}" || dief 'Unknown type: %s\n' "${impl_type}" # Run backend-specific script -"${manifest_file}" "$@" +exec "${manifest_file}" From c83f90ed2cf0d633ceee1d476accf8924c5025c2 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 24 Jun 2020 12:51:21 +0200 Subject: [PATCH 07/29] [type/__interface] Implement ifupdown.d backend --- .../files/backends/ifupdown.d/manifest | 65 +++++++++++++++++-- cdist/conf/type/__interface/manifest | 10 +-- 2 files changed, 64 insertions(+), 11 deletions(-) diff --git a/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest b/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest index ecf7652b..6b9af804 100755 --- a/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest +++ b/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest @@ -19,8 +19,21 @@ # along with cdist. If not, see . # -set -- --state "${__object}/parameter/state" +opt_format() { + printf '%s %s\n' "${1:?'option name missing'}" "${2:?'option value missing'}" +} +opt_from_param() { + # Only first line will be read. + opt_format \ + "${1:?'option name missing'}" \ + "$(head -n 1 "${__object}/parameter/${2:?'parameter name missing'}")" +} + + +set -- --state "$(cat "${__object}/parameter/state")" --family inet + +# Boolean flags if test -f "${__object}/parameter/onboot" then set -- "$@" --auto @@ -30,23 +43,63 @@ then set -- "$@" --hotplug fi -# Generate appropriate parameters for backend type + +if test -f "${__object}/parameter/name" +then + set -- "$@" --name "$(cat "${__object}/parameter/name")" +fi + + +# Generate appropriate parameters based on bootproto bootproto=$(cat "${__object}/parameter/bootproto") case $bootproto in (dhcp) - # TODO + set -- "$@" --method dhcp ;; (static) - # TODO + set -- "$@" --method static + + if test -s "${__object}/parameter/address" + then + while read -r _value + do + set -- "$@" --option "$(opt_format address "${_value}")" + done <"${__object}/parameter/address" + unset _value + fi + + if test -s "${__object}/parameter/netmask" + then + set -- "$@" --option "$(opt_from_param netmask netmask)" + fi + + if test -s "${__object}/parameter/gateway" + then + set -- "$@" --option "$(opt_from_param gateway gateway)" + fi ;; (manual) - # TODO + set -- "$@" --method manual ;; (*) exit 1 ;; esac +if test -s "${__object}/parameter/comment" +then + set -- "$@" --comment "$(cat "${__object}/parameter/comment")" +fi + +if test -s "${__object}/parameter/extra-config" +then + while read -r _opt + do + set -- "$@" --option "${_opt}" + done <"${__object}/parameter/extra-config" + unset _opt +fi + # Instantiate backend type -__interface_ifupdown.d "@" +__interface_ifupdown.d "${__object_id}" "$@" <"${__object}/stdin" diff --git a/cdist/conf/type/__interface/manifest b/cdist/conf/type/__interface/manifest index 607c9cb0..fd6f22dd 100755 --- a/cdist/conf/type/__interface/manifest +++ b/cdist/conf/type/__interface/manifest @@ -20,18 +20,18 @@ # die() { echo "$*" >&2; exit 1; } -dief() { die "$(printf "$@")"; } +dief() { + #shellcheck disable=SC2059 + die "$(printf "$@")" +} invalid_param() { die "$@"; } invalid_paramf() { dief "$@"; } os=$(cat "${__global}/explorer/os") -# Parameters -state=$(cat "${__object}/parameter/state") -comment=$(cat "${__object}/parameter/comment") +# Check parameters bootproto=$(cat "${__object}/parameter/bootproto") - case $bootproto in (dhcp) From be5904748802ed1ca68bf7fc99a2b5b50ed38755 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 24 Jun 2020 13:38:51 +0200 Subject: [PATCH 08/29] [type/__interface] Add --onchange parameter --- .../__interface/files/backends/ifupdown.d/manifest | 5 +++++ cdist/conf/type/__interface/man.rst | 11 +++++++++++ .../conf/type/__interface/parameter/default/onchange | 1 + cdist/conf/type/__interface/parameter/optional | 1 + 4 files changed, 18 insertions(+) create mode 100644 cdist/conf/type/__interface/parameter/default/onchange diff --git a/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest b/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest index 6b9af804..69cd515d 100755 --- a/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest +++ b/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest @@ -92,6 +92,11 @@ then set -- "$@" --comment "$(cat "${__object}/parameter/comment")" fi +if test -s "${__object}/parameter/onchange" +then + set -- "$@" --onchange "$(cat "${__object}/parameter/onchange")" +fi + if test -s "${__object}/parameter/extra-config" then while read -r _opt diff --git a/cdist/conf/type/__interface/man.rst b/cdist/conf/type/__interface/man.rst index fc0772cf..3dc35f87 100644 --- a/cdist/conf/type/__interface/man.rst +++ b/cdist/conf/type/__interface/man.rst @@ -57,6 +57,17 @@ extra-config Using this option makes the configuration non-portable to other backends. If this option is used extensively, it is recommended to use the respective backend type directly. +onchange + The action to perform if the interface configuration has changed. + Available options are: + leave (default) + Do nothing. + up + Bring the interface up if it is down. + down + Bring the interface down if it is up. + refresh + Refresh the interface (down && up). BOOLEAN PARAMETERS diff --git a/cdist/conf/type/__interface/parameter/default/onchange b/cdist/conf/type/__interface/parameter/default/onchange new file mode 100644 index 00000000..e8f9c907 --- /dev/null +++ b/cdist/conf/type/__interface/parameter/default/onchange @@ -0,0 +1 @@ +leave diff --git a/cdist/conf/type/__interface/parameter/optional b/cdist/conf/type/__interface/parameter/optional index c17ca504..0af245b0 100644 --- a/cdist/conf/type/__interface/parameter/optional +++ b/cdist/conf/type/__interface/parameter/optional @@ -3,5 +3,6 @@ comment gateway name netmask +onchange state type From 02ca74731dcd12d33b19560af1c6e9b924626b25 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 24 Jun 2020 14:39:36 +0200 Subject: [PATCH 09/29] [type/__interface] Draft UCI backend --- .../__interface/files/backends/uci/manifest | 117 +++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) diff --git a/cdist/conf/type/__interface/files/backends/uci/manifest b/cdist/conf/type/__interface/files/backends/uci/manifest index 79156e40..60165333 100755 --- a/cdist/conf/type/__interface/files/backends/uci/manifest +++ b/cdist/conf/type/__interface/files/backends/uci/manifest @@ -19,4 +19,119 @@ # along with cdist. If not, see . # -# TODO +opt_format() { + printf "%s='%s'\\n" "${1:?'option name missing'}" "${2:?'option value missing'}" +} + +opt_from_param() { + # Only first line will be read. + opt_format \ + "${1:?'option name missing'}" \ + "$(head -n 1 "${__object}/parameter/${2:?'parameter name missing'}")" +} + +onchange_action=$(cat "${__object}/parameter/onchange") +state=$(cat "${__object}/parameter/state") + +obj_name="network.${__object_id}" + +onchange_action() { + case $onchange_action + in + (refresh) + printf "ifup '%s'\n" "${__object_id}" + ;; + (up) + # shellcheck disable=SC2016 + echo 'isifup()(up=0; . /usr/share/libubox/jshn.sh && json_load "$(ifstatus "$1")" && json_get_var up up; return $((!up)))' + printf "isifup '%s' || ifup '%s'\n" "${__object_id}" "${__object_id}" + ;; + (down) + printf "ifdown '%s'\n" "${__object_id}" + ;; + (leave) + # ignore + ;; + (*) + printf 'Invalid --onchange: %s\n' "${onchange_action}" >&2 + exit 1 + ;; + esac +} + + +set -- --state "${state}" --transaction "${obj_name}" + +if test -s "${__object}/parameter/comment" +then + set -- "$@" --option "$(opt_from_param _comment comment)" +fi + +if test -f "${__object}/parameter/name" +then + set -- "$@" --option "$(opt_from_param ifname name)" +else + set -- "$@" --option "$(opt_format ifname "${__object_id}")" +fi + +set -- "$@" --option "$(opt_format auto "$( + ! test -f "${__object}/parameter/onboot"; echo $?)")" +set -- "$@" --option "$(opt_format force_link "$( + test -f "${__object}/parameter/hotplug"; echo $?)")" + +# Generate appropriate parameters based on bootproto +bootproto=$(cat "${__object}/parameter/bootproto") +case $bootproto +in + (dhcp) + set -- "$@" --option "$(opt_format proto dhcp)" + ;; + (static) + set -- "$@" --option "$(opt_format proto static)" + + if test -s "${__object}/parameter/address" + then + while read -r _value + do + set -- "$@" --option "$(opt_format ipaddr "${_value}")" + done <"${__object}/parameter/address" + unset _value + fi + + if test -s "${__object}/parameter/netmask" + then + set -- "$@" --option "$(opt_from_param netmask netmask)" + fi + + if test -s "${__object}/parameter/gateway" + then + set -- "$@" --option "$(opt_from_param gateway gateway)" + fi + ;; + (manual) + set -- "$@" --option "$(opt_format proto static)" + ;; + (*) + exit 1 + ;; +esac + +if test -s "${__object}/parameter/extra-config" +then + while read -r _opt + do + set -- "$@" --option "${_opt}" + done <"${__object}/parameter/extra-config" + unset _opt +fi + +# Instantiate backend type +__uci_section "${obj_name}" --type network.interface "$@" + +if test -s "${__object}/parameter/onchange" +then + require=__uci_commit/"${obj_name}" \ + __check_messages "interface_${__object_id}_onchange" \ + --pattern "^__uci_commit/network.${__object_id}:" \ + --execute "$(onchange_action)" +fi From 02d8177c4ad6e5ce28002fb60f93a9fdcd39e8cc Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Fri, 26 Jun 2020 18:08:50 +0200 Subject: [PATCH 10/29] [type/__interface] Remove --nodns, --noroute parameters They can be re-added when they get implemented. --- cdist/conf/type/__interface/man.rst | 4 ---- cdist/conf/type/__interface/parameter/boolean | 2 -- 2 files changed, 6 deletions(-) diff --git a/cdist/conf/type/__interface/man.rst b/cdist/conf/type/__interface/man.rst index 3dc35f87..a352669e 100644 --- a/cdist/conf/type/__interface/man.rst +++ b/cdist/conf/type/__interface/man.rst @@ -76,10 +76,6 @@ 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. EXAMPLES diff --git a/cdist/conf/type/__interface/parameter/boolean b/cdist/conf/type/__interface/parameter/boolean index fb0b6b4e..2b6d0a3b 100644 --- a/cdist/conf/type/__interface/parameter/boolean +++ b/cdist/conf/type/__interface/parameter/boolean @@ -1,4 +1,2 @@ hotplug -nodns -noroute onboot From 931c78b3f79e0a9ec6ccfbe4a361e7be0083076b Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Fri, 26 Jun 2020 18:14:46 +0200 Subject: [PATCH 11/29] [type/__interface] Sort options in man page --- cdist/conf/type/__interface/man.rst | 38 +++++++++++------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/cdist/conf/type/__interface/man.rst b/cdist/conf/type/__interface/man.rst index a352669e..b8dc670d 100644 --- a/cdist/conf/type/__interface/man.rst +++ b/cdist/conf/type/__interface/man.rst @@ -21,42 +21,27 @@ None. OPTIONAL PARAMETERS ------------------- -state - 'present', 'absent', 'exists' or 'pre-exists', defaults to 'present' where: - - present - the file is exactly the one from source - absent - the file does not exist - exists - the file from source but only if it doesn't already exist - pre-exists - check that the file exists and is a regular file, but do not - create or modify it -name - The name of the physical or logical network device to configure. - Defaults to __object_id. -bootproto - The boot protocol to use. - Acceptable values are 'dhcp', 'static', 'manual'. - Defaults to 'dhcp'. address The IP address to assign to the network interface. Can be repeated to assign multiple IP addresses. -gateway - The default gateway to assign to this interface (optional). netmask The netmask. +bootproto + The boot protocol to use. + Acceptable values are ``dhcp``, ``static``, ``manual``. + Defaults to ``dhcp``. comment A comment to be stored in the configuration file. -type - The backend to use to store the interface configuration. - Default is to auto detect. extra-config Other options to be passed to the implementation type verbatim. Using this option makes the configuration non-portable to other backends. If this option is used extensively, it is recommended to use the respective backend type directly. +gateway + The default gateway to assign to this interface (optional). +name + The name of the physical or logical network device to configure. + Defaults to ``__object_id``. onchange The action to perform if the interface configuration has changed. Available options are: @@ -68,6 +53,11 @@ onchange Bring the interface down if it is up. refresh Refresh the interface (down && up). +state + ``present`` or ``absent``, defaults to ``present``. +type + The backend to use to store the interface configuration. + Default is to auto detect. BOOLEAN PARAMETERS From 6667f0920bfc48b5477bf8506f525e787d62d446 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Fri, 26 Jun 2020 22:32:12 +0200 Subject: [PATCH 12/29] [type/__interface] Drop --netmask parameter --- .../conf/type/__interface/files/backends/ifupdown.d/manifest | 5 ----- cdist/conf/type/__interface/files/backends/uci/manifest | 5 ----- cdist/conf/type/__interface/man.rst | 4 +--- cdist/conf/type/__interface/manifest | 2 -- cdist/conf/type/__interface/parameter/optional | 1 - 5 files changed, 1 insertion(+), 16 deletions(-) diff --git a/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest b/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest index 69cd515d..ac596746 100755 --- a/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest +++ b/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest @@ -69,11 +69,6 @@ in unset _value fi - if test -s "${__object}/parameter/netmask" - then - set -- "$@" --option "$(opt_from_param netmask netmask)" - fi - if test -s "${__object}/parameter/gateway" then set -- "$@" --option "$(opt_from_param gateway gateway)" diff --git a/cdist/conf/type/__interface/files/backends/uci/manifest b/cdist/conf/type/__interface/files/backends/uci/manifest index 60165333..8c812638 100755 --- a/cdist/conf/type/__interface/files/backends/uci/manifest +++ b/cdist/conf/type/__interface/files/backends/uci/manifest @@ -98,11 +98,6 @@ in unset _value fi - if test -s "${__object}/parameter/netmask" - then - set -- "$@" --option "$(opt_from_param netmask netmask)" - fi - if test -s "${__object}/parameter/gateway" then set -- "$@" --option "$(opt_from_param gateway gateway)" diff --git a/cdist/conf/type/__interface/man.rst b/cdist/conf/type/__interface/man.rst index b8dc670d..7784047f 100644 --- a/cdist/conf/type/__interface/man.rst +++ b/cdist/conf/type/__interface/man.rst @@ -22,10 +22,8 @@ None. OPTIONAL PARAMETERS ------------------- address - The IP address to assign to the network interface. + The IP address (in CIDR notation) to assign to the network interface. Can be repeated to assign multiple IP addresses. -netmask - The netmask. bootproto The boot protocol to use. Acceptable values are ``dhcp``, ``static``, ``manual``. diff --git a/cdist/conf/type/__interface/manifest b/cdist/conf/type/__interface/manifest index fd6f22dd..661674cc 100755 --- a/cdist/conf/type/__interface/manifest +++ b/cdist/conf/type/__interface/manifest @@ -40,8 +40,6 @@ in || invalid_param '--address is invalid for --bootproto dhcp' ! test -f "${__object}/parameter/gateway" \ || invalid_param '--gateway is invalid for --bootproto dhcp' - ! test -f "${__object}/parameter/netmask" \ - || invalid_param '--netmask is invalid for --bootproto dhcp' ;; (static) # TODO diff --git a/cdist/conf/type/__interface/parameter/optional b/cdist/conf/type/__interface/parameter/optional index 0af245b0..16ae6fba 100644 --- a/cdist/conf/type/__interface/parameter/optional +++ b/cdist/conf/type/__interface/parameter/optional @@ -2,7 +2,6 @@ bootproto comment gateway name -netmask onchange state type From 22b515e624ea660bd2c3c60d33c05f7e664dd966 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Fri, 26 Jun 2020 18:08:13 +0200 Subject: [PATCH 13/29] [type/__systemd_networkd_network] Add type --- .../explorer/networkctl_bin | 24 ++++ .../__systemd_networkd_network/explorer/state | 60 +++++++++ .../type/__systemd_networkd_network/man.rst | 69 ++++++++++ .../type/__systemd_networkd_network/manifest | 121 ++++++++++++++++++ .../parameter/boolean | 1 + .../parameter/default/priority | 1 + .../parameter/default/state | 1 + .../parameter/optional | 3 + .../parameter/optional_multiple | 2 + 9 files changed, 282 insertions(+) create mode 100755 cdist/conf/type/__systemd_networkd_network/explorer/networkctl_bin create mode 100755 cdist/conf/type/__systemd_networkd_network/explorer/state create mode 100644 cdist/conf/type/__systemd_networkd_network/man.rst create mode 100755 cdist/conf/type/__systemd_networkd_network/manifest create mode 100644 cdist/conf/type/__systemd_networkd_network/parameter/boolean create mode 100644 cdist/conf/type/__systemd_networkd_network/parameter/default/priority create mode 100644 cdist/conf/type/__systemd_networkd_network/parameter/default/state create mode 100644 cdist/conf/type/__systemd_networkd_network/parameter/optional create mode 100644 cdist/conf/type/__systemd_networkd_network/parameter/optional_multiple diff --git a/cdist/conf/type/__systemd_networkd_network/explorer/networkctl_bin b/cdist/conf/type/__systemd_networkd_network/explorer/networkctl_bin new file mode 100755 index 00000000..e2cf8409 --- /dev/null +++ b/cdist/conf/type/__systemd_networkd_network/explorer/networkctl_bin @@ -0,0 +1,24 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# +# Prints the path of networkctl if found on the target system. +# + +command -v networkctl 2>/dev/null || true diff --git a/cdist/conf/type/__systemd_networkd_network/explorer/state b/cdist/conf/type/__systemd_networkd_network/explorer/state new file mode 100755 index 00000000..75913e11 --- /dev/null +++ b/cdist/conf/type/__systemd_networkd_network/explorer/state @@ -0,0 +1,60 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# +# Check whether a configuration for the interface already exists with the same +# name already exists. +# The output will be "exists" followed by the config file path on the next line, +# or "absent" +# In case networkctl cannot be found, the output will be "error". +# + +networkctl_bin=$("${__type_explorer}/networkctl_bin") + +test -x "${networkctl_bin}" || { echo error; exit 0; } + +if test -f "${__object}/parameter/name" +then + name=$(cat "${__object}/parameter/name") +else + name=$__object_id +fi + +if "${networkctl_bin}" --no-pager --no-legend list "${name}" >/dev/null 2>&1 +then + echo exists + + "${networkctl_bin}" --no-pager --no-legend status "${name}" \ + | awk -F ': ' -v ifname="${name}" ' + BEGIN { + # header line + getline + # · N: en... + if (index($2, ifname) != 1 || substr($2, length(ifname) + 1) !~ /^[[:blank:]]*$/) + exit + } + !$0 { exit } # skip journal lines + /^[[:blank:]]*Network File:/ { + sub(/[[:blank:]]*$/, "", $2) + print $2 + }' \ + | grep -ixvF 'n/a' || true # networkctl prints "n/a" if iface is unmanaged +else + echo absent +fi diff --git a/cdist/conf/type/__systemd_networkd_network/man.rst b/cdist/conf/type/__systemd_networkd_network/man.rst new file mode 100644 index 00000000..3cc999fe --- /dev/null +++ b/cdist/conf/type/__systemd_networkd_network/man.rst @@ -0,0 +1,69 @@ +cdist-type__systemd_networkd_network(7) +======================================= + +NAME +---- +cdist-type__systemd_networkd_network - Manage network configuration using +systemd-networkd. + + +DESCRIPTION +----------- +This space intentionally left blank. + + +REQUIRED PARAMETERS +------------------- +None. + + +OPTIONAL PARAMETERS +------------------- +match + Match directives can be used to filter the interfaces to which this + configuration applies. This paramter can be used multiple times. + The value will be copied to the [Match] section of the config file verbatim. + Defaults to: "Name={interface name}" +name + The name of the interface to configure. +option + ... +priority + The "priority" of this configuration. It is used as a prefix to the + configuration file name. + Defaults to 10. +state + Either ``present`` or ``absent``. Defaults to ``present``. + + +BOOLEAN PARAMETERS +------------------ +auto-reload + Automatically apply new config after changes have been written. + + +EXAMPLES +-------- + +.. code-block:: sh + + # TODO + __systemd_networkd_network + + +SEE ALSO +-------- +:strong:`systemd.network`\ (5) + + +AUTHORS +------- +Dennis Camera + + +COPYING +------- +Copyright \(C) 2020 Dennis Camera. 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_networkd_network/manifest b/cdist/conf/type/__systemd_networkd_network/manifest new file mode 100755 index 00000000..0879b6ec --- /dev/null +++ b/cdist/conf/type/__systemd_networkd_network/manifest @@ -0,0 +1,121 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +CONFIG_FILE_PATH='/etc/systemd/network' + +networkctl_bin=$(cat "${__object}/explorer/networkctl_bin") + +test -n "${networkctl_bin}" || { + printf 'This system is not supported by this type (%s).' "${__type##*/}" >&2 + printf ' The networkctl tool could not be found.\n' >&2 + exit 1 +} + +{ + # shellcheck disable=SC2034 + read -r state_is + read -r config_is || true +} <"${__object}/explorer/state" + +if test -f "${__object}/parameter/name" +then + name=$(cat "${__object}/parameter/name") +else + name=$__object_id +fi + +priority=$(cat "${__object}/parameter/priority") +state_should=$(cat "${__object}/parameter/state") + +config_file=$(printf '%s/%02u-%s.network' "${CONFIG_FILE_PATH}" "${priority}" "${__object_id}") + +if test -f "${__object:?}/parameter/auto-reload" +then + reload_cmd="${networkctl_bin} reload" +else + reload_cmd= +fi + +gen_conf() { + echo '[Match]' + + if test -s "${__object}/parameter/match" + then + cat "${__object}/parameter/match" + else + # By default match against the interface name + printf 'Name=%s\n' "${name}" + fi + + { + grep -e '^Network\.' "${__object}/parameter/option" + + grep -v -e '^\(Match\|Network\)\.' "${__object}/parameter/option" \ + | sort -t . -k 1 + } | while read -r _option + do + _section=${_option%%.*} + + if test "${_cur_section}" != "${_section}" + then + # new section + printf '\n[%s]\n' "${_section}" + _cur_section=$_section + fi + + echo "${_option#*.}" + done +} + + +if test -n "${config_is}" -a "${config_is}" != "${config_file}" +then + # Check if only the priority has changed! + # We cannot in all cases delete the old config file as it might be a default + # config. + if test "$(dirname "${config_file}")" = "$(dirname "${config_is}")" \ + && test "$(basename "${config_is}" | sed -e 's/^[0-9]*//')" \ + = "$(basename "${config_file}" | sed -e 's/^[0-9]*//')" + then + # Remove old config, but do not reload, yet. + # reload will be done after new config file has been written… + require="__file${config_file}" __file "${config_is}" --state absent + fi +fi + + +case $state_should +in + (present) + __directory "${CONFIG_FILE_PATH}" --state pre-exists + export require=__directory"${CONFIG_FILE_PATH}" + + gen_conf | __file "${config_file}" --state "${state_should}" \ + --owner 0 --mode 0644 --source - \ + --onchange "${reload_cmd}" + ;; + (absent) + __file "${config_file}" --state absent \ + --onchange "${reload_cmd}" + ;; + (*) + printf 'Invalid --state: %s\n' "${state_should}" + ;; +esac diff --git a/cdist/conf/type/__systemd_networkd_network/parameter/boolean b/cdist/conf/type/__systemd_networkd_network/parameter/boolean new file mode 100644 index 00000000..ae36618d --- /dev/null +++ b/cdist/conf/type/__systemd_networkd_network/parameter/boolean @@ -0,0 +1 @@ +auto-reload diff --git a/cdist/conf/type/__systemd_networkd_network/parameter/default/priority b/cdist/conf/type/__systemd_networkd_network/parameter/default/priority new file mode 100644 index 00000000..f599e28b --- /dev/null +++ b/cdist/conf/type/__systemd_networkd_network/parameter/default/priority @@ -0,0 +1 @@ +10 diff --git a/cdist/conf/type/__systemd_networkd_network/parameter/default/state b/cdist/conf/type/__systemd_networkd_network/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__systemd_networkd_network/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__systemd_networkd_network/parameter/optional b/cdist/conf/type/__systemd_networkd_network/parameter/optional new file mode 100644 index 00000000..685217c5 --- /dev/null +++ b/cdist/conf/type/__systemd_networkd_network/parameter/optional @@ -0,0 +1,3 @@ +name +priority +state diff --git a/cdist/conf/type/__systemd_networkd_network/parameter/optional_multiple b/cdist/conf/type/__systemd_networkd_network/parameter/optional_multiple new file mode 100644 index 00000000..ec20610b --- /dev/null +++ b/cdist/conf/type/__systemd_networkd_network/parameter/optional_multiple @@ -0,0 +1,2 @@ +match +option From f62bf3844922ff3c66560819c530d5545262a6dd Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Fri, 26 Jun 2020 18:13:44 +0200 Subject: [PATCH 14/29] [type/__interface] Draft systemd backend --- .../files/backends/systemd/manifest | 97 ++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/cdist/conf/type/__interface/files/backends/systemd/manifest b/cdist/conf/type/__interface/files/backends/systemd/manifest index 79156e40..9d404bcc 100755 --- a/cdist/conf/type/__interface/files/backends/systemd/manifest +++ b/cdist/conf/type/__interface/files/backends/systemd/manifest @@ -19,4 +19,99 @@ # along with cdist. If not, see . # -# TODO +opt_format() { + printf '%s=%s\n' "${1:?'option name missing'}" "${2:?'option value missing'}" +} + +opt_from_param() { + # Only first line will be read. + opt_format \ + "${1:?'option name missing'}" \ + "$(head -n 1 "${__object}/parameter/${2:?'parameter name missing'}")" +} + + +set -- --state "$(cat "${__object}/parameter/state")" + +# Boolean flags +test -f "${__object}/parameter/onboot" || { + echo "WARNING: ${__type##*/}: The systemd backend only supports --onboot." >&2 +} +test -f "${__object}/parameter/hotplug" || { + echo "WARNING: ${__type##*/}: The systemd backend only supports --hotplug." >&2 +} + + +if test -f "${__object}/parameter/name" +then + set -- "$@" --name "$(cat "${__object}/parameter/name")" +fi + + +# Generate appropriate parameters based on bootproto +bootproto=$(cat "${__object}/parameter/bootproto") +case $bootproto +in + (dhcp*) + if test "${bootproto}" = dhcp + then + set -- "$@" --option "$(opt_format Network.DHCP yes)" + # TODO: Implement IPv6 support + # else + # set -- "$@" --option "$(opt_format Network.DHCP "${bootproto}")" + fi + ;; + (static) + set -- "$@" --option 'Network.DHCP=false' + + if test -s "${__object}/parameter/address" + then + while read -r _value + do + set -- "$@" --option "$(opt_format Network.Address "${_value}")" + done <"${__object}/parameter/address" + unset _value + fi + + if test -s "${__object}/parameter/gateway" + then + set -- "$@" --option "$(opt_from_param Network.Gateway gateway)" + fi + ;; + (manual) + set -- "$@" --option 'Network.DHCP=false' + ;; + (*) + exit 1 + ;; +esac + +if test -s "${__object}/parameter/comment" +then + set -- "$@" --option "$(opt_from_param Network.Description comment)" +fi + +case $(cat "${__object}/parameter/onchange") +in + (leave) + ;; + (refresh) + set -- "$@" --auto-reload + ;; + (*) + echo 'The --onchange parameter for type systemd only accepts "leave" or "refresh".' >&2 + echo 'systemd-networkd automatically reconfigures all interfaces.' >&2 + exit 1 +esac + +if test -s "${__object}/parameter/extra-config" +then + while read -r _opt + do + set -- "$@" --option "${_opt}" + done <"${__object}/parameter/extra-config" + unset _opt +fi + +# Instantiate backend type +__systemd_networkd_network "${__object_id}" "$@" From 95b5fcbdc4d27badcbce4623eda77b621351646d Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 29 Jun 2020 11:09:59 +0200 Subject: [PATCH 15/29] [type/__interface_ifcfg] Add type with basic support for RedHat --- cdist/conf/type/__interface_ifcfg/man.rst | 68 +++++++ cdist/conf/type/__interface_ifcfg/manifest | 184 ++++++++++++++++++ .../type/__interface_ifcfg/parameter/boolean | 2 + .../parameter/default/onchange | 1 + .../__interface_ifcfg/parameter/default/state | 1 + .../type/__interface_ifcfg/parameter/optional | 4 + .../type/__interface_ifcfg/parameter/required | 1 + 7 files changed, 261 insertions(+) create mode 100644 cdist/conf/type/__interface_ifcfg/man.rst create mode 100755 cdist/conf/type/__interface_ifcfg/manifest create mode 100644 cdist/conf/type/__interface_ifcfg/parameter/boolean create mode 100644 cdist/conf/type/__interface_ifcfg/parameter/default/onchange create mode 100644 cdist/conf/type/__interface_ifcfg/parameter/default/state create mode 100644 cdist/conf/type/__interface_ifcfg/parameter/optional create mode 100644 cdist/conf/type/__interface_ifcfg/parameter/required diff --git a/cdist/conf/type/__interface_ifcfg/man.rst b/cdist/conf/type/__interface_ifcfg/man.rst new file mode 100644 index 00000000..72b50350 --- /dev/null +++ b/cdist/conf/type/__interface_ifcfg/man.rst @@ -0,0 +1,68 @@ +cdist-type__interface_ifcfg(7) +=============================== + +NAME +---- +cdist-type__interface_ifcfg - Manage network interfaces using ifcfg network +scripts. + + +DESCRIPTION +----------- +This type allows to configure network interfaces using the ifcfg network scripts +on RedHat and SuSE distributions. + + +REQUIRED PARAMETERS +------------------- +bootproto + ... + + +OPTIONAL PARAMETERS +------------------- +address + +comment + If supplied, the value will be inserted at the top of the configuration file + as a comment. +option + ... + Can be used multiple times. + + +BOOLEAN PARAMETERS +------------------ +onboot + +hotplug + + + +EXAMPLES +-------- + +.. code-block:: sh + + # TODO + __interface_ifcfg ... + + +SEE ALSO +-------- +:strong:`cdist-type__interface`\ (7) + + +AUTHORS +------- +Steven Armstrong +Dennis Camera + + +COPYING +------- +Copyright \(C) 2014--2020 Steven Armstrong and Dennis Camera. + +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/__interface_ifcfg/manifest b/cdist/conf/type/__interface_ifcfg/manifest new file mode 100755 index 00000000..c1ebfd55 --- /dev/null +++ b/cdist/conf/type/__interface_ifcfg/manifest @@ -0,0 +1,184 @@ +#!/bin/sh -e +# +# 2014 Steven Armstrong (steven-cdist at armstrong.cc) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +yesno() { test $? -eq 0 && echo yes || echo no; } +opt_format() { + printf '%s="%s"\n' "${1:?'option name missing'}" "${2:?'option value missing'}" +} +prefix2subnet() { + python3 -c 'for addr in __import__("sys").argv[1:]: print(__import__("ipaddress").ip_network(addr, strict=False).netmask)' "$@" +} + +os=$(cat "${__global}/explorer/os") + +case $os +in + (centos|redhat|scientific) + NETWORK_SCRIPTS_DIR='/etc/sysconfig/network-scripts' + ;; + (suse) + NETWORK_SCRIPTS_DIR='/etc/sysconfig/network' + ;; + (*) + printf "Your operating system (%s) is currently not supported by this type (%s)\n" "${os}" "${__type##*/}" >&2 + printf "Please contribute an implementation for it if you can.\n" >&2 + exit 1 + ;; +esac + +if test -s "${__object}/parameter/name" +then + name=$(cat "${__object}/parameter/name") +else + name=$__object_id +fi +state_should=$(cat "${__object}/parameter/state") +bootproto=$(cat "${__object}/parameter/bootproto") +onchange=$(cat "${__object}/parameter/onchange") + +ifcfg_file="${NETWORK_SCRIPTS_DIR:?}/ifcfg-${__object_id}" + + +onchange_action() { + case $onchange + in + (refresh) + printf "ifdown '%s' || true ; ifup '%s'\n" "${name}" "${name}" + ;; + (up) + printf "ifup '%s'\n" "${name}" + ;; + (down) + printf "ifdown '%s' || true\n" "${name}" + ;; + (leave) + # ignore + ;; + (*) + printf 'Invalid --onchange: %s\n' "${onchange}" >&2 + exit 1 + ;; + esac +} + + +{ + cat <<-EOF + # Created by cdist ${__type##*/} + # Do not change. Changes will be overwritten. + # + + EOF + + if test -f "$__object/parameter/comment" + then + awk '{ print "# " $0 }' <"$__object/parameter/comment" + echo + fi + + opt_format DEVICE "${name}" + opt_format NM_CONTROLLED no + + ignored_parameters= + + # manually_handled_parameters are handled in their own code block, not by + # the generic accumulator + manually_handled_parameters='bootproto comment name extra-config state onboot onchange hotplug' + + case $bootproto + in + (dhcp) + opt_format BOOTPROTO dhcp + ignored_parameters='address broadcast gateway' + ;; + (static|manual) + opt_format BOOTPROTO none + ;; + (*) + printf 'Invalid --bootproto: %s\n' "${bootproto}" >&2 + exit 1 + ;; + esac + + _bonding_opts= + + for _param in "${__object}"/parameter/* + do + _key=$(echo "${_param}" | tr '[:lower:]' '[:upper:]' | tr '-' '_') + + echo "${ignored_parameters}" | grep -q -w "${_param}" && continue + echo "${manually_handled_parameters}" | grep -q -w "${_param}" && continue + + case $_param + in + (onboot|hotplug) + # boolean options + opt_format "${_key}" "$(test -f "${__object}/parameter/${_param}" | yesno)" + ;; + (bond-master) + opt_format SLAVE yes + opt_format MASTER "$(cat "${__object}/parameter/${_param}")" + ;; + (bond-*) + _key=$(echo "${_param#bond-}" | tr '-' '_') + _value=$(cat "${__object}/parameter/${_param}") + + if test "${_key}" = 'arp_ip_target' + then + _value=$(echo "${_value}" | awk -v RS= -v FS='\n' -v OFS=',' '$1=$1') + fi + + _bonding_opts="${_bonding_opts} $(opt_format "${_key}" "${_value}")" + ;; + (*) + case $_param + in + (address) + n=0 + while read -r _addr + do + opt_format "IPADDR${n}" "${_addr%%/*}" + opt_format "NETMASK${n}" "$(prefix2subnet "${_addr##*/}")" + : $((n+=1)) + done <"${__object}/parameter/address" + unset n _addr + ;; + (*) + opt_format "${_key}" "$(cat "${__object}/parameter/${_param}")" + ;; + esac + ;; + esac + done + + if test -n "${_bonding_opts}" + then + # strip leading space + opt_format BONDING_OPTS "${_bonding_opts# }" + fi + + if test -f "${__object}/parameter/extra-config" + then + cat "${__object}/parameter/extra-config" + fi +} | __file "${ifcfg_file}" \ + --state "${state_should}" --owner root --group root --mode 0644 \ + --onchange "$(onchange_action)" --source - diff --git a/cdist/conf/type/__interface_ifcfg/parameter/boolean b/cdist/conf/type/__interface_ifcfg/parameter/boolean new file mode 100644 index 00000000..14b5e789 --- /dev/null +++ b/cdist/conf/type/__interface_ifcfg/parameter/boolean @@ -0,0 +1,2 @@ +onboot +hotplug diff --git a/cdist/conf/type/__interface_ifcfg/parameter/default/onchange b/cdist/conf/type/__interface_ifcfg/parameter/default/onchange new file mode 100644 index 00000000..e8f9c907 --- /dev/null +++ b/cdist/conf/type/__interface_ifcfg/parameter/default/onchange @@ -0,0 +1 @@ +leave diff --git a/cdist/conf/type/__interface_ifcfg/parameter/default/state b/cdist/conf/type/__interface_ifcfg/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__interface_ifcfg/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__interface_ifcfg/parameter/optional b/cdist/conf/type/__interface_ifcfg/parameter/optional new file mode 100644 index 00000000..f8e8477d --- /dev/null +++ b/cdist/conf/type/__interface_ifcfg/parameter/optional @@ -0,0 +1,4 @@ +comment +name +onchange +state diff --git a/cdist/conf/type/__interface_ifcfg/parameter/required b/cdist/conf/type/__interface_ifcfg/parameter/required new file mode 100644 index 00000000..507318ee --- /dev/null +++ b/cdist/conf/type/__interface_ifcfg/parameter/required @@ -0,0 +1 @@ +bootproto From 63b5800d9f35777f9b529da5e50705aa28145a5e Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 29 Jun 2020 13:25:41 +0200 Subject: [PATCH 16/29] [type/__interface] Draft ifcfg backend --- .../__interface/files/backends/ifcfg/manifest | 105 ++++++++++++++++++ .../files/backends/redhat/manifest | 22 ---- cdist/conf/type/__interface/manifest | 4 +- 3 files changed, 107 insertions(+), 24 deletions(-) create mode 100755 cdist/conf/type/__interface/files/backends/ifcfg/manifest delete mode 100755 cdist/conf/type/__interface/files/backends/redhat/manifest diff --git a/cdist/conf/type/__interface/files/backends/ifcfg/manifest b/cdist/conf/type/__interface/files/backends/ifcfg/manifest new file mode 100755 index 00000000..9d46b24f --- /dev/null +++ b/cdist/conf/type/__interface/files/backends/ifcfg/manifest @@ -0,0 +1,105 @@ +#!/bin/sh -e +# -*- mode: sh; indent-tabs-mode: t -*- +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +opt_format() { + printf '%s="%s"\n' "${1:?'option name missing'}" "${2:?'option value missing'}" +} + +opt_from_param() { + # Only first line will be read. + opt_format \ + "${1:?'option name missing'}" \ + "$(head -n 1 "${__object}/parameter/${2:?'parameter name missing'}")" +} + + +set -- --state "$(cat "${__object}/parameter/state")" --family inet + +# Boolean flags +if test -f "${__object}/parameter/onboot" +then + set -- "$@" --onboot +fi +if test -f "${__object}/parameter/hotplug" +then + set -- "$@" --hotplug +fi + + +if test -f "${__object}/parameter/name" +then + set -- "$@" --name "$(cat "${__object}/parameter/name")" +fi + + +# Generate appropriate parameters based on bootproto +bootproto=$(cat "${__object}/parameter/bootproto") +case $bootproto +in + (dhcp) + set -- "$@" --bootproto dhcp + ;; + (static) + set -- "$@" --bootproto static + + if test -s "${__object}/parameter/address" + then + while read -r _addr + do + set -- "$@" --address "${_addr}" + done <"${__object}/parameter/address" + unset _addr + fi + + if test -s "${__object}/parameter/gateway" + then + set -- "$@" --option "$(opt_from_param GATEWAY gateway)" + fi + ;; + (manual) + set -- "$@" --bootproto none + ;; + (*) + exit 1 + ;; +esac + +if test -s "${__object}/parameter/comment" +then + set -- "$@" --comment "$(cat "${__object}/parameter/comment")" +fi + +if test -s "${__object}/parameter/onchange" +then + set -- "$@" --onchange "$(cat "${__object}/parameter/onchange")" +fi + +if test -s "${__object}/parameter/extra-config" +then + while read -r _opt + do + set -- "$@" --option "${_opt}" + done <"${__object}/parameter/extra-config" + unset _opt +fi + +# Instantiate backend type +__interface_ifcfg "${__object_id}" "$@" diff --git a/cdist/conf/type/__interface/files/backends/redhat/manifest b/cdist/conf/type/__interface/files/backends/redhat/manifest deleted file mode 100755 index 79156e40..00000000 --- a/cdist/conf/type/__interface/files/backends/redhat/manifest +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -e -# -*- mode: sh; indent-tabs-mode: t -*- -# -# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) -# -# This file is part of cdist. -# -# cdist is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# cdist is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with cdist. If not, see . -# - -# TODO diff --git a/cdist/conf/type/__interface/manifest b/cdist/conf/type/__interface/manifest index 661674cc..6cf71bb3 100755 --- a/cdist/conf/type/__interface/manifest +++ b/cdist/conf/type/__interface/manifest @@ -69,8 +69,8 @@ else (devuan) impl_type=ifupdown.d ;; - (centos|redhat) - impl_type=redhat + (centos|redhat|scientific|suse) + impl_type=ifcfg ;; (openwrt) impl_type=uci From bd5e07b353d41eec17759264bea7c0de738c2cd0 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 29 Jun 2020 13:25:52 +0200 Subject: [PATCH 17/29] [type/__interface_ifcfg] Draft SuSE support --- cdist/conf/type/__interface_ifcfg/manifest | 88 ++++++++++++++++++---- 1 file changed, 75 insertions(+), 13 deletions(-) diff --git a/cdist/conf/type/__interface_ifcfg/manifest b/cdist/conf/type/__interface_ifcfg/manifest index c1ebfd55..4abff076 100755 --- a/cdist/conf/type/__interface_ifcfg/manifest +++ b/cdist/conf/type/__interface_ifcfg/manifest @@ -26,6 +26,12 @@ opt_format() { prefix2subnet() { python3 -c 'for addr in __import__("sys").argv[1:]: print(__import__("ipaddress").ip_network(addr, strict=False).netmask)' "$@" } +param2var() { + echo "${1:?'param name missing'}" | tr '[:lower:]' '[:upper:]' | tr '-' '_' +} +ipversion() { + python3 -c 'for addr in __import__("sys").argv[1:]: print(__import__("ipaddress").ip_address(addr).version)' "$@" +} os=$(cat "${__global}/explorer/os") @@ -33,9 +39,11 @@ case $os in (centos|redhat|scientific) NETWORK_SCRIPTS_DIR='/etc/sysconfig/network-scripts' + systype=redhat ;; (suse) NETWORK_SCRIPTS_DIR='/etc/sysconfig/network' + systype=suse ;; (*) printf "Your operating system (%s) is currently not supported by this type (%s)\n" "${os}" "${__type##*/}" >&2 @@ -97,11 +105,37 @@ onchange_action() { opt_format DEVICE "${name}" opt_format NM_CONTROLLED no + case $systype + in + (redhat) + for _param in onboot hotplug + do + _key=$(param2var "${_param}") + opt_format "${_key}" "$(test -f "${__object}/parameter/${_param}" | yesno)" + done + unset _param _key + ;; + (suse) + _startmode=manual + + if test -f "${__object}/parameter/onboot" + then + _startmode=auto + fi + if test -f "${__object}/parameter/hotplug" + then + _startmode=ifplugd + fi + + opt_format STARTMODE "${_startmode}" + ;; + esac + ignored_parameters= # manually_handled_parameters are handled in their own code block, not by # the generic accumulator - manually_handled_parameters='bootproto comment name extra-config state onboot onchange hotplug' + manually_handled_parameters='bootproto comment extra-config hotplug name onboot onchange state' case $bootproto in @@ -109,7 +143,7 @@ onchange_action() { opt_format BOOTPROTO dhcp ignored_parameters='address broadcast gateway' ;; - (static|manual) + (static|none) opt_format BOOTPROTO none ;; (*) @@ -122,17 +156,13 @@ onchange_action() { for _param in "${__object}"/parameter/* do - _key=$(echo "${_param}" | tr '[:lower:]' '[:upper:]' | tr '-' '_') + _key=$(param2var "${_param}") echo "${ignored_parameters}" | grep -q -w "${_param}" && continue echo "${manually_handled_parameters}" | grep -q -w "${_param}" && continue case $_param in - (onboot|hotplug) - # boolean options - opt_format "${_key}" "$(test -f "${__object}/parameter/${_param}" | yesno)" - ;; (bond-master) opt_format SLAVE yes opt_format MASTER "$(cat "${__object}/parameter/${_param}")" @@ -153,12 +183,44 @@ onchange_action() { in (address) n=0 - while read -r _addr - do - opt_format "IPADDR${n}" "${_addr%%/*}" - opt_format "NETMASK${n}" "$(prefix2subnet "${_addr##*/}")" - : $((n+=1)) - done <"${__object}/parameter/address" + case $systype + in + (redhat) + # the fucked-up config + while read -r _addr + do + if test "$(ipversion "${_addr}")" -eq 6 + then + if ! ${_ipv6_enabled:-false} + then + opt_format IPV6INIT yes + opt_format IPV6ADDR "${_addr}" + _ipv6_enabled=true + else + _ipv6_sec="${_ipv6_sec} ${_addr}" + fi + else + opt_format "IPADDR${n}" "${_addr%%/*}" + opt_format "NETMASK${n}" "$(prefix2subnet "${_addr##*/}")" + : $((n+=1)) + fi + done + + if test -n "${_ipv6_sec}" + then + opt_format IPV6ADDR_SECONDARIES "${_ipv6_sec# }" + fi + unset _ipv6_enabled _ipv6_sec + ;; + (suse) + # the sane config + while read -r _addr + do + opt_format "IPADDR${n}" "${_addr}" + : $((n+=1)) + done + ;; + esac <"${__object}/parameter/address" unset n _addr ;; (*) From 3f3680db3a3659c6689f63c6f544e43c3199e2b2 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 26 Aug 2020 15:41:46 +0200 Subject: [PATCH 18/29] [type/__interface] Fix ifupdown.d backend when stdin is empty --- .../type/__interface/files/backends/ifupdown.d/manifest | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest b/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest index ac596746..7a9b328b 100755 --- a/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest +++ b/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest @@ -102,4 +102,8 @@ then fi # Instantiate backend type -__interface_ifupdown.d "${__object_id}" "$@" <"${__object}/stdin" +if test -s "${__object:?}/stdin" +then + exec <"${__object:?}/stdin" +fi +__interface_ifupdown.d "${__object_id}" "$@" From ed5954744852015ad17e20b59e852d672acbd00d Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 26 Aug 2020 15:52:13 +0200 Subject: [PATCH 19/29] [type/__interface] Error if expected environment variables are unset --- .../__interface/files/backends/ifcfg/manifest | 34 +++++++-------- .../files/backends/ifupdown.d/manifest | 34 +++++++-------- .../files/backends/systemd/manifest | 30 ++++++------- .../__interface/files/backends/uci/manifest | 42 +++++++++---------- cdist/conf/type/__interface/manifest | 20 ++++----- 5 files changed, 80 insertions(+), 80 deletions(-) diff --git a/cdist/conf/type/__interface/files/backends/ifcfg/manifest b/cdist/conf/type/__interface/files/backends/ifcfg/manifest index 9d46b24f..a4b6dbdf 100755 --- a/cdist/conf/type/__interface/files/backends/ifcfg/manifest +++ b/cdist/conf/type/__interface/files/backends/ifcfg/manifest @@ -27,31 +27,31 @@ opt_from_param() { # Only first line will be read. opt_format \ "${1:?'option name missing'}" \ - "$(head -n 1 "${__object}/parameter/${2:?'parameter name missing'}")" + "$(head -n 1 "${__object:?}/parameter/${2:?'parameter name missing'}")" } -set -- --state "$(cat "${__object}/parameter/state")" --family inet +set -- --state "$(cat "${__object:?}/parameter/state")" --family inet # Boolean flags -if test -f "${__object}/parameter/onboot" +if test -f "${__object:?}/parameter/onboot" then set -- "$@" --onboot fi -if test -f "${__object}/parameter/hotplug" +if test -f "${__object:?}/parameter/hotplug" then set -- "$@" --hotplug fi -if test -f "${__object}/parameter/name" +if test -f "${__object:?}/parameter/name" then - set -- "$@" --name "$(cat "${__object}/parameter/name")" + set -- "$@" --name "$(cat "${__object:?}/parameter/name")" fi # Generate appropriate parameters based on bootproto -bootproto=$(cat "${__object}/parameter/bootproto") +bootproto=$(cat "${__object:?}/parameter/bootproto") case $bootproto in (dhcp) @@ -60,16 +60,16 @@ in (static) set -- "$@" --bootproto static - if test -s "${__object}/parameter/address" + if test -s "${__object:?}/parameter/address" then while read -r _addr do set -- "$@" --address "${_addr}" - done <"${__object}/parameter/address" + done <"${__object:?}/parameter/address" unset _addr fi - if test -s "${__object}/parameter/gateway" + if test -s "${__object:?}/parameter/gateway" then set -- "$@" --option "$(opt_from_param GATEWAY gateway)" fi @@ -82,24 +82,24 @@ in ;; esac -if test -s "${__object}/parameter/comment" +if test -s "${__object:?}/parameter/comment" then - set -- "$@" --comment "$(cat "${__object}/parameter/comment")" + set -- "$@" --comment "$(cat "${__object:?}/parameter/comment")" fi -if test -s "${__object}/parameter/onchange" +if test -s "${__object:?}/parameter/onchange" then - set -- "$@" --onchange "$(cat "${__object}/parameter/onchange")" + set -- "$@" --onchange "$(cat "${__object:?}/parameter/onchange")" fi -if test -s "${__object}/parameter/extra-config" +if test -s "${__object:?}/parameter/extra-config" then while read -r _opt do set -- "$@" --option "${_opt}" - done <"${__object}/parameter/extra-config" + done <"${__object:?}/parameter/extra-config" unset _opt fi # Instantiate backend type -__interface_ifcfg "${__object_id}" "$@" +__interface_ifcfg "${__object_id:?}" "$@" diff --git a/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest b/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest index 7a9b328b..bbdca8bb 100755 --- a/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest +++ b/cdist/conf/type/__interface/files/backends/ifupdown.d/manifest @@ -27,31 +27,31 @@ opt_from_param() { # Only first line will be read. opt_format \ "${1:?'option name missing'}" \ - "$(head -n 1 "${__object}/parameter/${2:?'parameter name missing'}")" + "$(head -n 1 "${__object:?}/parameter/${2:?'parameter name missing'}")" } -set -- --state "$(cat "${__object}/parameter/state")" --family inet +set -- --state "$(cat "${__object:?}/parameter/state")" --family inet # Boolean flags -if test -f "${__object}/parameter/onboot" +if test -f "${__object:?}/parameter/onboot" then set -- "$@" --auto fi -if test -f "${__object}/parameter/hotplug" +if test -f "${__object:?}/parameter/hotplug" then set -- "$@" --hotplug fi -if test -f "${__object}/parameter/name" +if test -f "${__object:?}/parameter/name" then - set -- "$@" --name "$(cat "${__object}/parameter/name")" + set -- "$@" --name "$(cat "${__object:?}/parameter/name")" fi # Generate appropriate parameters based on bootproto -bootproto=$(cat "${__object}/parameter/bootproto") +bootproto=$(cat "${__object:?}/parameter/bootproto") case $bootproto in (dhcp) @@ -60,16 +60,16 @@ in (static) set -- "$@" --method static - if test -s "${__object}/parameter/address" + if test -s "${__object:?}/parameter/address" then while read -r _value do set -- "$@" --option "$(opt_format address "${_value}")" - done <"${__object}/parameter/address" + done <"${__object:?}/parameter/address" unset _value fi - if test -s "${__object}/parameter/gateway" + if test -s "${__object:?}/parameter/gateway" then set -- "$@" --option "$(opt_from_param gateway gateway)" fi @@ -82,22 +82,22 @@ in ;; esac -if test -s "${__object}/parameter/comment" +if test -s "${__object:?}/parameter/comment" then - set -- "$@" --comment "$(cat "${__object}/parameter/comment")" + set -- "$@" --comment "$(cat "${__object:?}/parameter/comment")" fi -if test -s "${__object}/parameter/onchange" +if test -s "${__object:?}/parameter/onchange" then - set -- "$@" --onchange "$(cat "${__object}/parameter/onchange")" + set -- "$@" --onchange "$(cat "${__object:?}/parameter/onchange")" fi -if test -s "${__object}/parameter/extra-config" +if test -s "${__object:?}/parameter/extra-config" then while read -r _opt do set -- "$@" --option "${_opt}" - done <"${__object}/parameter/extra-config" + done <"${__object:?}/parameter/extra-config" unset _opt fi @@ -106,4 +106,4 @@ if test -s "${__object:?}/stdin" then exec <"${__object:?}/stdin" fi -__interface_ifupdown.d "${__object_id}" "$@" +__interface_ifupdown.d "${__object_id:?}" "$@" diff --git a/cdist/conf/type/__interface/files/backends/systemd/manifest b/cdist/conf/type/__interface/files/backends/systemd/manifest index 9d404bcc..2e86ee4e 100755 --- a/cdist/conf/type/__interface/files/backends/systemd/manifest +++ b/cdist/conf/type/__interface/files/backends/systemd/manifest @@ -27,29 +27,29 @@ opt_from_param() { # Only first line will be read. opt_format \ "${1:?'option name missing'}" \ - "$(head -n 1 "${__object}/parameter/${2:?'parameter name missing'}")" + "$(head -n 1 "${__object:?}/parameter/${2:?'parameter name missing'}")" } -set -- --state "$(cat "${__object}/parameter/state")" +set -- --state "$(cat "${__object:?}/parameter/state")" # Boolean flags -test -f "${__object}/parameter/onboot" || { +test -f "${__object:?}/parameter/onboot" || { echo "WARNING: ${__type##*/}: The systemd backend only supports --onboot." >&2 } -test -f "${__object}/parameter/hotplug" || { +test -f "${__object:?}/parameter/hotplug" || { echo "WARNING: ${__type##*/}: The systemd backend only supports --hotplug." >&2 } -if test -f "${__object}/parameter/name" +if test -f "${__object:?}/parameter/name" then - set -- "$@" --name "$(cat "${__object}/parameter/name")" + set -- "$@" --name "$(cat "${__object:?}/parameter/name")" fi # Generate appropriate parameters based on bootproto -bootproto=$(cat "${__object}/parameter/bootproto") +bootproto=$(cat "${__object:?}/parameter/bootproto") case $bootproto in (dhcp*) @@ -64,16 +64,16 @@ in (static) set -- "$@" --option 'Network.DHCP=false' - if test -s "${__object}/parameter/address" + if test -s "${__object:?}/parameter/address" then while read -r _value do set -- "$@" --option "$(opt_format Network.Address "${_value}")" - done <"${__object}/parameter/address" + done <"${__object:?}/parameter/address" unset _value fi - if test -s "${__object}/parameter/gateway" + if test -s "${__object:?}/parameter/gateway" then set -- "$@" --option "$(opt_from_param Network.Gateway gateway)" fi @@ -86,12 +86,12 @@ in ;; esac -if test -s "${__object}/parameter/comment" +if test -s "${__object:?}/parameter/comment" then set -- "$@" --option "$(opt_from_param Network.Description comment)" fi -case $(cat "${__object}/parameter/onchange") +case $(cat "${__object:?}/parameter/onchange") in (leave) ;; @@ -104,14 +104,14 @@ in exit 1 esac -if test -s "${__object}/parameter/extra-config" +if test -s "${__object:?}/parameter/extra-config" then while read -r _opt do set -- "$@" --option "${_opt}" - done <"${__object}/parameter/extra-config" + done <"${__object:?}/parameter/extra-config" unset _opt fi # Instantiate backend type -__systemd_networkd_network "${__object_id}" "$@" +__systemd_networkd_network "${__object_id:?}" "$@" diff --git a/cdist/conf/type/__interface/files/backends/uci/manifest b/cdist/conf/type/__interface/files/backends/uci/manifest index 8c812638..21c1bd7e 100755 --- a/cdist/conf/type/__interface/files/backends/uci/manifest +++ b/cdist/conf/type/__interface/files/backends/uci/manifest @@ -27,27 +27,27 @@ opt_from_param() { # Only first line will be read. opt_format \ "${1:?'option name missing'}" \ - "$(head -n 1 "${__object}/parameter/${2:?'parameter name missing'}")" + "$(head -n 1 "${__object:?}/parameter/${2:?'parameter name missing'}")" } -onchange_action=$(cat "${__object}/parameter/onchange") -state=$(cat "${__object}/parameter/state") +onchange_action=$(cat "${__object:?}/parameter/onchange") +state=$(cat "${__object:?}/parameter/state") -obj_name="network.${__object_id}" +obj_name="network.${__object_id:?}" onchange_action() { case $onchange_action in (refresh) - printf "ifup '%s'\n" "${__object_id}" + printf "ifup '%s'\n" "${__object_id:?}" ;; (up) # shellcheck disable=SC2016 echo 'isifup()(up=0; . /usr/share/libubox/jshn.sh && json_load "$(ifstatus "$1")" && json_get_var up up; return $((!up)))' - printf "isifup '%s' || ifup '%s'\n" "${__object_id}" "${__object_id}" + printf "isifup '%s' || ifup '%s'\n" "${__object_id:?}" "${__object_id:?}" ;; (down) - printf "ifdown '%s'\n" "${__object_id}" + printf "ifdown '%s'\n" "${__object_id:?}" ;; (leave) # ignore @@ -62,25 +62,25 @@ onchange_action() { set -- --state "${state}" --transaction "${obj_name}" -if test -s "${__object}/parameter/comment" +if test -s "${__object:?}/parameter/comment" then set -- "$@" --option "$(opt_from_param _comment comment)" fi -if test -f "${__object}/parameter/name" +if test -f "${__object:?}/parameter/name" then set -- "$@" --option "$(opt_from_param ifname name)" else - set -- "$@" --option "$(opt_format ifname "${__object_id}")" + set -- "$@" --option "$(opt_format ifname "${__object_id:?}")" fi set -- "$@" --option "$(opt_format auto "$( - ! test -f "${__object}/parameter/onboot"; echo $?)")" + ! test -f "${__object:?}/parameter/onboot"; echo $?)")" set -- "$@" --option "$(opt_format force_link "$( - test -f "${__object}/parameter/hotplug"; echo $?)")" + test -f "${__object:?}/parameter/hotplug"; echo $?)")" # Generate appropriate parameters based on bootproto -bootproto=$(cat "${__object}/parameter/bootproto") +bootproto=$(cat "${__object:?}/parameter/bootproto") case $bootproto in (dhcp) @@ -89,16 +89,16 @@ in (static) set -- "$@" --option "$(opt_format proto static)" - if test -s "${__object}/parameter/address" + if test -s "${__object:?}/parameter/address" then while read -r _value do set -- "$@" --option "$(opt_format ipaddr "${_value}")" - done <"${__object}/parameter/address" + done <"${__object:?}/parameter/address" unset _value fi - if test -s "${__object}/parameter/gateway" + if test -s "${__object:?}/parameter/gateway" then set -- "$@" --option "$(opt_from_param gateway gateway)" fi @@ -111,22 +111,22 @@ in ;; esac -if test -s "${__object}/parameter/extra-config" +if test -s "${__object:?}/parameter/extra-config" then while read -r _opt do set -- "$@" --option "${_opt}" - done <"${__object}/parameter/extra-config" + done <"${__object:?}/parameter/extra-config" unset _opt fi # Instantiate backend type __uci_section "${obj_name}" --type network.interface "$@" -if test -s "${__object}/parameter/onchange" +if test -s "${__object:?}/parameter/onchange" then require=__uci_commit/"${obj_name}" \ - __check_messages "interface_${__object_id}_onchange" \ - --pattern "^__uci_commit/network.${__object_id}:" \ + __check_messages "interface_${__object_id:?}_onchange" \ + --pattern "^__uci_commit/network.${__object_id:?}:" \ --execute "$(onchange_action)" fi diff --git a/cdist/conf/type/__interface/manifest b/cdist/conf/type/__interface/manifest index 6cf71bb3..73727a2a 100755 --- a/cdist/conf/type/__interface/manifest +++ b/cdist/conf/type/__interface/manifest @@ -28,17 +28,17 @@ invalid_param() { die "$@"; } invalid_paramf() { dief "$@"; } -os=$(cat "${__global}/explorer/os") +os=$(cat "${__global:?}/explorer/os") # Check parameters -bootproto=$(cat "${__object}/parameter/bootproto") +bootproto=$(cat "${__object:?}/parameter/bootproto") case $bootproto in (dhcp) # Check parameters - ! test -f "${__object}/parameter/address" \ + ! test -f "${__object:?}/parameter/address" \ || invalid_param '--address is invalid for --bootproto dhcp' - ! test -f "${__object}/parameter/gateway" \ + ! test -f "${__object:?}/parameter/gateway" \ || invalid_param '--gateway is invalid for --bootproto dhcp' ;; (static) @@ -52,15 +52,15 @@ in ;; esac -if test -f "${__object}/parameter/type" +if test -f "${__object:?}/parameter/type" then - impl_type=$(cat "${__object}/parameter/type") + impl_type=$(cat "${__object:?}/parameter/type") else # Guess the type based on the operating system case $os in (debian) - os_major=$(grep -o '^[0-9][0-9]*' "${__global}/explorer/os_version") + os_major=$(grep -o '^[0-9][0-9]*' "${__global:?}/explorer/os_version") test "${os_major}" -ge 7 \ || die 'Debian versions older than 7 (wheezy) are not supported' @@ -76,18 +76,18 @@ else impl_type=uci ;; (*) - if test -s "${__object}/explorer/has_networkctl" + if test -s "${__object:?}/explorer/has_networkctl" then impl_type=systemd else - die "Don't know how to manage interfaces on: ${os}" + dief "Don't know how to manage interfaces on: %s\n" "${os}" fi ;; esac fi # Hand over to backend-specific implementation -manifest_file="${__type}/files/backends/${impl_type}/manifest" +manifest_file="${__type:?}/files/backends/${impl_type}/manifest" test -x "${manifest_file}" || dief 'Unknown type: %s\n' "${impl_type}" # Run backend-specific script From e283ab0d0364a086f11d1ee524a54de9ec76c689 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 31 Aug 2020 14:55:07 +0200 Subject: [PATCH 20/29] [type/__interface] Fix sphinx errors --- cdist/conf/type/__interface/man.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cdist/conf/type/__interface/man.rst b/cdist/conf/type/__interface/man.rst index 7784047f..de71c438 100644 --- a/cdist/conf/type/__interface/man.rst +++ b/cdist/conf/type/__interface/man.rst @@ -42,15 +42,17 @@ name Defaults to ``__object_id``. onchange The action to perform if the interface configuration has changed. + Available options are: + leave (default) - Do nothing. + Do nothing. up - Bring the interface up if it is down. + Bring the interface up if it is down. down - Bring the interface down if it is up. + Bring the interface down if it is up. refresh - Refresh the interface (down && up). + Refresh the interface (down && up). state ``present`` or ``absent``, defaults to ``present``. type From 2a7a06cbb7c7067b1392fd9dc469e789d148aeac Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Thu, 27 Aug 2020 17:47:39 +0200 Subject: [PATCH 21/29] [type/__bridge] Add type template --- cdist/conf/type/__bridge/gencode-remote | 20 ++++ cdist/conf/type/__bridge/man.rst | 106 ++++++++++++++++++ cdist/conf/type/__bridge/manifest | 41 +++++++ cdist/conf/type/__bridge/parameter/boolean | 3 + .../type/__bridge/parameter/default/bootproto | 1 + .../type/__bridge/parameter/default/onchange | 1 + .../type/__bridge/parameter/default/state | 1 + cdist/conf/type/__bridge/parameter/optional | 7 ++ .../type/__bridge/parameter/optional_multiple | 2 + .../type/__bridge/parameter/required_multiple | 1 + 10 files changed, 183 insertions(+) create mode 100755 cdist/conf/type/__bridge/gencode-remote create mode 100644 cdist/conf/type/__bridge/man.rst create mode 100755 cdist/conf/type/__bridge/manifest create mode 100644 cdist/conf/type/__bridge/parameter/boolean create mode 100644 cdist/conf/type/__bridge/parameter/default/bootproto create mode 100644 cdist/conf/type/__bridge/parameter/default/onchange create mode 100644 cdist/conf/type/__bridge/parameter/default/state create mode 100644 cdist/conf/type/__bridge/parameter/optional create mode 100644 cdist/conf/type/__bridge/parameter/optional_multiple create mode 100644 cdist/conf/type/__bridge/parameter/required_multiple diff --git a/cdist/conf/type/__bridge/gencode-remote b/cdist/conf/type/__bridge/gencode-remote new file mode 100755 index 00000000..77ad9d25 --- /dev/null +++ b/cdist/conf/type/__bridge/gencode-remote @@ -0,0 +1,20 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera@ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + diff --git a/cdist/conf/type/__bridge/man.rst b/cdist/conf/type/__bridge/man.rst new file mode 100644 index 00000000..130aa9d4 --- /dev/null +++ b/cdist/conf/type/__bridge/man.rst @@ -0,0 +1,106 @@ +cdist-type__bridge(7) +===================== + +NAME +---- +cdist-type__bridge - Manage network bridges + + +DESCRIPTION +----------- +This cdist type allows you to manage virtual Ethernet bridges on the target. +It acts as a wrapper around cdist-type__interface(7) to provide more convenient +access to bridge-specific parameters. +Only TCP/IP is supported. For other protocol stacks, use the specific types for +your OS. + + +REQUIRED PARAMETERS +------------------- +port + A port (interface) to be part of the bridge. + This parameter can be used multiple times, to add more than one port to the + bridge. + The ports should not be defined as __interfaces. + + +OPTIONAL PARAMETERS +------------------- +address + The IP address (in CIDR notation) to assign to the network interface. + Can be repeated to assign multiple IP addresses. +bootproto + The boot protocol to use. + + Acceptable values are ``dhcp``, ``static``, ``manual``. + Defaults to ``manual``. +comment + A comment to be stored in the configuration file. +extra-config + Other options to be passed to the implementation type verbatim. + Using this option makes the configuration non-portable to other backends. + If this option is used extensively, it is recommended to use the respective + backend type directly. +gateway + The default gateway to assign to this interface (optional). +name + The name of the physical or logical network device to configure. + Defaults to ``__object_id``. +onchange + The action to perform if the interface configuration has changed. + + Available options are: + + leave (default) + Do nothing. + up + Bring the interface up if it is down. + down + Bring the interface down if it is up. + refresh + Refresh the interface (down && up). +state + ``present`` or ``absent``, defaults to ``present``. +type + The backend to use to store the interface configuration. + Default is to auto detect. + + +BOOLEAN PARAMETERS +------------------ +onboot + Bring the interface up on boot. + Otherwise, it has to be manually brought up using OS utilities + (e.g. ifup\ (8)). +hotplug + | Allow hotplugging the ports on this bridge. + | N.B.: Some backends might not support this. +stp + Enable the Spanning Tree Protocol (STP) on this bridge. + + +EXAMPLES +-------- + +.. code-block:: sh + + # Create a bridge br0 comprised of eth0 and eth1 that is brought up on boot. + __bridge br0 --onboot --port eth0 --port eth1 + + +SEE ALSO +-------- +:strong:`cdist-type__interface`\ (7) + + +AUTHORS +------- +Dennis Camera + + +COPYING +------- +Copyright \(C) 2020 Dennis Camera. 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/__bridge/manifest b/cdist/conf/type/__bridge/manifest new file mode 100755 index 00000000..4d5fda84 --- /dev/null +++ b/cdist/conf/type/__bridge/manifest @@ -0,0 +1,41 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera@ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + + +os=$(cat "${__global:?}/explorer/os") + +case $os +in + (*) + printf "Your operating system (%s) is currently not supported by this type (%s)\n" "${os}" "${__type##*/}" >&2 + printf "Please contribute an implementation for it if you can.\n" >&2 + exit 1 + ;; +esac + +# Hand over to backend-specific implementation +manifest_file="${__type:?}/files/backends/${impl_type}/manifest" +test -x "${manifest_file}" || { + printf 'Unknown type: %s\n' "${impl_type}" >&2 + exit 1 +} + +# Run backend-specific script +exec "${manifest_file}" diff --git a/cdist/conf/type/__bridge/parameter/boolean b/cdist/conf/type/__bridge/parameter/boolean new file mode 100644 index 00000000..0d323712 --- /dev/null +++ b/cdist/conf/type/__bridge/parameter/boolean @@ -0,0 +1,3 @@ +hotplug +onboot +stp diff --git a/cdist/conf/type/__bridge/parameter/default/bootproto b/cdist/conf/type/__bridge/parameter/default/bootproto new file mode 100644 index 00000000..2905494b --- /dev/null +++ b/cdist/conf/type/__bridge/parameter/default/bootproto @@ -0,0 +1 @@ +manual diff --git a/cdist/conf/type/__bridge/parameter/default/onchange b/cdist/conf/type/__bridge/parameter/default/onchange new file mode 100644 index 00000000..e8f9c907 --- /dev/null +++ b/cdist/conf/type/__bridge/parameter/default/onchange @@ -0,0 +1 @@ +leave diff --git a/cdist/conf/type/__bridge/parameter/default/state b/cdist/conf/type/__bridge/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__bridge/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__bridge/parameter/optional b/cdist/conf/type/__bridge/parameter/optional new file mode 100644 index 00000000..16ae6fba --- /dev/null +++ b/cdist/conf/type/__bridge/parameter/optional @@ -0,0 +1,7 @@ +bootproto +comment +gateway +name +onchange +state +type diff --git a/cdist/conf/type/__bridge/parameter/optional_multiple b/cdist/conf/type/__bridge/parameter/optional_multiple new file mode 100644 index 00000000..5bb11f03 --- /dev/null +++ b/cdist/conf/type/__bridge/parameter/optional_multiple @@ -0,0 +1,2 @@ +address +extra-config diff --git a/cdist/conf/type/__bridge/parameter/required_multiple b/cdist/conf/type/__bridge/parameter/required_multiple new file mode 100644 index 00000000..20e6f145 --- /dev/null +++ b/cdist/conf/type/__bridge/parameter/required_multiple @@ -0,0 +1 @@ +port From 718a068d105b2eca9a8168fcfaf4237dfcdcbbe4 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 31 Aug 2020 13:25:49 +0200 Subject: [PATCH 22/29] [type/__bridge] Implement ifupdown.d backend --- .../files/backends/ifupdown.d/manifest | 95 +++++++++++++++++++ cdist/conf/type/__bridge/manifest | 10 ++ 2 files changed, 105 insertions(+) create mode 100755 cdist/conf/type/__bridge/files/backends/ifupdown.d/manifest diff --git a/cdist/conf/type/__bridge/files/backends/ifupdown.d/manifest b/cdist/conf/type/__bridge/files/backends/ifupdown.d/manifest new file mode 100755 index 00000000..0528bb1b --- /dev/null +++ b/cdist/conf/type/__bridge/files/backends/ifupdown.d/manifest @@ -0,0 +1,95 @@ +#!/bin/sh -e +# -*- mode: sh; indent-tabs-mode: t -*- +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +__package_apt bridge-utils +export require=__package_apt/bridge-utils + +bridge_stp='off' +enable_hotplug=no + +cd "${__object:?}/parameter" +for param in * +do + case $param + in + (bootproto) + bootproto=$(cat "${__object:?}/parameter/bootproto") + set -- "$@" --bootproto "${bootproto}" + + case $bootproto + in + (manual) + # if set to manual, there is nothing to wait for… + set -- "$@" --extra-config 'bridge_maxwait 0' + ;; + esac + ;; + (hotplug) + # N.B.: This option must be equal for all configured bridges, + # or cdist will error. + # This is a limitation of the bridge-utils package. + enable_hotplug=yes + ;; + (port) + while read -r _port + do + test -z "$(echo "${_port}" | tr -d 'A-Za-z0-9')" || { + printf 'Invalid bridge port name: %s\n' "${_port}" >&2 + exit 1 + } + + bridge_ports="${bridge_ports-} ${_port}" + done <"${__object:?}/parameter/port" + unset _port + + set -- "$@" --extra-config "bridge_ports${bridge_ports}" + unset bridge_ports + ;; + (stp) + bridge_stp='on' + ;; + (onboot) + # boolean parameters + set -- "$@" --"${param}" + ;; + (*) + set -- "$@" --"${param}" "$(cat "${__object:?}/parameter/${param}")" + ;; + esac +done + + +# Set boolean options +set -- "$@" --extra-config "bridge_stp ${bridge_stp}" +test "${bridge_stp}" = 'on' || set -- "$@" --extra-config 'bridge_fd 0' + +__key_value /etc/default/bridge-utils:BRIDGE_HOTPLUG --state present \ + --file /etc/default/bridge-utils --key BRIDGE_HOTPLUG \ + --delimiter = --exact_delimiter \ + --value "${enable_hotplug}" + + +# Instantiate backend type +if test -s "${__object:?}/stdin" +then + exec <"${__object:?}/stdin" +fi +__interface "${__object_id:?}" --type ifupdown.d "$@" diff --git a/cdist/conf/type/__bridge/manifest b/cdist/conf/type/__bridge/manifest index 4d5fda84..1b9ae14b 100755 --- a/cdist/conf/type/__bridge/manifest +++ b/cdist/conf/type/__bridge/manifest @@ -23,6 +23,16 @@ os=$(cat "${__global:?}/explorer/os") case $os in + (debian) + os_major=$(grep -o '^[0-9][0-9]*' "${__global:?}/explorer/os_version") + test "${os_major}" -ge 7 \ + || die 'Debian versions older than 7 (wheezy) are not supported' + + impl_type=ifupdown.d + ;; + (devuan) + impl_type=ifupdown.d + ;; (*) printf "Your operating system (%s) is currently not supported by this type (%s)\n" "${os}" "${__type##*/}" >&2 printf "Please contribute an implementation for it if you can.\n" >&2 From 34d62aed955ba0485f1de89be96c455e4560027b Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 31 Aug 2020 14:16:07 +0200 Subject: [PATCH 23/29] [type/__interface_ifcfg] Error if expected environment variables are not set --- cdist/conf/type/__interface_ifcfg/manifest | 40 +++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/cdist/conf/type/__interface_ifcfg/manifest b/cdist/conf/type/__interface_ifcfg/manifest index 4abff076..62b0a9bb 100755 --- a/cdist/conf/type/__interface_ifcfg/manifest +++ b/cdist/conf/type/__interface_ifcfg/manifest @@ -27,13 +27,13 @@ prefix2subnet() { python3 -c 'for addr in __import__("sys").argv[1:]: print(__import__("ipaddress").ip_network(addr, strict=False).netmask)' "$@" } param2var() { - echo "${1:?'param name missing'}" | tr '[:lower:]' '[:upper:]' | tr '-' '_' + echo "${1:?'param name missing'}" | tr '[:lower:]-' '[:upper:]_' } ipversion() { python3 -c 'for addr in __import__("sys").argv[1:]: print(__import__("ipaddress").ip_address(addr).version)' "$@" } -os=$(cat "${__global}/explorer/os") +os=$(cat "${__global:?}/explorer/os") case $os in @@ -52,17 +52,17 @@ in ;; esac -if test -s "${__object}/parameter/name" +if test -s "${__object:?}/parameter/name" then - name=$(cat "${__object}/parameter/name") + name=$(cat "${__object:?}/parameter/name") else - name=$__object_id + name=${__object_id:?} fi -state_should=$(cat "${__object}/parameter/state") -bootproto=$(cat "${__object}/parameter/bootproto") -onchange=$(cat "${__object}/parameter/onchange") +state_should=$(cat "${__object:?}/parameter/state") +bootproto=$(cat "${__object:?}/parameter/bootproto") +onchange=$(cat "${__object:?}/parameter/onchange") -ifcfg_file="${NETWORK_SCRIPTS_DIR:?}/ifcfg-${__object_id}" +ifcfg_file="${NETWORK_SCRIPTS_DIR:?}/ifcfg-${__object_id:?}" onchange_action() { @@ -96,9 +96,9 @@ onchange_action() { EOF - if test -f "$__object/parameter/comment" + if test -f "${__object:?}/parameter/comment" then - awk '{ print "# " $0 }' <"$__object/parameter/comment" + awk '{ print "# " $0 }' <"${__object:?}/parameter/comment" echo fi @@ -118,11 +118,11 @@ onchange_action() { (suse) _startmode=manual - if test -f "${__object}/parameter/onboot" + if test -f "${__object:?}/parameter/onboot" then _startmode=auto fi - if test -f "${__object}/parameter/hotplug" + if test -f "${__object:?}/parameter/hotplug" then _startmode=ifplugd fi @@ -154,7 +154,7 @@ onchange_action() { _bonding_opts= - for _param in "${__object}"/parameter/* + for _param in "${__object:?}"/parameter/* do _key=$(param2var "${_param}") @@ -165,11 +165,11 @@ onchange_action() { in (bond-master) opt_format SLAVE yes - opt_format MASTER "$(cat "${__object}/parameter/${_param}")" + opt_format MASTER "$(cat "${__object:?}/parameter/${_param}")" ;; (bond-*) _key=$(echo "${_param#bond-}" | tr '-' '_') - _value=$(cat "${__object}/parameter/${_param}") + _value=$(cat "${__object:?}/parameter/${_param}") if test "${_key}" = 'arp_ip_target' then @@ -220,11 +220,11 @@ onchange_action() { : $((n+=1)) done ;; - esac <"${__object}/parameter/address" + esac <"${__object:?}/parameter/address" unset n _addr ;; (*) - opt_format "${_key}" "$(cat "${__object}/parameter/${_param}")" + opt_format "${_key}" "$(cat "${__object:?}/parameter/${_param}")" ;; esac ;; @@ -237,9 +237,9 @@ onchange_action() { opt_format BONDING_OPTS "${_bonding_opts# }" fi - if test -f "${__object}/parameter/extra-config" + if test -f "${__object:?}/parameter/extra-config" then - cat "${__object}/parameter/extra-config" + cat "${__object:?}/parameter/extra-config" fi } | __file "${ifcfg_file}" \ --state "${state_should}" --owner root --group root --mode 0644 \ From 71f5fbad148a879eb20b64702e9d2b42c9a8ac0a Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 31 Aug 2020 14:16:55 +0200 Subject: [PATCH 24/29] [type/__systemd_networkd_network] Error if expected environment variables are not set --- .../__systemd_networkd_network/explorer/state | 8 +++---- .../type/__systemd_networkd_network/manifest | 24 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/cdist/conf/type/__systemd_networkd_network/explorer/state b/cdist/conf/type/__systemd_networkd_network/explorer/state index 75913e11..6c225e4e 100755 --- a/cdist/conf/type/__systemd_networkd_network/explorer/state +++ b/cdist/conf/type/__systemd_networkd_network/explorer/state @@ -25,15 +25,15 @@ # In case networkctl cannot be found, the output will be "error". # -networkctl_bin=$("${__type_explorer}/networkctl_bin") +networkctl_bin=$("${__type_explorer:?}/networkctl_bin") test -x "${networkctl_bin}" || { echo error; exit 0; } -if test -f "${__object}/parameter/name" +if test -f "${__object:?}/parameter/name" then - name=$(cat "${__object}/parameter/name") + name=$(cat "${__object:?}/parameter/name") else - name=$__object_id + name=${__object_id:?} fi if "${networkctl_bin}" --no-pager --no-legend list "${name}" >/dev/null 2>&1 diff --git a/cdist/conf/type/__systemd_networkd_network/manifest b/cdist/conf/type/__systemd_networkd_network/manifest index 0879b6ec..ab4da92e 100755 --- a/cdist/conf/type/__systemd_networkd_network/manifest +++ b/cdist/conf/type/__systemd_networkd_network/manifest @@ -20,7 +20,7 @@ CONFIG_FILE_PATH='/etc/systemd/network' -networkctl_bin=$(cat "${__object}/explorer/networkctl_bin") +networkctl_bin=$(cat "${__object:?}/explorer/networkctl_bin") test -n "${networkctl_bin}" || { printf 'This system is not supported by this type (%s).' "${__type##*/}" >&2 @@ -32,19 +32,19 @@ test -n "${networkctl_bin}" || { # shellcheck disable=SC2034 read -r state_is read -r config_is || true -} <"${__object}/explorer/state" +} <"${__object:?}/explorer/state" -if test -f "${__object}/parameter/name" +if test -f "${__object:?}/parameter/name" then - name=$(cat "${__object}/parameter/name") + name=$(cat "${__object:?}/parameter/name") else - name=$__object_id + name=${__object_id:?} fi -priority=$(cat "${__object}/parameter/priority") -state_should=$(cat "${__object}/parameter/state") +priority=$(cat "${__object:?}/parameter/priority") +state_should=$(cat "${__object:?}/parameter/state") -config_file=$(printf '%s/%02u-%s.network' "${CONFIG_FILE_PATH}" "${priority}" "${__object_id}") +config_file=$(printf '%s/%02u-%s.network' "${CONFIG_FILE_PATH}" "${priority}" "${__object_id:?}") if test -f "${__object:?}/parameter/auto-reload" then @@ -56,18 +56,18 @@ fi gen_conf() { echo '[Match]' - if test -s "${__object}/parameter/match" + if test -s "${__object:?}/parameter/match" then - cat "${__object}/parameter/match" + cat "${__object:?}/parameter/match" else # By default match against the interface name printf 'Name=%s\n' "${name}" fi { - grep -e '^Network\.' "${__object}/parameter/option" + grep -e '^Network\.' "${__object:?}/parameter/option" - grep -v -e '^\(Match\|Network\)\.' "${__object}/parameter/option" \ + grep -v -e '^\(Match\|Network\)\.' "${__object:?}/parameter/option" \ | sort -t . -k 1 } | while read -r _option do From f464b382a684fee96a05f79cdeaea33664ee9105 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 31 Aug 2020 14:17:38 +0200 Subject: [PATCH 25/29] [type/__interface_ifcfg] Add --type parameter --- cdist/conf/type/__interface_ifcfg/man.rst | 4 ++++ cdist/conf/type/__interface_ifcfg/manifest | 11 +++++++++++ .../type/__interface_ifcfg/parameter/default/type | 1 + cdist/conf/type/__interface_ifcfg/parameter/required | 1 + 4 files changed, 17 insertions(+) create mode 100644 cdist/conf/type/__interface_ifcfg/parameter/default/type diff --git a/cdist/conf/type/__interface_ifcfg/man.rst b/cdist/conf/type/__interface_ifcfg/man.rst index 72b50350..54fc76b7 100644 --- a/cdist/conf/type/__interface_ifcfg/man.rst +++ b/cdist/conf/type/__interface_ifcfg/man.rst @@ -17,6 +17,10 @@ REQUIRED PARAMETERS ------------------- bootproto ... +type + The type of the interface, e.g. ``Ethernet``, ``Bridge``, ``Dummy``, + ``Loopback``. + Defaults to ``Ethernet``. OPTIONAL PARAMETERS diff --git a/cdist/conf/type/__interface_ifcfg/manifest b/cdist/conf/type/__interface_ifcfg/manifest index 62b0a9bb..a0bc0c16 100755 --- a/cdist/conf/type/__interface_ifcfg/manifest +++ b/cdist/conf/type/__interface_ifcfg/manifest @@ -61,6 +61,7 @@ fi state_should=$(cat "${__object:?}/parameter/state") bootproto=$(cat "${__object:?}/parameter/bootproto") onchange=$(cat "${__object:?}/parameter/onchange") +iftype=$(cat "${__object:?}/parameter/type") ifcfg_file="${NETWORK_SCRIPTS_DIR:?}/ifcfg-${__object_id:?}" @@ -108,6 +109,8 @@ onchange_action() { case $systype in (redhat) + opt_format TYPE "${iftype}" + for _param in onboot hotplug do _key=$(param2var "${_param}") @@ -116,6 +119,14 @@ onchange_action() { unset _param _key ;; (suse) + iftype=$(echo "${iftype}" | tr '[:upper:]' '[:lower:]') + if test "${iftype}" = 'loopback' -o "${iftype}" = 'dummy' + then + # Only use INTERFACETYPE for lo/dummy. + # cf. /usr/share/YaST2/modules/NetworkInterfaces.rb + opt_format INTERFACETYPE "${iftype}" + fi + _startmode=manual if test -f "${__object:?}/parameter/onboot" diff --git a/cdist/conf/type/__interface_ifcfg/parameter/default/type b/cdist/conf/type/__interface_ifcfg/parameter/default/type new file mode 100644 index 00000000..8942065e --- /dev/null +++ b/cdist/conf/type/__interface_ifcfg/parameter/default/type @@ -0,0 +1 @@ +Ethernet diff --git a/cdist/conf/type/__interface_ifcfg/parameter/required b/cdist/conf/type/__interface_ifcfg/parameter/required index 507318ee..8df5eed7 100644 --- a/cdist/conf/type/__interface_ifcfg/parameter/required +++ b/cdist/conf/type/__interface_ifcfg/parameter/required @@ -1 +1,2 @@ bootproto +type From a2d8d6f2d7c3c44cadcb1856c2b0f03f9b4ddb18 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 31 Aug 2020 16:03:29 +0200 Subject: [PATCH 26/29] [type/__bridge] Draft ifcfg backend --- .../__bridge/files/backends/ifcfg/manifest | 109 ++++++++++++++++++ cdist/conf/type/__bridge/manifest | 3 + 2 files changed, 112 insertions(+) create mode 100755 cdist/conf/type/__bridge/files/backends/ifcfg/manifest diff --git a/cdist/conf/type/__bridge/files/backends/ifcfg/manifest b/cdist/conf/type/__bridge/files/backends/ifcfg/manifest new file mode 100755 index 00000000..68e3e76d --- /dev/null +++ b/cdist/conf/type/__bridge/files/backends/ifcfg/manifest @@ -0,0 +1,109 @@ +#!/bin/sh -e +# -*- mode: sh; indent-tabs-mode: t -*- +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +os=$(cat "${__global:?}/explorer/os") + +case $os +in + (centos|redhat|scientific) + systype=redhat + ;; + (suse) + systype=suse + set -- "$@" --extra-config BRIDGE=yes + ;; + (*) + printf "Your operating system (%s) is currently not supported by %s's ifcfg backend.\n" "${os}" "${__type##*/}" >&2 + printf "Please contribute an implementation for it if you can.\n" >&2 + exit 1 + ;; +esac + + +bridge_stp='off' + +cd "${__object:?}/parameter" +for param in * +do + case $param + in + (bootproto) + bootproto=$(cat "${__object:?}/parameter/bootproto") + set -- "$@" --bootproto "${bootproto}" + ;; + (hotplug) + echo '--hotplug is not (yet) supported by the ifcfg backend.' >&2 + exit 1 + ;; + (port) + case $systype + in + (redhat) + # TOOD + ;; + (suse) + bridge_ports=$( + while read -r _port + do + test -z "$(echo "${_port}" | tr -d 'A-Za-z0-9')" || { + printf 'Invalid bridge port name: %s\n' "${_port}" >&2 + exit 1 + } + set -- "$@" "${_port}" + done <"${__object:?}/parameter/port" + echo "$*" + ) + + set -- "$@" --extra-config "BRIDGE_PORTS='${bridge_ports}'" + unset bridge_ports + ;; + esac + ;; + (stp) + bridge_stp='on' + ;; + (onboot) + # boolean parameters + set -- "$@" --"${param}" + ;; + (*) + set -- "$@" --"${param}" "$(cat "${__object:?}/parameter/${param}")" + ;; + esac +done + + +# Set boolean options +case $systype +in + (redhat) + set -- "$@" --extra-config "STP=${bridge_stp}" + test "${bridge_stp}" = 'on' || set -- "$@" --extra-config DELAY=0 + ;; + (suse) + set -- "$@" --extra-config "BRIDGE_STP=${bridge_stp}" + test "${bridge_stp}" = 'on' \ + || set -- "$@" --extra-config BRIDGE_FORWARDDELAY=0 + ;; +esac + +# Instantiate backend type +__interface_ifcfg "${__object_id:?}" --type Bridge "$@" diff --git a/cdist/conf/type/__bridge/manifest b/cdist/conf/type/__bridge/manifest index 1b9ae14b..755a09bc 100755 --- a/cdist/conf/type/__bridge/manifest +++ b/cdist/conf/type/__bridge/manifest @@ -33,6 +33,9 @@ in (devuan) impl_type=ifupdown.d ;; + (centos|redhat|scientific|suse) + impl_type=ifcfg + ;; (*) printf "Your operating system (%s) is currently not supported by this type (%s)\n" "${os}" "${__type##*/}" >&2 printf "Please contribute an implementation for it if you can.\n" >&2 From 6d057bbb61d79d14c57b9678cfc071899ca92e0a Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 30 Nov 2020 11:13:36 +0100 Subject: [PATCH 27/29] [type/__bridge] Fix man.rst: bridges are always logical interfaces --- cdist/conf/type/__bridge/man.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/conf/type/__bridge/man.rst b/cdist/conf/type/__bridge/man.rst index 130aa9d4..bffe088b 100644 --- a/cdist/conf/type/__bridge/man.rst +++ b/cdist/conf/type/__bridge/man.rst @@ -44,7 +44,7 @@ extra-config gateway The default gateway to assign to this interface (optional). name - The name of the physical or logical network device to configure. + The name of the logical network device to configure. Defaults to ``__object_id``. onchange The action to perform if the interface configuration has changed. From 5866dda7c7db0357ee0822e6130229bb7234e37c Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 30 Nov 2020 11:45:21 +0100 Subject: [PATCH 28/29] [type/__bridge] Make --port optional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …to support a new use case: only create the bridge using cdist but add ports later using other software. --- .../__bridge/files/backends/ifcfg/manifest | 15 +++++---- .../files/backends/ifupdown.d/manifest | 31 ++++++++++--------- .../type/__bridge/parameter/optional_multiple | 1 + .../type/__bridge/parameter/required_multiple | 1 - 4 files changed, 25 insertions(+), 23 deletions(-) delete mode 100644 cdist/conf/type/__bridge/parameter/required_multiple diff --git a/cdist/conf/type/__bridge/files/backends/ifcfg/manifest b/cdist/conf/type/__bridge/files/backends/ifcfg/manifest index 68e3e76d..6f863c14 100755 --- a/cdist/conf/type/__bridge/files/backends/ifcfg/manifest +++ b/cdist/conf/type/__bridge/files/backends/ifcfg/manifest @@ -37,13 +37,13 @@ in ;; esac - +bridge_ports= # space-separated list bridge_stp='off' cd "${__object:?}/parameter" for param in * do - case $param + case ${param} in (bootproto) bootproto=$(cat "${__object:?}/parameter/bootproto") @@ -54,7 +54,7 @@ do exit 1 ;; (port) - case $systype + case ${systype} in (redhat) # TOOD @@ -67,13 +67,10 @@ do printf 'Invalid bridge port name: %s\n' "${_port}" >&2 exit 1 } - set -- "$@" "${_port}" + printf ' %s' "${_port}" done <"${__object:?}/parameter/port" - echo "$*" ) - - set -- "$@" --extra-config "BRIDGE_PORTS='${bridge_ports}'" - unset bridge_ports + bridge_ports=${bridge_ports# } ;; esac ;; @@ -90,6 +87,8 @@ do esac done +# Set bridge ports +set -- "$@" --extra-config "BRIDGE_PORTS='${bridge_ports}'" # Set boolean options case $systype diff --git a/cdist/conf/type/__bridge/files/backends/ifupdown.d/manifest b/cdist/conf/type/__bridge/files/backends/ifupdown.d/manifest index 0528bb1b..f29b883a 100755 --- a/cdist/conf/type/__bridge/files/backends/ifupdown.d/manifest +++ b/cdist/conf/type/__bridge/files/backends/ifupdown.d/manifest @@ -22,19 +22,20 @@ __package_apt bridge-utils export require=__package_apt/bridge-utils +bridge_ports='none' # space-separated list bridge_stp='off' enable_hotplug=no cd "${__object:?}/parameter" for param in * do - case $param + case ${param} in (bootproto) bootproto=$(cat "${__object:?}/parameter/bootproto") set -- "$@" --bootproto "${bootproto}" - case $bootproto + case ${bootproto} in (manual) # if set to manual, there is nothing to wait for… @@ -49,19 +50,18 @@ do enable_hotplug=yes ;; (port) - while read -r _port - do - test -z "$(echo "${_port}" | tr -d 'A-Za-z0-9')" || { - printf 'Invalid bridge port name: %s\n' "${_port}" >&2 - exit 1 - } + bridge_ports=$( + while read -r _port + do + test -z "$(echo "${_port}" | tr -d 'A-Za-z0-9')" || { + printf 'Invalid bridge port name: %s\n' "${_port}" >&2 + exit 1 + } - bridge_ports="${bridge_ports-} ${_port}" - done <"${__object:?}/parameter/port" - unset _port - - set -- "$@" --extra-config "bridge_ports${bridge_ports}" - unset bridge_ports + printf ' %s' "${_port}" + done <"${__object:?}/parameter/port" + ) + bridge_ports=${bridge_ports# } ;; (stp) bridge_stp='on' @@ -77,6 +77,9 @@ do done +# Set bridge ports +set -- "$@" --extra-config "bridge_ports ${bridge_ports}" + # Set boolean options set -- "$@" --extra-config "bridge_stp ${bridge_stp}" test "${bridge_stp}" = 'on' || set -- "$@" --extra-config 'bridge_fd 0' diff --git a/cdist/conf/type/__bridge/parameter/optional_multiple b/cdist/conf/type/__bridge/parameter/optional_multiple index 5bb11f03..d54585d1 100644 --- a/cdist/conf/type/__bridge/parameter/optional_multiple +++ b/cdist/conf/type/__bridge/parameter/optional_multiple @@ -1,2 +1,3 @@ address extra-config +port diff --git a/cdist/conf/type/__bridge/parameter/required_multiple b/cdist/conf/type/__bridge/parameter/required_multiple deleted file mode 100644 index 20e6f145..00000000 --- a/cdist/conf/type/__bridge/parameter/required_multiple +++ /dev/null @@ -1 +0,0 @@ -port From 3a65e5f361ef7ed6b19394a6a32b8f2132d470c7 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 1 Feb 2021 22:26:15 +0100 Subject: [PATCH 29/29] [type/__interface_ifupdown.d] Require base interfaces file first --- cdist/conf/type/__interface_ifupdown.d/manifest | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cdist/conf/type/__interface_ifupdown.d/manifest b/cdist/conf/type/__interface_ifupdown.d/manifest index 3f99e32d..d37bc30b 100755 --- a/cdist/conf/type/__interface_ifupdown.d/manifest +++ b/cdist/conf/type/__interface_ifupdown.d/manifest @@ -1,6 +1,6 @@ #!/bin/sh -e # -# 2020 Dennis Camera (dennis.camera@ssrq-sds-fds.ch) +# 2020-2021 Dennis Camera (dennis.camera@ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -98,6 +98,7 @@ in # The /etc/network/interfaces file is overwritten with a basic example. __file "${INTERFACES_FILE}" --state present --owner root --mode 0644 \ --source "${__type}/files/interfaces" + export require="__file${INTERFACES_FILE}" else # If state is present and IFUPDOWND_LEAVE_EXISTING_CONFIG is set, # ensure that the interfaces.d directory is sourced in the main @@ -106,6 +107,7 @@ in --file "${INTERFACES_FILE}" \ --before '^#?[:blank:]*(auto|no-auto-down|no-scripts|allow-|iface|mapping|rename|source|source-directory)|^#[[:blank:]]*The .* interface$' \ --line "source ${INTERFACES_D_PATH}/*" + export require="__line${INTERFACES_FILE}:source_interfaces.d" fi __directory "${INTERFACES_D_PATH}" --state pre-exists \