Compare commits

...

5 commits

Author SHA1 Message Date
Darko Poljak
449426d362 Note that type rewrites network interface files 2020-01-23 14:43:33 +01:00
Darko Poljak
7408ddc134 Rewrite man page in rst 2020-01-23 14:40:25 +01:00
Darko Poljak
a30b4e3619 Fix shellcheck issues 2020-01-23 14:40:25 +01:00
Darko Poljak
f03299ebf3 __service -> __start_on_boot 2020-01-23 14:40:25 +01:00
Darko Poljak
e3553b15b6 Add Steven's __netowrk_interface type 2020-01-23 14:40:25 +01:00
17 changed files with 1268 additions and 0 deletions

View file

@ -0,0 +1,38 @@
#!/bin/sh
#
# workaround the bloody upstart race conditions
# by delaying the emission of the net-device-up signal until the interface is
# really up and configured.
#
# environment variables:
# METHOD=dhcp
# MODE=start
# LOGICAL=eth0
# PHASE=post-up
# ADDRFAM=inet
# VERBOSITY=0
# PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# IF_METRIC=100
# IFACE=eth0
# PWD=/root
# nothing to do for loopback
[ "$IFACE" = lo ] && exit 0
LOG_FILE="/tmp/wait-for-ip-${IFACE}.log"
cp /dev/null $LOG_FILE
RETRY=20
index=0
if [ "$ADDRFAM" = "inet" -a "$METHOD" = "dhcp" ]; then
until [ -n "$ip" -o $index -eq $RETRY ]; do
ip=$(ip -o -family inet addr show dev $IFACE | awk '{split($4, a, "/"); print a[1]}')
index=$((index+1))
sleep 0.5
done
if [ -n "$ip" ]; then
echo "Interface $IFACE is up with ip $ip after $index of $RETRY tries." >> $LOG_FILE
else
echo "Interface $IFACE failed to come up with an ip address, giving up after $RETRY tries." >> $LOG_FILE
fi
fi

View file

@ -0,0 +1,64 @@
#!/bin/sh
#
# See 'IFACE OPTIONS' in interfaces(5) for available variables.
#
DEBUG=
#DEBUG=1
debug() {
if [ "$DEBUG" ]; then
echo "[DEBUG] $@" >&2
fi
}
interface="$IFACE"
# noop for loopback
[ "$interface" = "lo" ] && exit 0
# only work with ipv4
[ "$ADDRFAM" = "inet" ] || exit 0
# Interface must be explicitly configured to do symmetric routing.
[ "${IF_SYMMETRIC_ROUTING:-no}" = "no" ] && exit 0
case "$MODE" in
start)
action="up"
;;
stop)
action="down"
;;
esac
case "$METHOD" in
dhcp)
LEASEFILE="/var/lib/dhcp/dhclient.${interface}.leases"
ip_address="$(awk '/fixed-address/ {sub(/;$/,""); print $2}' "$LEASEFILE" | tail -1)"
subnet_mask_or_prefix="$(awk '/option subnet-mask/ {sub(/;$/,""); print $3}' "$LEASEFILE" | tail -1)"
gateway="$(awk '/option routers/ {sub(/;$/,""); print $3}' "$LEASEFILE" | tail -1)"
;;
static)
[ -n "$IF_ADDRESS" ] && ip_address="$IF_ADDRESS"
[ -n "$IF_NETMASK" ] && subnet_mask_or_prefix="$IF_NETMASK"
[ -n "$IF_GATEWAY" ] && gateway="$IF_GATEWAY"
;;
*)
echo "Unknown/unsupported METHOD: $METHOD" >&2
exit 1
;;
esac
debug "$interface -----"
debug "action: $action"
debug "interface: $interface"
debug "ip_address: $ip_address"
debug "subnet_mask_or_prefix: $subnet_mask_or_prefix"
debug "gateway: $gateway"
debug "/$interface -----"
if [ -n "$action" -a -n "$interface" -a -n "$ip_address" -a -n "$subnet_mask_or_prefix" ]; then
symmetric-routing "$action" "$interface" "$ip_address" "$subnet_mask_or_prefix" "$gateway"
fi

View file

