#!/bin/sh # Update a virtual cluster built by autocluster, with IPv6 addresses # Copyright (C) Martin Schwenke 2019, 2020 # This program 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. # # This program 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 this program; if not, see . # Add IPv6 addresses on interfaces eth1, eth2, eth3. The IPv6 # addresses are calculated from the IPv4 addresses. The CTDB nodes # and public_addresses files are updated to contain only the IPv6 # addresses. # This nasty hack is requird because vagrant-libvirt does not properly # support IPv6 addresses. set -eu if [ $# -ne 1 ] ; then echo "usage: ${0} " exit 1 fi cluster="$1" hosts=".autocluster/${cluster}/hosts" if [ ! -r "$hosts" ] ; then echo "error: no file \"${hosts}\"" exit 1 fi nodes=".autocluster/${cluster}/nodes" : >"$nodes" public_addresses=".autocluster/${cluster}/public_addresses" : >"$public_addresses" hosts_ipv6=".autocluster/${cluster}/hosts.ipv6" echo '# autocluster m1' >"$hosts_ipv6" maybe_add_ip () { _host="$1" _addr="$2" _iface="$3" printf ' %s@%s: ' "$_addr" "$_iface" _t=$(ssh -n "$_host" ip -o addr show to "${_addr%/*}" | \ awk '{print $2}') if [ -z "$_t" ] ; then ssh -n "$_host" ip addr add "$_addr" dev "$_iface" echo '+' else echo '.' fi } echo "Confirming IPv6 addresses:" sort -n "$hosts" | while read -r ipv4 fqdn host ; do case "$ipv4" in \#*) continue ;; esac ipv4_rest="$ipv4" a="${ipv4_rest%%.*}" ipv4_rest="${ipv4_rest#*.}" b="${ipv4_rest%%.*}" ipv4_rest="${ipv4_rest#*.}" c="${ipv4_rest%%.*}" ipv4_rest="${ipv4_rest#*.}" d="${ipv4_rest%%.*}" echo "${host}:" ssh -n "$host" sysctl -q net.ipv6.conf.all.disable_ipv6=0 # # eth1 # eth1_ipv6=$(printf 'fd00:%x:%x:%x::%x/64' "$a" "$b" "$c" "$d") case "$host" in ${cluster}n[0-9]*) echo "${eth1_ipv6%/*}" >>"$nodes" ;; esac echo "${eth1_ipv6%/*} ${fqdn} ${host}" >>"$hosts_ipv6" maybe_add_ip "$host" "$eth1_ipv6" "eth1" # # eth2 # eth2_c=$((c + 1)) eth2_ipv6=$(printf 'fd00:%x:%x:%x::%x/64' "$a" "$b" "$eth2_c" "$d") case "$host" in ${cluster}n[0-9]*) p_d=$((d + 100)) p=$(printf 'fd00:%x:%x:%x::%x/64' "$a" "$b" "$eth2_c" "$p_d") printf '%s\t%s\n' "$p" "eth2" >>"$public_addresses" ;; esac maybe_add_ip "$host" "$eth2_ipv6" "eth2" # # eth3 # eth3_c=$((c + 2)) eth3_ipv6=$(printf 'fd00:%x:%x:%x::%x/64' "$a" "$b" "$eth3_c" "$d") case "$host" in ${cluster}n[0-9]*) p_d=$((d + 100)) p=$(printf 'fd00:%x:%x:%x::%x/64' "$a" "$b" "$eth3_c" "$p_d") printf '%s\t%s\n' "$p" "eth3" >>"$public_addresses" ;; esac maybe_add_ip "$host" "$eth3_ipv6" "eth3" done echo echo "${nodes}:" cat "$nodes" echo echo "${public_addresses}:" cat "$public_addresses" echo echo "${hosts_ipv6}:" cat "$hosts_ipv6" echo echo "Stopping ctdb:" sort -n "$hosts" | while read -r ipv4 _ host ; do case "$ipv4" in \#*) continue ;; esac case "$host" in ${cluster}n[0-9]*) echo "${host}" ssh -n "$host" systemctl stop ctdb ;; esac done echo echo "Determining CTDB configuration directory" conf=".autocluster/${cluster}/config.yml" if grep -Fxq 'tarball: null' "$conf" ; then # Default ctdb_config_dir="/etc/ctdb" else prefix=$(sed -n -e 's|^tarball_install_prefix: *||p' "$conf") ctdb_config_dir="${prefix}/etc/ctdb" fi echo "$ctdb_config_dir" echo echo "Copying configuration files:" sort -n "$hosts" | while read -r ipv4 _ host ; do case "$ipv4" in \#*) continue ;; esac case "$host" in ${cluster}n[0-9]*|${cluster}test[0-9]*) dst="${host}:${ctdb_config_dir}/nodes" echo "$dst" scp -q "$nodes" "$dst" ;; esac case "$host" in ${cluster}n[0-9]*) dst="${host}:${ctdb_config_dir}/public_addresses" echo "$dst" scp -q "$public_addresses" "$dst" ;; esac done echo echo "Starting ctdb:" sort -n "$hosts" | while read -r ipv4 _ host ; do case "$ipv4" in \#*) continue ;; esac case "$host" in ${cluster}n[0-9]*) echo "${host}" ssh -n "$host" systemctl start ctdb ;; esac done echo echo "Waiting until healthy:" sort -n "$hosts" | while read -r ipv4 _ host ; do case "$ipv4" in \#*) continue ;; esac if [ "$host" != "${cluster}n1" ] ; then continue fi timeout=120 printf '|<%d|' $timeout for n in $(seq 1 $timeout) ; do if ssh -n "$host" ctdb nodestatus all >/dev/null ; then break fi printf '.' sleep 1 done out=$(ssh -n "$host" ctdb nodestatus all 2>&1) # shellcheck disable=SC2181 if [ $? -eq 0 ] ; then printf '|%d|\n' "$n" else printf 'TIMEOUT!\n' fi echo echo "$out" done