@ -0,0 +1,9 @@
# Generated by cdist __network_interface
# Changes will be overwritten.
# loopback
auto lo
iface lo inet loopback
# include per interface configurations
source /etc/network/interfaces.d/*.conf

View file

@ -0,0 +1,238 @@
#!/bin/sh -e
#
# 2012-2018 Steven Armstrong (steven-cdist at armstrong.cc)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
__package ifupdown
# Use cumulus ifupdown2 instead of ifupown and ifenslave
# ifupdown2 is currently not compatible with network-wait-online.
#__package ifupdown \
# --name ifupdown2
type_files="$__type/files/debian"
mkdir "$__object/files"
interface_filename="${__object_id}.conf"
(
cat << DONE
# Created by cdist ${__type##*/}
# Do not change. Changes will be overwritten.
#
DONE
if [ -f "$__object/parameter/comment" ]; then
awk '{ print "# "$0 }' < "$__object/parameter/comment"
fi
if [ -f "$__object/parameter/onboot" ]; then
# shellcheck disable=SC2154
printf "auto %s\n" "$name"
elif [ -f "$__object/parameter/hotplug" ]; then
# shellcheck disable=SC2154
printf "allow-hotplug %s\n" "$name"
fi
ignored_parameters="linkdelay"
manually_handled_parameters="name comment extra-config state method onboot hotplug nodns noroute no-network-wait-online symmetric-routing bond-slaves"
# shellcheck disable=SC2154
case "$method" in
dhcp)
printf "iface %s inet %s\n" "$name" "$method"
ignored_parameters="$ignored_parameters address broadcast gateway netmask"
;;
static|manual)
printf "iface %s inet %s\n" "$name" "$method"
;;
*)
echo "Unsupported value for parameter --method. Got '$method'. See man page for supported values." >&2
exit 1
;;
esac
for param in "$__object"/parameter/*; do
if echo "$ignored_parameters" | grep -w -q "$param"; then
continue
fi
if echo "$manually_handled_parameters" | grep -w -q "$param"; then
continue
fi
if [ -f "$type_files/name-map" ]; then
key="$(awk -v param="$param" '{ if ($1 == param) {print $2;} else { print param;} }' "$type_files/name-map")"
else
key="$param"
fi
printf " %s %s\n" "$key" "$(cat "$__object/parameter/$param")"
done
if [ -f "$__object/parameter/bond-mode" ] || [ -f "$__object/parameter/bond-primary" ]; then
# Note: ifenslave is not needed when using ifupdown2
# install package required for bonding
__package ifenslave
if [ -f "$__object/parameter/bond-slaves" ]; then
printf ' bond-slaves %s\n' "$(cat "$__object/parameter/bond-slaves")"
else
# need this or the slave tries to bring the master up, but the master hangs waiting for a slave
printf ' bond-slaves none\n'
fi
fi
if [ -f "$__object/parameter/no-network-wait-online" ]; then
# Do not consider this interface in network-wait-online.service
printf ' no-network-wait-online yes\n'
fi
if [ -f "$__object/parameter/symmetric-routing" ]; then
# Deploy scripts that implement the feature ...
__file /sbin/symmetric-routing \
--owner root --group root --mode 0755 \
--source "$__type/files/symmetric-routing"
require="__package/ifupdown __file/sbin/symmetric-routing" \
__file /etc/network/if-up.d/symmetric-routing \
--owner root --group root --mode 0755 \
--source "$__type/files/debian/ifupdown-symmetric-routing"
require="__package/ifupdown __file/etc/network/if-up.d/symmetric-routing" \
__link /etc/network/if-down.d/symmetric-routing \
--type symbolic \
--source ../if-up.d/symmetric-routing
# ... then enable it in interface stanza file.
printf ' symmetric-routing yes\n'
fi
# shellcheck disable=SC2154
if [ -n "$vlan" ] && [ -n "$device" ]; then
# Explicit parent interface for vlans
printf ' vlan-raw-device %s\n' "$device"
fi
if [ -f "$__object/parameter/extra-config" ]; then
extra_config="$(cat "$__object/parameter/extra-config")"
if [ "$extra_config" = "-" ]; then
extra_config="$__object/stdin"
fi
awk '{print " " $0}' "$extra_config"
fi
) >> "$__object/files/$interface_filename"
__directory /etc/network \
--state present \
--owner root \
--group root \
--mode 755
require="__directory/etc/network" \
__directory /etc/network/interfaces.d \
--state present \
--owner root \
--group root \
--mode 755
require="__directory/etc/network" \
__file /etc/network/interfaces \
--source "$type_files/interfaces" \
--owner root \
--group root \
--mode 644
# shellcheck disable=SC2154
require="__file/etc/network/interfaces __directory/etc/network/interfaces.d" \
__file "/etc/network/interfaces.d/$interface_filename" \
--owner root \
--group root \
--mode 644 \
--source "$__object/files/$interface_filename" \
--state "$state"
if [ "$method" = "dhcp" ] && [ -f "$__object/parameter/noroute" ]; then
(
cat << DONE
# Created by cdist ${__type##*/}
# Do not change. Changes will be overwritten.
#
if [ "\$interface" = "$name" ]; then
case "\$reason" in
BOUND|RENEW|REBIND|REBOOT)
# prevent default gateway to be set by this interface
unset new_routers
;;
esac
fi
DONE
) | \
__file "/etc/dhcp/dhclient-enter-hooks.d/cdist-__network_interface-${name}-noroute" \
--owner root \
--group root \
--mode 644 \
--source - \
--state "$state"
fi # end noroute
if [ "$method" = "dhcp" ] && [ -f "$__object/parameter/nodns" ]; then
(
cat << DONE
# Created by cdist ${__type##*/}
# Do not change. Changes will be overwritten.
#
if [ "\$interface" = "$name" ]; then
# Prevent /etc/resolv.conf from being changed by this interface
# by overriding the default 'make_resolv_conf' function.
make_resolv_conf(){
:
}
fi
DONE
) | \
__file "/etc/dhcp/dhclient-enter-hooks.d/cdist-__network_interface-${name}-nodns" \
--owner root \
--group root \
--mode 644 \
--source - \
--state "$state"
fi # end nodns
os=$(cat "$__global/explorer/os")
if [ "$os" = "ubuntu" ]; then
# workaround the bloody upstart race conditions
# by deploying a script that delays the emission of the net-device-up
# signal until the interface is really up and configured.
#script_name="00000-wait-for-ip"
#__file "/etc/network/if-up.d/$script_name" \
# --owner root --group root --mode 755 \
# --source "$type_files/$script_name"
# Deal with systemd network-online.target race conditions
require="__package/ifupdown" \
__file /etc/network/if-pre-up.d/network-online \
--owner root --group root --mode 0755 \
--source "$__type/files/debian/network-online"
require="__file/etc/network/if-pre-up.d/network-online" \
__link /etc/network/if-up.d/network-online \
--type symbolic \
--source ../if-pre-up.d/network-online
fi

View file

@ -0,0 +1,49 @@
#!/bin/sh
#
# See 'IFACE OPTIONS' in interfaces(5) for available variables.
#
DEBUG=
#DEBUG=1
debug() {
if [ "$DEBUG" ]; then
echo "[DEBUG] $@" >&2
fi
}
interface="$IFACE"
# noop for loopback
[ "$interface" = "lo" ] && exit 0
# nothing usefull we could do for '--all'
[ "$interface" = "--all" ] && exit 0
# Interface is configured to not be considered by network-wait-online.service
[ "${IF_NO_NETWORK_WAIT_ONLINE:-no}" = "yes" ] && exit 0
case "$MODE" in
start)
action="up"
;;
stop)
action="down"
;;
esac
state_dir=/run/network-online-interfaces
mkdir -p "$state_dir"
case "$PHASE" in
pre-up)
# Create flag file to wait for in network-wait-online.service
touch "$state_dir/$interface"
;;
post-up)
# This interface is up!
# Remove the flag file that was created in /sbin/ifup-pre-local
# so that the network-wait-online.service can reach the network-online.target
rm -rf "$state_dir/$interface"
;;
esac

View file

@ -0,0 +1,17 @@
[Unit]
Description=Wait for network to be configured
Documentation=man:ifup(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=%NETWORK_SERVICE_NAME%
Before=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
TimeoutStartSec=3min
ExecStart=/bin/sh -ec 'while [ "$(ls -1 /run/network-online-interfaces/)" ]; do sleep 1; done'
[Install]
WantedBy=network-online.target

View file

@ -0,0 +1,39 @@
#!/bin/sh
#echo "/sbin/ifup-pre-local" >&2
#set -x
config="$1"
interface="$1"
cd /etc/sysconfig/network-scripts
. ./network-functions
[ -f ../network ] && . ../network
need_config "$config"
source_config
# If not started at boot we don't care
[ "${ONBOOT:-no}" = "no" ] && exit 0
# noop for loopback
[ "$DEVICE" = "lo" ] && exit 0
state_dir=/run/network-online-interfaces
mkdir -p "$state_dir"
if [ "${NO_NETWORK_WAIT_ONLINE:-no}" = "no" ]; then
# remember device for later use in network-wait-online.service
touch "$state_dir/$DEVICE"
fi
# hackaround bugs in /etc/sysconfig/network-scripts/ifup
wait_for_device=20
index=0
until [ -d "/sys/class/net/$DEVICE" -o $index -eq $wait_for_device ]; do
echo "waiting for /sys/class/net/$DEVICE $index/$wait_for_device" >&2
sleep 1
index=$(($index + 1))
done

View file

@ -0,0 +1,84 @@
#!/bin/sh
myname="${0##*/}"
case "$myname" in
ifup-local)
action="up"
;;
ifdown-local|ifdown-pre-local)
action="down"
;;
*)
echo "Unable to determine action from script name: $myname" >&2
exit 1
;;
esac
DEBUG=
#DEBUG=1
debug() {
if [ "$DEBUG" ]; then
echo "[DEBUG] $@" >&2
fi
}
interface="$1"
# noop for loopback
[ "$interface" = "lo" ] && exit 0
cd /etc/sysconfig/network-scripts
. ./network-functions
[ -f ../network ] && . ../network
need_config "$interface"
source_config
case "${BOOTPROTO}" in
bootp|dhcp)
generate_lease_file_name
ip_address="$(awk '/fixed-address/ {sub(/;$/,""); print $2}' "$LEASEFILE" | tail -1)"
subnet_mask_or_prefix="$(awk '/option subnet-mask/ {sub(/;$/,""); print $3}' "$LEASEFILE" | tail -1)"
gateway="$(awk '/option routers/ {sub(/;$/,""); print $3}' "$LEASEFILE" | tail -1)"
;;
none)
# No ip address set -> nothing we could do
[ -n "$IPADDR" ] && ip_address="$IPADDR"
[ -n "$PREFIX" ] && subnet_mask_or_prefix="$PREFIX" || {
[ -n "$NETMASK" ] && subnet_mask_or_prefix="$NETMASK"
}
[ -n "$GATEWAY" ] && gateway="$GATEWAY"
;;
*)
echo "Unknown/unsupported BOOTPROTO: $BOOTPROTO" >&2
exit 1
;;
esac
debug "$interface -----"
debug "action: $action"
debug "interface: $interface"
debug "ip_address: $ip_address"
debug "subnet_mask_or_prefix: $subnet_mask_or_prefix"
debug "gateway: $gateway"
debug "/$interface -----"
# Interface must be explicitly configured to do symmetric routing.
if [ "${SYMMETRIC_ROUTING:-no}" = "yes" ]; then
if [ -n "$action" -a -n "$interface" -a -n "$ip_address" -a -n "$subnet_mask_or_prefix" ]; then
symmetric-routing "$action" "$interface" "$ip_address" "$subnet_mask_or_prefix" "$gateway"
fi
fi
case "$action" in
up)
# This interface is up!
# Remove the flag file that was created in /sbin/ifup-pre-local
# so that the network-wait-online.service can reach the network-online.target
state_dir=/run/network-online-interfaces
rm -rf "$state_dir/$interface"
;;
esac

View file

@ -0,0 +1,175 @@
#!/bin/sh -e
#
# 2014 Steven Armstrong (steven-cdist at armstrong.cc)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
type_files="$__type/files/redhat"
mkdir "$__object/files"
# shellcheck disable=SC2154
interface_filename="ifcfg-${name}"
(
cat << DONE
# Created by cdist ${__type##*/}
# Do not change. Changes will be overwritten.
#
DONE
if [ -f "$__object/parameter/comment" ]; then
awk '{ print "# "$0 }' < "$__object/parameter/comment"
fi
printf 'DEVICE="%s"\n' "$name"
printf 'NM_CONTROLLED=no\n'
printf 'USERCTL=no\n'
if [ -f "$__object/parameter/onboot" ]; then
printf 'ONBOOT=yes\n'
else
printf 'ONBOOT=no\n'
fi
if [ -f "$__object/parameter/hotplug" ]; then
printf 'HOTPLUG=yes\n'
else
printf 'HOTPLUG=no\n'
fi
if [ -f "$__object/parameter/nodns" ]; then
printf 'PEERDNS=no\n'
else
printf 'PEERDNS=yes\n'
fi
if [ -f "$__object/parameter/noroute" ]; then
printf 'DEFROUTE=no\n'
else
printf 'DEFROUTE=yes\n'
fi
if [ -f "$__object/parameter/no-network-wait-online" ]; then
printf 'NO_NETWORK_WAIT_ONLINE=yes\n'
fi
if [ -f "$__object/parameter/symmetric-routing" ]; then
# Deploy scripts that implement the feature ...
__file /sbin/symmetric-routing \
--owner root --group root --mode 0755 \
--source "$__type/files/symmetric-routing"
# ... then enable it in interface cfg file.
printf 'SYMMETRIC_ROUTING=yes\n'
fi
ignored_parameters=""
manually_handled_parameters="name comment extra-config state method onboot hotplug nodns noroute no-network-wait-online symmetric-routing"
# shellcheck disable=SC2154
case "$method" in
dhcp)
printf 'BOOTPROTO=dhcp\n'
ignored_parameters="$ignored_parameters address broadcast gateway netmask"
;;
static|manual)
printf 'BOOTPROTO=none\n'
;;
*)
echo "Unsupported value for parameter --method. Got '$method'. See man page for supported values." >&2
exit 1
;;
esac
for param in "$__object"/parameter/*; do
if echo "$ignored_parameters" | grep -w -q "$param"; then
continue
fi
if echo "$manually_handled_parameters" | grep -w -q "$param"; then
continue
fi
case "$param" in
bond-master)
# if someone is my master, I am a slave
printf 'SLAVE=yes\n'
printf 'MASTER=%s\n' "$(cat "$__object/parameter/$param")"
;;
bond-*)
key="$(echo "${param#*bond-}" | tr - _)"
if [ "$param" = "bond-arp-ip-target" ]; then
value="$(tr '\n' , < "$__object/parameter/$param")"
# strip trailing comma
value="${value%,}"
else
value="$(cat "$__object/parameter/$param")"
fi
printf '%s=%s\n' "$key" "$value" >> "$__object/files/bonding_opts"
;;
*)
# check for redhat specific name for this parameter
if [ -f "$type_files/name-map" ]; then
key="$(awk -v param="$param" '{ if ($1 == param) {print $2;} else { print param;} }' "$type_files/name-map")"
else
key="$param"
fi
# redhat likes things uppercase
key="$(echo "$key" | tr '[:lower:]' '[:upper:]')"
printf '%s=%s\n' "$key" "$(cat "$__object/parameter/$param")"
;;
esac
done
if [ -f "$__object/files/bonding_opts" ]; then
value="$(tr '\n' ' ' < "$__object/files/bonding_opts")"
# strip trailing space
value="${value% }"
printf 'BONDING_OPTS="%s"\n' "$value"
fi
# shellcheck disable=SC2154
if [ -n "$vlan" ] && [ -n "$device" ]; then
# Enable vlan for this interface
printf 'VLAN=yes\n'
fi
if [ -f "$__object/parameter/extra-config" ]; then
extra_config="$(cat "$__object/parameter/extra-config")"
if [ "$extra_config" = "-" ]; then
extra_config="$__object/stdin"
fi
cat "$extra_config"
fi
) >> "$__object/files/$interface_filename"
# shellcheck disable=SC2154
__file "/etc/sysconfig/network-scripts/$interface_filename" \
--owner root \
--group root \
--mode 644 \
--source "$__object/files/$interface_filename" \
--state "$state"
# Deploy helper scripts
__file /sbin/ifupdown-local \
--owner root --group root --mode 0755 \
--source "$__type/files/redhat/ifupdown-local"
require="__file/sbin/ifupdown-local" \
__link /sbin/ifup-local \
--type symbolic \
--source ./ifupdown-local
require="__file/sbin/ifupdown-local" \
__link /sbin/ifdown-pre-local \
--type symbolic \
--source ./ifupdown-local
__file /sbin/ifup-pre-local \
--owner root --group root --mode 0755 \
--source "$__type/files/redhat/ifup-pre-local"

View file

@ -0,0 +1 @@
address ipaddr

View file

@ -0,0 +1,240 @@
#!/bin/sh
#
set -e
error() {
echo "[ERROR] $@" >&2
}
die() {
error "$@"
exit 1
}
info() {
echo "[INFO] $@" >&2
}
debug() {
if [ "$DEBUG" ]; then
echo "[DEBUG] $@" >&2
fi
}
usage() {
cat << EOS 1>&2
Usage: ${0##*/} [OPTIONS] ACTION INTERFACE IP_ADDRESS SUBNET_MASK_OR_PREFIX [GATEWAY]
(see -h for more information)
EOS
}
help() {
usage 2>&1 | head -n -1 1>&2
cat << EOS 1>&2
Setup policy based routing for the given interface
to ensure symmetric routing.
ACTION must be either 'up' or 'down' to add respectively remove the
routing table entries.
Options:
-h show this help message
-d run in debug mode
-x run with 'set -x' set
-n no action, just show what would be done without doing it
Examples:
${0##*/} up eth1 192.168.42.23 255.255.255.0 192.168.0.1
${0##*/} down eth1 192.168.42.23 255.255.255.0 192.168.0.1
# gateway is optional
${0##*/} up eth1 192.168.42.23 255.255.255.0
${0##*/} down eth1 192.168.42.23 255.255.255.0
# same but using prefix instead of subnet mask
${0##*/} up eth1 192.168.42.23 24 192.168.0.1
${0##*/} down eth1 192.168.42.23 24 192.168.0.1
EOS
}
die_usage() {
error "$@"
usage
exit 1
}
### Utility functions
# Convert ip to int.
ip2int() {
_ip="$1"
{ IFS=. read _a _b _c _d; } << _done
$_ip
_done
echo $(((((((_a << 8) | _b) << 8) | _c) << 8) | _d))
unset _ip _a _b _c _d
}
# Convert int to ip.
int2ip() {
_ui32=$1; shift
_ip=
for _n in 1 2 3 4; do
_ip=$((_ui32 & 0xff))${_ip:+.}$_ip
_ui32=$((_ui32 >> 8))
done
echo $_ip
unset _ui32 _ip _n
}
# Convert the given prefix into a subnet mask.
mask_from_prefix() {
_prefix="$1"
_mask=$((0xffffffff << (32 - $_prefix)))
int2ip $_mask
unset _prefix _mask
}
# Calculate network number from the given ip and prefix.
network_from_ip_and_prefix() {
_ip="$1"
_prefix="$2"
_addr=$(ip2int $_ip)
_mask=$((0xffffffff << (32 - $_prefix)))
int2ip $((_addr & _mask))
unset _ip _prefix _addr _mask
}
# Calculate number of bits in the given subnet mask.
prefix_from_mask() {
# Assumes there's no "255." after a non-255 byte in the mask
_mask="$1"
_x=${_mask##*255.}
set -- 0^^^128^192^224^240^248^252^254^ $(( (${#1} - ${#_x})*2 )) ${_x%%.*}
_x=${1%%$3*}
echo $(( $2 + (${#_x}/4) ))
unset _mask _x
}
rt_tables=/etc/iproute2/rt_tables
#rt_tables=/tmp/rt_tables
# Get and if required create a routing table for the given table name.
table_id_from_name() {
_interface="$1"
_table_id=$(awk -vname=$_interface '{ if ($2 == name) print $1 }' "$rt_tables")
if [ -z "$_table_id" ]; then
# find unused table id and create a new table for this interface
_used_ids=$(awk '$1 !~ /^(#| |255|254|253|0)/ { print $1 }' "$rt_tables")
for _tid in $(seq 1 252); do
if echo "$_used_ids" | grep -q "$_tid"; then
continue
else
_table_id="$_tid"
[ $NOACTION ] || printf '%s %s\n' "$_table_id" "$_interface" >> "$rt_tables"
break
fi
done
fi
echo "$_table_id"
unset _interface _table_id _used_ids _tid
}
### Parse command line arguments
NOACTION=
DEBUG=
SETX=
while getopts "ndxh" options
do
#echo "$flag" $OPTIND $OPTARG
case $options in
n) NOACTION=1;;
d) DEBUG=1;;
x) SETX=1;;
?|h) help
exit 0
;;
*) usage
exit 1
;;
esac
done
# Strip arguments allready handled by getopts
shift $((OPTIND-1))
[ "$SETX" ] && set -x
# Validate arguments
[ "$#" -ge 4 ] || die_usage "Expected at least 4 arguments, got: $#"
action="$1" # up | down
interface="$2"
ip_address="$3"
subnet_mask_or_prefix="$4"
gateway="$5"
debug "action: $action"
debug "interface: $interface"
debug "ip_address: $ip_address"
debug "subnet_mask_or_prefix: $subnet_mask_or_prefix"
debug "gateway: $gateway"
case "$subnet_mask_or_prefix" in
*.*)
# has a dot, must be a subnet mask
subnet_mask="$subnet_mask_or_prefix"
prefix=$(prefix_from_mask "$subnet_mask")
network="$(network_from_ip_and_prefix "$ip_address" "$prefix")"
;;
*)
# no dot, must be prefix
prefix="$subnet_mask_or_prefix"
subnet_mask="$(mask_from_prefix "$prefix")"
network="$(network_from_ip_and_prefix "$ip_address" "$prefix")"
;;
esac
table_name="$interface"
table_id="$(table_id_from_name "$table_name")"
debug "subnet_mask: $subnet_mask"
debug "prefix: $prefix"
debug "network: $network"
debug "table_name: $table_name"
debug "table_id: $table_id"
(
case "$action" in
up)
# setup routing table for interface
printf 'ip route add "%s/%s" dev "%s" proto static src "%s" table "%s"\n' \
"$network" "$prefix" "$interface" "$ip_address" "$table_name"
if [ -n "$gateway" ]; then
printf 'ip route add default via "%s" table "%s"\n' "$gateway" "$table_name"
fi
printf 'ip rule add from "%s" table "%s"\n' "$ip_address" "$table_name"
;;
down)
printf 'ip rule del from "%s" table "%s"\n' "$ip_address" "$table_name"
if [ -n "$gateway" ]; then
printf 'ip route del default via "%s" table "%s"\n' "$gateway" "$table_name"
fi
printf 'ip route del "%s/%s" dev "%s" proto static src "%s" table "%s"\n' \
"$network" "$prefix" "$interface" "$ip_address" "$table_name"
;;
*)
echo "Unknown action: $action" >&2
exit 1
;;
esac
# tell the kernel that it needs to re-parse the policy database
printf 'ip route flush cache\n'
) | (
if [ "$NOACTION" ]; then
cat
else
/bin/sh -s
fi
)

View file

@ -0,0 +1,200 @@
cdist-type__network_interface(7)
================================
NAME
----
cdist-type__network_interface - configure network interfaces
DESCRIPTION
-----------
Configures network interfaces on debian an redhat based systems.
Interface names containing a dot are assumed to be vlan tagged sub interfaces.
e.g. eth0.10 is vlan 10 on physical device eth0.
Note that this type rewrites network interface files.
REQUIRED PARAMETERS
-------------------
None.
OPTIONAL PARAMETERS
-------------------
name
The name of the physical or logical network device.
Defaults to __object_id.
method
The method for determining an IP address for the interface.
'dhcp', 'static' or 'manual'.
Defaults to 'dhcp'.
address
The IP address of the network interface.
Only used if --method is not 'dhcp'.
broadcast
Only used if --method is not 'dhcp'.
comment
Comment.
extra-config
Additional config that is added to the generated interfaces file verbatim.
gateway
Default gateway (dotted quad).
Only used if --method is not 'dhcp'.
netmask
The subnet mask to apply to the interface.
Only used if --method is not 'dhcp'.
metric
Routing metric for the default gateway.
mtu
The Maximum Transmission Unit size to use for the interface.
state
'present' or 'absent', defaults to 'present'.
bond-arp-interval
Specifies (in milliseconds) how often ARP monitoring occurs.
bond-arp-ip-target
Specifies the target IP address of ARP requests when the arp_interval parameter is enabled.
Can be specified up to 16 times.
bond-master
The name of the master (bonding) interface to which this slave should be enslaved.
bond-miimon
Specifies (in milliseconds) how often MII link monitoring occurs.
bond-mode
Allows you to specify the bonding policy. The value can be one of:
- balance-rr (0)
- active-backup (1)
- balance-xor (2)
- broadcast (3)
- 802.3ad (4)
- balance-tlb (5)
- balance-alb (6)
bond-primary
Specifies the interface name, such as eth0, of the primary device.
bond-slaves
The slave interfaces that form this bonding.
linkdelay
Only useable on Redhat based systems.
Time in seconds that the system should pause after the specific interface
is enabled. This may be useful if one interface is connected to a
switch which has spanning tree enabled and must wait for STP to
converge before the interface should be considered usable.
BOOLEAN PARAMETERS
------------------
onboot
Whether to bring the interface up on boot.
hotplug
Allow/disallow hotplug support for this interface.
nodns
Do not configure nameservers in /etc/resolv.conf.
noroute
Do not set default route.
no-network-wait-online
Do not consider this network interface in the network-wait-online.service unit.
symmetric-routing
Manage routing tables and rules to ensure symmetric routing.
EXAMPLES
--------
.. code-block:: sh
__network_interface eth0 --onboot
# Same thing, but explicitly define method
__network_interface eth0 --method dhcp --onboot
__network_interface eth1 \
--method static \
--address 192.168.42.23 \
--netmask 255.255.255.0 \
--gateway 192.168.42.1 \
--onboot
__network_interface eth3 --method dhcp --hotplug
# Don't wait for Infiniband interface to be up before reaching systemd network-online.target
__network_interface ib0 --method dhcp --no-network-wait-online
# active-backup bonding with 2 slaves
__network_interface bond0 \
--onboot \
--method static \
--bond-mode active-backup \
--bond-miimon 500 \
--bond-primary eth5 \
--address 10.205.9.65 \
--netmask 255.255.224.0
__network_interface eth5 \
--onboot \
--method manual \
--bond-master bond0
__network_interface eth6 \
--onboot \
--method manual \
--bond-master bond0
# extra config
__network_interface eth0 \
--method dhcp \
--extra-config - << DONE
post-up ip route add 10.205.0.0/19 via 10.205.161.1
post-up ip route add 10.205.96.0/19 via 10.205.161.1
pre-down ip route del 10.205.0.0/19 via 10.205.161.1
pre-down ip route del 10.205.96.0/19 via 10.205.161.1
DONE
SEE ALSO
--------
Redhat bonding documentation:
* https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/sec-Using_Channel_Bonding.html
* https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Networking_Guide/sec-Using_Channel_Bonding.html
* https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/s2-networkscripts-interfaces-chan.html
Debian bonding documentation
* /usr/share/doc/ifenslave-2.6/README.Debian.gz
Symmetric routing
* http://www.microhowto.info/howto/ensure_symmetric_routing_on_a_server_with_multiple_default_gateways.html
AUTHORS
-------
Steven Armstrong <steven-cdist--@--armstrong.cc>
COPYING
-------
Copyright \(C) 2012-2016 Steven Armstrong. You can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

View file

@ -0,0 +1,86 @@
#!/bin/sh -e
#
# 2012-2014 Steven Armstrong (steven-cdist at armstrong.cc)
# 2020 Adapted for upstream cdist by Darko Poljak (darko.poljak at gmail.com)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
os=$(cat "$__global/explorer/os")
osv="$(cat "$__global/explorer/os_version")"
not_supported() {
echo "Your operating system ($os $osv) is currently not supported by this type (${__type##*/})." >&2
echo "Please contribute an implementation for it if you can." >&2
exit 1
}
case "$os" in
ubuntu)
osv_int="$(echo "$osv" | tr -d .)"
if [ "$osv_int" -lt 1110 ]; then
not_supported
fi
manifest_file="$__type/files/debian/manifest"
systemd_network_service_name="networking.service"
;;
debian)
manifest_file="$__type/files/debian/manifest"
systemd_network_service_name="networking.service"
;;
centos|redhat)
manifest_file="$__type/files/redhat/manifest"
systemd_network_service_name="network.service"
;;
*)
not_supported
;;
esac
name="$(cat "$__object/parameter/name" 2>/dev/null || echo "$__object_id")"
method="$(cat "$__object/parameter/method")"
state="$(cat "$__object/parameter/state")"
device=
vlan=
case "$name" in
*.*)
device="${name%.*}"
vlan="${name#*.}"
;;
esac
# export variables
export name
export device
export vlan
export method
export state
# run os specific manifest
"$manifest_file"
if grep -q systemd "$__global/explorer/init"; then
sed -e "s|%NETWORK_SERVICE_NAME%|${systemd_network_service_name}|" \
"$__type/files/network-wait-online.service" | \
__file /etc/systemd/system/network-wait-online.service \
--owner root --group root --mode 0644 \
--source -
require="__file/etc/systemd/system/network-wait-online.service" \
__start_on_boot network-wait-online
fi

View file

@ -0,0 +1,6 @@
hotplug
nodns
noroute
onboot
no-network-wait-online
symmetric-routing

View file

@ -0,0 +1 @@
dhcp

View file

@ -0,0 +1 @@
present

View file

@ -0,0 +1,20 @@
address
bond-arp-interval
bond-arp-ip-target
bond-master
bond-miimon
bond-mode
bond-primary
bond-slaves
broadcast
comment
extra-config
gateway
linkdelay
method
metric
mtu
name
netmask
network
state