Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cloud-netconfig for openSUSE:Factory checked in at 2023-08-31 13:45:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cloud-netconfig (Old) and /work/SRC/openSUSE:Factory/.cloud-netconfig.new.1766 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cloud-netconfig" Thu Aug 31 13:45:41 2023 rev:15 rq:1108072 version:1.8 Changes: -------- --- /work/SRC/openSUSE:Factory/cloud-netconfig/cloud-netconfig.changes 2023-01-09 17:24:17.951327063 +0100 +++ /work/SRC/openSUSE:Factory/.cloud-netconfig.new.1766/cloud-netconfig.changes 2023-08-31 13:51:24.452424768 +0200 @@ -1,0 +2,7 @@ +Wed Aug 30 06:26:29 UTC 2023 - Joachim Gleissner <jgleiss...@suse.com> + +- Update to version 1.8: + + Fix Azure metadata check (bsc#1214715) + + Fix cleanup on ifdown + +------------------------------------------------------------------- Old: ---- cloud-netconfig-1.7.tar.bz2 New: ---- cloud-netconfig-1.8.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cloud-netconfig.spec ++++++ --- /var/tmp/diff_new_pack.KIWOMS/_old 2023-08-31 13:51:25.492461942 +0200 +++ /var/tmp/diff_new_pack.KIWOMS/_new 2023-08-31 13:51:25.496462085 +0200 @@ -42,7 +42,7 @@ %endif Name: %{base_name}%{flavor_suffix} -Version: 1.7 +Version: 1.8 Release: 0 License: GPL-3.0-or-later Summary: Network configuration scripts for %{csp_string} @@ -59,6 +59,7 @@ BuildRequires: sysconfig-netconfig Requires: sysconfig-netconfig %endif +BuildRequires: systemd-rpm-macros BuildRequires: pkgconfig(udev) %if 0%{?sle_version} > 150100 BuildRequires: NetworkManager @@ -74,7 +75,11 @@ Provides: cloud-netconfig Conflicts: cloud-netconfig %endif +%if 0%{?suse_version} == 1315 %{?systemd_requires} +%else +%{?systemd_ordering} +%endif %define _scriptdir %{_libexecdir}/cloud-netconfig %if 0%{?suse_version} > 1550 %define _netconfigdir %{_libexecdir}/netconfig.d @@ -120,6 +125,11 @@ ln -s /dev/null %{buildroot}/%{_sysconfdir}/udev/rules.d/75-persistent-net-generator.rules %endif +# install link to cleanup script in /etc/sysconfig/network/scripts to wicked +# will find it +mkdir -p %{buildroot}/%{_sysconfdir}/sysconfig/network/scripts +ln -s %{_scriptdir}/cloud-netconfig-cleanup %{buildroot}/%{_sysconfdir}/sysconfig/network/scripts/cloud-netconfig-cleanup + %if 0%{?sle_version} <= 150100 rm -r %{buildroot}/usr/lib/NetworkManager %endif @@ -127,7 +137,8 @@ %files -n %{base_name}%{flavor_suffix} %defattr(-,root,root) %{_scriptdir} -%if %{defined no_config} +%{_sysconfdir}/sysconfig/network/scripts/cloud-netconfig-cleanup +%if %{defined no_dist_conf} %config(noreplace) %{_distconfdir}/default/cloud-netconfig %else %{_distconfdir}/default/cloud-netconfig ++++++ cloud-netconfig-1.7.tar.bz2 -> cloud-netconfig-1.8.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.7/VERSION new/cloud-netconfig-1.8/VERSION --- old/cloud-netconfig-1.7/VERSION 2022-12-16 15:29:58.369590436 +0100 +++ new/cloud-netconfig-1.8/VERSION 2023-08-29 14:54:14.645962006 +0200 @@ -1 +1 @@ -1.7 +1.8 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.7/azure/functions.cloud-netconfig new/cloud-netconfig-1.8/azure/functions.cloud-netconfig --- old/cloud-netconfig-1.7/azure/functions.cloud-netconfig 2022-12-16 15:29:58.369590436 +0100 +++ new/cloud-netconfig-1.8/azure/functions.cloud-netconfig 2023-08-29 14:52:53.647936208 +0200 @@ -113,8 +113,8 @@ # metadata_available() { - local resp=$($CURL "http://169.254.169.254/metadata${URL_APX}" 2>/dev/null) - [[ "$resp" == *instance/* ]] + local resp=$($CURL "http://169.254.169.254/metadata/instance/${URL_APX}" 2>/dev/null) + [[ "$resp" == *network/* ]] return $? } Binary files old/cloud-netconfig-1.7/cloud-netconfig-1.7.tar.bz2 and new/cloud-netconfig-1.8/cloud-netconfig-1.7.tar.bz2 differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.7/cloud-netconfig.spec new/cloud-netconfig-1.8/cloud-netconfig.spec --- old/cloud-netconfig-1.7/cloud-netconfig.spec 2022-12-16 15:29:58.373590508 +0100 +++ new/cloud-netconfig-1.8/cloud-netconfig.spec 2023-08-29 14:53:10.071544960 +0200 @@ -1,7 +1,7 @@ # # spec file for package cloud-netconfig # -# Copyright (c) 2017 SUSE Linux GmbH, Nuernberg, Germany. +# Copyright (c) 2022 SUSE Linux GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -41,7 +41,7 @@ %endif Name: %{base_name}%{flavor_suffix} -Version: 1.7 +Version: 1.8 Release: 0 License: GPL-3.0-or-later Summary: Network configuration scripts for %{csp_string} @@ -59,7 +59,10 @@ Requires: sysconfig-netconfig %endif BuildRequires: pkgconfig(udev) +BuildRequires: systemd-rpm-macros +%if 0%{?sle_version} > 150100 BuildRequires: NetworkManager +%endif Requires: udev Requires: curl %if 0%{?sles_version} == 11 @@ -71,7 +74,11 @@ Provides: cloud-netconfig Conflicts: cloud-netconfig %endif +%if 0%{?suse_version} == 1315 %{?systemd_requires} +%else +%{?systemd_ordering} +%endif %define _scriptdir %{_libexecdir}/cloud-netconfig %if 0%{?suse_version} > 1550 %define _netconfigdir %{_libexecdir}/netconfig.d @@ -84,6 +91,7 @@ This package contains scripts for automatically configuring network interfaces in %{csp_string} with full support for hotplug. +%if 0%{?sle_version} > 150100 %package -n %{base_name}-nm Summary: Network configuration scripts for %{csp_string} Group: System/Management @@ -92,6 +100,7 @@ %description -n %{base_name}-nm Dispatch script for NetworkManager that automatically runs cloud-netconfig. +%endif %prep %setup -q -n %{base_name}-%{version} @@ -116,11 +125,19 @@ ln -s /dev/null %{buildroot}/%{_sysconfdir}/udev/rules.d/75-persistent-net-generator.rules %endif +# install link to cleanup script in /etc/sysconfig/network/scripts to wicked +# will find it +mkdir -p %{buildroot}/%{_sysconfdir}/sysconfig/network/scripts +ln -s %{_scriptdir}/cloud-netconfig-cleanup %{buildroot}/%{_sysconfdir}/sysconfig/network/scripts/cloud-netconfig-cleanup + +%if 0%{?sle_version} <= 150100 +rm -r %{buildroot}/usr/lib/NetworkManager +%endif %files -n %{base_name}%{flavor_suffix} %defattr(-,root,root) %{_scriptdir} -%if %{defined no_config} +%if %{defined no_dist_conf} %config(noreplace) %{_distconfdir}/default/cloud-netconfig %else %{_distconfdir}/default/cloud-netconfig @@ -134,8 +151,10 @@ %doc README.md %license LICENSE +%if 0%{?sle_version} > 150100 %files -n %{base_name}-nm /usr/lib/NetworkManager/dispatcher.d +%endif %pre %service_add_pre %{base_name}.service %{base_name}.timer diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.7/cloud-netconfig.spec.orig new/cloud-netconfig-1.8/cloud-netconfig.spec.orig --- old/cloud-netconfig-1.7/cloud-netconfig.spec.orig 1970-01-01 01:00:00.000000000 +0100 +++ new/cloud-netconfig-1.8/cloud-netconfig.spec.orig 2022-12-16 16:29:26.532492397 +0100 @@ -0,0 +1,152 @@ +# +# spec file for package cloud-netconfig +# +# Copyright (c) 2017 SUSE Linux GmbH, Nuernberg, Germany. +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# + +%define base_name cloud-netconfig + +%if "@BUILD_FLAVOR@" == "" +%define flavor_suffix %nil +%define csp_string None +ExclusiveArch: do-not-build +%endif +%if "@BUILD_FLAVOR@" == "azure" +%define flavor_suffix -azure +%define csp_string Microsoft Azure +%endif +%if "@BUILD_FLAVOR@" == "ec2" +%define flavor_suffix -ec2 +%define csp_string Amazon EC2 +%endif +%if "@BUILD_FLAVOR@" == "gce" +%define flavor_suffix -gce +%define csp_string Google Compute Engine +%endif + +%if ! %{defined _distconfdir} +%define _distconfdir %{_sysconfdir} +%define no_dist_conf 1 +%endif + +Name: %{base_name}%{flavor_suffix} +Version: 1.7 +Release: 0 +License: GPL-3.0-or-later +Summary: Network configuration scripts for %{csp_string} +Url: https://github.com/SUSE-Enceladus/cloud-netconfig +Group: System/Management +Source0: %{base_name}-%{version}.tar.bz2 +BuildRoot: %{_tmppath}/%{name}-%{version}-build +BuildArch: noarch +%if 0%{?suse_version} == 1110 +BuildRequires: sysconfig +Requires: sysconfig +%define _udevrulesdir %{_sysconfdir}/udev/rules.d +%else +BuildRequires: sysconfig-netconfig +Requires: sysconfig-netconfig +%endif +BuildRequires: pkgconfig(udev) +BuildRequires: NetworkManager +Requires: udev +Requires: curl +%if 0%{?sles_version} == 11 +# RPM in SLES 11 does not support self conflict, use otherproviders() +# workaround +Provides: cloud-netconfig +Conflicts: otherproviders(cloud-netconfig) +%else +Provides: cloud-netconfig +Conflicts: cloud-netconfig +%endif +%{?systemd_requires} +%define _scriptdir %{_libexecdir}/cloud-netconfig +%if 0%{?suse_version} > 1550 +%define _netconfigdir %{_libexecdir}/netconfig.d +%else +%define _netconfigdir %{_sysconfdir}/netconfig.d +%endif + + +%description -n %{base_name}%{flavor_suffix} +This package contains scripts for automatically configuring network interfaces +in %{csp_string} with full support for hotplug. + +%package -n %{base_name}-nm +Summary: Network configuration scripts for %{csp_string} +Group: System/Management +Requires: cloud-netconfig +Requires: NetworkManager + +%description -n %{base_name}-nm +Dispatch script for NetworkManager that automatically runs cloud-netconfig. + +%prep +%setup -q -n %{base_name}-%{version} + +%build + +%install +make install%{flavor_suffix} \ + DESTDIR=%{buildroot} \ + PREFIX=%{_usr} \ + SYSCONFDIR=%{_sysconfdir} \ + DISTCONFDIR=%{_distconfdir} \ + SCRIPTDIR=%{_scriptdir} \ + UDEVRULESDIR=%{_udevrulesdir} \ + UNITDIR=%{_unitdir} \ + NETCONFIGDIR=%{_netconfigdir} + +# Disable persistent net generator from udev-persistent-ifnames as +# it does not work for xen interfaces. This will likely produce a warning. +%if 0%{?suse_version} >= 1315 +mkdir -p %{buildroot}/%{_sysconfdir}/udev/rules.d +ln -s /dev/null %{buildroot}/%{_sysconfdir}/udev/rules.d/75-persistent-net-generator.rules +%endif + + +%files -n %{base_name}%{flavor_suffix} +%defattr(-,root,root) +%{_scriptdir} +%if %{defined no_config} +%config(noreplace) %{_distconfdir}/default/cloud-netconfig +%else +%{_distconfdir}/default/cloud-netconfig +%endif +%{_netconfigdir} +%if 0%{?suse_version} >= 1315 +%{_sysconfdir}/udev/rules.d +%endif +%{_udevrulesdir}/* +%{_unitdir}/* +%doc README.md +%license LICENSE + +%files -n %{base_name}-nm +/usr/lib/NetworkManager/dispatcher.d + +%pre +%service_add_pre %{base_name}.service %{base_name}.timer + +%post +%service_add_post %{base_name}.service %{base_name}.timer + +%preun +%service_del_preun %{base_name}.service %{base_name}.timer + +%postun +%service_del_postun %{base_name}.service %{base_name}.timer + +%changelog diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.7/cloud-netconfig.spec.tmp new/cloud-netconfig-1.8/cloud-netconfig.spec.tmp --- old/cloud-netconfig-1.7/cloud-netconfig.spec.tmp 1970-01-01 01:00:00.000000000 +0100 +++ new/cloud-netconfig-1.8/cloud-netconfig.spec.tmp 2023-08-29 14:45:09.956788435 +0200 @@ -0,0 +1,146 @@ +# +# spec file for package cloud-netconfig +# +# Copyright (c) 2017 SUSE Linux GmbH, Nuernberg, Germany. +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# + +%define base_name cloud-netconfig + +%if "@BUILD_FLAVOR@" == "" +%define flavor_suffix %nil +%define csp_string None +ExclusiveArch: do-not-build +%endif +%if "@BUILD_FLAVOR@" == "azure" +%define flavor_suffix -azure +%define csp_string Microsoft Azure +%endif +%if "@BUILD_FLAVOR@" == "ec2" +%define flavor_suffix -ec2 +%define csp_string Amazon EC2 +%endif +%if "@BUILD_FLAVOR@" == "gce" +%define flavor_suffix -gce +%define csp_string Google Compute Engine +%endif + +<<<<<<< Updated upstream +======= +%if ! %{defined _distconfdir} +%define _distconfdir %{_sysconfdir} +%endif + +>>>>>>> Stashed changes +Name: %{base_name}%{flavor_suffix} +Version: 1.6 +Release: 0 +License: GPL-3.0-or-later +Summary: Network configuration scripts for %{csp_string} +Url: https://github.com/SUSE-Enceladus/cloud-netconfig +Group: System/Management +Source0: %{base_name}-%{version}.tar.bz2 +BuildRoot: %{_tmppath}/%{name}-%{version}-build +BuildArch: noarch +%if 0%{?suse_version} == 1110 +BuildRequires: sysconfig +Requires: sysconfig +%define _udevrulesdir %{_sysconfdir}/udev/rules.d +%else +BuildRequires: sysconfig-netconfig +Requires: sysconfig-netconfig +%endif +BuildRequires: pkgconfig(udev) +Requires: udev +Requires: curl +%if 0%{?sles_version} == 11 +# RPM in SLES 11 does not support self conflict, use otherproviders() +# workaround +Provides: cloud-netconfig +Conflicts: otherproviders(cloud-netconfig) +%else +Provides: cloud-netconfig +Conflicts: cloud-netconfig +%endif +%{?systemd_requires} + +%description -n %{base_name}%{flavor_suffix} +This package contains scripts for automatically configuring network interfaces +in %{csp_string} with full support for hotplug. + +%prep +%setup -q -n %{base_name}-%{version} + +%build + +%install +make install%{flavor_suffix} \ + DESTDIR=%{buildroot} \ + PREFIX=%{_usr} \ + SYSCONFDIR=%{_sysconfdir} \ + LIBEXECDIR=%{_libexecdir} \ + UDEVRULESDIR=%{_udevrulesdir} \ + UNITDIR=%{_unitdir} + +# Disable persistent net generator from udev-persistent-ifnames as +# it does not work for xen interfaces. This will likely produce a warning. +%if 0%{?suse_version} >= 1315 +mkdir -p %{buildroot}/%{_sysconfdir}/udev/rules.d +ln -s /dev/null %{buildroot}/%{_sysconfdir}/udev/rules.d/75-persistent-net-generator.rules +%endif + +<<<<<<< Updated upstream +%files -n %{base_name}%{flavor_suffix} +%defattr(-,root,root) +%dir %{_libexecdir}/netconfig +%dir %{_libexecdir}/netconfig/scripts +%dir %{_libexecdir}/netconfig/netconfig.d +%{_libexecdir}/netconfig/scripts/* +%{_libexecdir}/netconfig/netconfig.d/cloud-netconfig +%config(noreplace) %{_sysconfdir}/default/cloud-netconfig +======= +mkdir -p %{buildroot}/%{_sysconfdir}/sysconfig/network/scripts +ln -s %{_scriptdir}/cloud-netconfig-cleanup %{buildroot}/%{_sysconfdir}/sysconfig/network/scripts/cloud-netconfig-cleanup + +%if 0%{?sle_version} <= 150100 +rm -r %{buildroot}/usr/lib/NetworkManager +%endif + +%files -n %{base_name}%{flavor_suffix} +%defattr(-,root,root) +%{_scriptdir} +%{_sysconfdir}/sysconfig/network/scripts/cloud-netconfig-cleanup +%config(noreplace) %{_distconfdir}/default/cloud-netconfig +%{_netconfigdir} +>>>>>>> Stashed changes +%if 0%{?suse_version} >= 1315 +%{_sysconfdir}/udev/rules.d +%endif +%{_udevrulesdir}/* +%{_unitdir}/* +%doc README.md +%license LICENSE + +%pre +%service_add_pre %{base_name}.service %{base_name}.timer + +%post +%service_add_post %{base_name}.service %{base_name}.timer + +%preun +%service_del_preun %{base_name}.service %{base_name}.timer + +%postun +%service_del_postun %{base_name}.service %{base_name}.timer + +%changelog diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.7/common/cloud-netconfig.tmp new/cloud-netconfig-1.8/common/cloud-netconfig.tmp --- old/cloud-netconfig-1.7/common/cloud-netconfig.tmp 1970-01-01 01:00:00.000000000 +0100 +++ new/cloud-netconfig-1.8/common/cloud-netconfig.tmp 2023-08-29 14:48:10.739844114 +0200 @@ -0,0 +1,480 @@ +#!/bin/bash + +# Copyright (c) 2017 SUSE Linux GmbH +# +# This file is part of cloud-netconfig. +# +# cloud-netconfig 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. +# +# cloud-netconfig 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 cloud-netconfig. If not, see <http://www.gnu.org/licenses/ + +PROGNAME="cloud-netconfig" +# The environment variable ROOT indicates the root of the system to be +# managed by SuSEconfig when that root is not '/' +r="$ROOT" + +. "$r/usr/libexec/netconfig/scripts/functions.netconfig" +# for get_ipv4_addresses_from_metadata() +. "$r/usr/libexec/netconfig/scripts/functions.cloud-netconfig" + +STATEDIR=/var/run/netconfig +ADDRDIR=/var/run/netconfig/cloud + +# ------------------------------------------------------------------- +# return all IPv4 addresses currently configured on given interface +# +get_ipv4_addresses_from_interface() +{ + local idx type addr iface="$1" + test -z "$iface" && return 1 + ip -o -4 addr show dev $iface | while read -r idx iface_r type addr rest ; do + echo -n "${addr} " + done +} + +# ------------------------------------------------------------------- +# return all IPv6 addresses currently configured on given interface +# +get_ipv6_addresses_from_interface() +{ + local idx iface_r scope_lit scope type addr rest iface="$1" + test -z "$iface" && return 1 + ip -o -6 addr show dev $iface | \ + while read -r idx iface_r type addr scope_lit scope rest ; do + # skip anything that is not scope global + if [[ "$scope" == "global" ]]; then + echo -n "${addr} " + fi + done +} + +# ------------------------------------------------------------------- +# compare arrays and return the ones that are in the first but not +# the second +# +get_extra_elements() +{ + local actual=(${!1}) target=(${!2}) + local elem_a elem_t + for elem_a in ${actual[@]} ; do + found=0 + for elem_t in ${target[@]} ; do + if [ "$elem_a" == "$elem_t" ]; then + found=1 + break + fi + done + test $found = 0 && echo -n "$elem_a " + done +} + +# ------------------------------------------------------------------- +# check wether $2 is an element of array $1 +# +is_element() +{ + local array=(${!1}) item=${2} + local elem + for elem in ${array[@]} ; do + if [[ $elem == $item ]]; then + return 0 + fi + done + return 1 +} + +# ------------------------------------------------------------------- +# look up a free priority with a given prefix from the rule table +# +get_free_priority() +{ + local prefix="$1" + test -z "$prefix" && return 1 + + local IPV + [[ -n "$2" ]] && IPV="-${2}" + + local prio=$((prefix*100)) + local taken + while [[ $prio -lt $((prefix*100+100)) ]]; do + taken=0 + while read -r no rest ; do + if [[ "${prio}" == "${no%%:}" ]]; then + taken=1 + break + fi + done < <(ip $IPV rule show) + if [[ $taken == 0 ]]; then + echo -n "${prio}" + return + fi + prio=$((prio+1)) + done + warn "No free priority for prefix $prefix" + echo -n "29999" +} + +# ------------------------------------------------------------------- +# get IPv4 addresses from log dir +# +get_cn_assigned_addrs() +{ + local iface="$1" + test -z "$iface" && return 1 + + if [[ -e ${ADDRDIR}/${iface} ]]; then + echo $(cat ${ADDRDIR}/${iface}) + fi +} + +# ------------------------------------------------------------------- +# get link status for interface +# +get_link_status() +{ + local iface="$1" + test -z "$iface" && return 1 + + ip -o -br link show dev $iface | awk '{ print $2 }' +} + +# ------------------------------------------------------------------- +# add address to log +# +add_addr_to_log() +{ + local iface="$1" + local addr="$2" + + test -z "$iface" -o -z "$addr" && return 1 + addr_log_file="${ADDRDIR}/${iface}" + if [[ -e ${addr_log_file} ]]; then + grep -q -x "${addr}" "${addr_log_file}" || echo "${addr}" >> "${addr_log_file}" + else + mkdir -p "${ADDRDIR}" + echo "${addr}" > "${addr_log_file}" + fi +} + +# ------------------------------------------------------------------- +# remove address from log +# +remove_addr_from_log() +{ + local iface="$1" + local addr="$2" + + test -z "$iface" -o -z "$addr" && return 1 + addr_log_file="${ADDRDIR}/${iface}" + if [[ -e ${addr_log_file} ]]; then + addr_log_file_tmp=$(mktemp ${ADDRDIR}/${iface}.XXXXXXXX) + if [ $? -ne 0 ]; then + log "could not create temp file, not removing address from log" + else + grep -v -x "${addr}" "${addr_log_file}" >> "${addr_log_file_tmp}" + mv "${addr_log_file_tmp}" "${addr_log_file}" + fi + fi +} + +# ------------------------------------------------------------------- +# copy routes from default table to given table and remove routes +# that do not exist in default table (if any) +# +update_routing_table() +{ + local rtable="$1" + local iface="$2" + + test -z "$rtable" && return 1 + + # copy routes from default table + for ipv in "-4" "-6" ; do + ip $ipv route show | grep -v "^default" | while read route ; do + ip $ipv route replace $route table $rtable + done + + # Do a second run with routes specific to the interface being configured. + # This makes sure that in case there are competing routes (same destination + # but different device), the one matching the right interface is selected. + # This situation can happen in case there are multiple interfaces that are + # connected to the same subnet. + ip $ipv route show dev "$iface" | grep -v "^default" | while read route ; do + ip $ipv route replace $route dev "$iface" table $rtable + done + + # check if there are any leftover routes and delete them + ip $ipv route show all table $rtable | grep -v "^default" | while read route ; do + ip_out="$(ip $ipv route show $route)" + test -z "$ip_out" && ip $ipv route del $route table $rtable + done + done +} + +# ------------------------------------------------------------------- +# configure interface with secondary IPv4 addresses configured in the +# cloud framework and set up routing policies +# +configure_interface_ipv4() +{ + local cfg="$1" + test -z "$cfg" -o ! -f "$cfg" && return 1 + local INTERFACE IPADDR NETWORK NETMASK BROADCAST GATEWAYS + get_variable "INTERFACE" "$cfg" + get_variable "IPADDR" "$cfg" + get_variable "NETWORK" "$cfg" + get_variable "NETMASK" "$cfg" + get_variable "BROADCAST" "$cfg" + get_variable "GATEWAYS" "$cfg" + get_variable "PREFIXLEN" "$cfg" + get_variable "ROUTES" "$cfg" + local HWADDR="$(cat /sys/class/net/${INTERFACE}/address)" + local RTABLE="10${INTERFACE: -1}" + + # get active and configured addresses + local laddrs=($(get_ipv4_addresses_from_interface $INTERFACE)) + local raddrs=($(get_ipv4_addresses_from_metadata $HWADDR)) + + # get differences + local addr_to_remove=($(get_extra_elements laddrs[@] raddrs[@])) + local addr_to_add=($(get_extra_elements raddrs[@] laddrs[@])) + + # get addresses cloud-netconfig configured + local addr_cn=($(get_cn_assigned_addrs $INTERFACE)) + + debug "active IPv4 addresses on $INTERFACE: ${laddrs[@]}" + debug "configured IPv4 addresses for $INTERFACE: ${raddrs[@]}" + debug "excess addresses on $INTERFACE: ${addr_to_remove[@]}" + debug "addresses to configure on $INTERFACE: ${addr_to_add[@]}" + + local addr priority + for addr in ${addr_to_remove[@]} ; do + # as a safety measure, check against the address received via DHCP and + # refuse to remove it even if it is not in the meta data + if [[ "${addr%/*}" == "${IPADDR%/*}" ]]; then + debug "not removing DHCP IP address from interface" + continue + fi + + if is_element addr_cn[@] ${addr} ; then + # remove old IP address + log "removing address $addr from interface $INTERFACE" + ip -4 addr del $addr dev $INTERFACE + + # drop routing policy rule + ip -4 rule del from ${addr%/*} + + # remove from address log + remove_addr_from_log $INTERFACE $addr + else + debug "not removing address ${addr} (was not added by cloud-netconfig)" + fi + done + for addr in ${addr_to_add[@]} ; do + # add new IP address + log "adding address $addr to interface $INTERFACE" + ip -4 addr add $addr broadcast $BROADCAST dev $INTERFACE + add_addr_to_log $INTERFACE $addr + done + + # If we have a single NIC configuration, skip routing policies + if [[ $SINGLE_NIC = yes ]]; then + return + fi + + # To make a working default route for secondary interfaces, we + # need a separate route table so we can send packets there + # using routing policy. Check whether the table is there and + # create it if not. + if [ -z "$(ip -4 route show default dev $INTERFACE table $RTABLE)" ]; then + local GW GWS=() + # we simply take the first gateway in case there is more than one + eval GWS=\(${GATEWAYS}\) + if [[ -n "${GWS[0]}" ]]; then + GW="${GWS[0]}" + else + debug "No gateway from DHCP4, guessing" + # no default route, guess one + if [[ $PREFIXLEN = 32 ]]; then + # peer-to-peer setup but no gateway. At the time of writing + # that is the setup in GCE. Subnet routes and gateway get + # delivered by DHCP as addtional routes. + for r in $ROUTES ; do + if [[ ${r##*,} = 0.0.0.0 ]]; then + GW="${r%%,*}" + break + fi + done + else + # we assume the gateway is the first host of the network + local netstart=${NETWORK##*.} + local gw_host_part=$((netstart+1)) + GW="${NETWORK%.*}.${gw_host_part}" + fi + fi + if [[ -n $GW ]]; then + debug "adding default route via $GW for $INTERFACE table $RTABLE" + ip -4 route add default via $GW dev "$INTERFACE" table "$RTABLE" + else + warn "No default route for $INTERFACE" + fi + fi + + # copy specific routes from the default routing table + update_routing_table $RTABLE $INTERFACE + + # update routing policies so connections from addresses on + # secondary interfaces are routed via those + local found prio from ip rest + for addr in ${raddrs[@]} ; do + found=0 + while read -r prio from ip rest ; do + if [[ "${addr%/*}" == "$ip" ]]; then + found=1 + break + fi + done < <(ip -4 rule show) + if [[ $found == 0 ]]; then + priority=$(get_free_priority $RTABLE 4) + ip -4 rule add from ${addr%/*} priority $priority table $RTABLE + fi + done +} + +# ------------------------------------------------------------------- +# set up IPv6 routing policies +# +configure_interface_ipv6() +{ + local cfg="$1" + test -z "$cfg" -o ! -f "$cfg" && return 1 + get_variable "INTERFACE" "$cfg" + + # NOTE: unlike with IPv4, we set up routing policies even for the primary + # interface. Default routes for IPv6 will likely have the same metric, so + # unlike with the IPv4 routes, where we use higher metrics for the non + # primary interfaces, we may run into the situation where the kernel picks + # the default route of a non primary interface as the main default. Using + # routing policies prevents that, but it means there will be a routing + # policy even if you do not have a secondary interface at all (not a + # problem, just not as nice as it could be). + + local RTABLE="10${INTERFACE: -1}" + + # if necessary, create route table with default route for interface + if [ -z "$(ip -6 route show default dev $INTERFACE table $RTABLE)" ]; then + # it is possible that we received the DHCP response before the + # the router advertisement; in that case, we wait up to 10 secs + local route via GW rest counter=0 + while [[ $counter -lt 10 ]]; do + counter=$((counter+1)) + read -r route via GW rest < <(ip -6 route show default dev $INTERFACE) + if [[ -n "$GW" ]]; then + break + else + sleep 1 + fi + done + if [[ -z "$GW" ]]; then + warn "no IPv6 default route available for $INTERFACE" + return + fi + ip -6 route add default via $GW dev $INTERFACE table $RTABLE + fi + + local addr laddrs=($(get_ipv6_addresses_from_interface $INTERFACE)) + local found prio from ip rest + for addr in ${laddrs[@]} ; do + found=0 + while read -r prio from ip rest ; do + if [[ "${addr%/*}" == "$ip" ]]; then + found=1 + break + fi + done < <(ip -6 rule show) + if [[ $found == 0 ]]; then + priority=$(get_free_priority $RTABLE 6) + ip -6 rule add from ${addr%/*} priority $priority table $RTABLE + fi + done +} + +# ------------------------------------------------------------------- +# check if interface is configured to be managed by cloud-netconfig +# and whether it is DHCP configured; if yes, apply settings from +# the cloud framework +# +manage_interfaceconfig() +{ + local cfg="$1" + test -z "$cfg" -o ! -d "$cfg" && return 1 + local ifcfg="/etc/sysconfig/network/ifcfg-${cfg##*/}" + local CLOUD_NETCONFIG_MANAGE + if [ "$netsys" == "wicked" ]; then + local ifcfg="/etc/sysconfig/network/ifcfg-${iface}" + if [[ -f "${ifcfg}" ]]; then + get_variable "CLOUD_NETCONFIG_MANAGE" "${ifcfg}" + fi + elif [ "$netsys" == "NetworkManager" ]; then + test -e /usr/etc/default/cloud-netconfig && \ + get_variable "CLOUD_NETCONFIG_MANAGE" /usr/etc/default/cloud-netconfig + test -e /etc/default/cloud-netconfig && \ + get_variable "CLOUD_NETCONFIG_MANAGE" /etc/default/cloud-netconfig + else + debug "Unknown network service $netsys. Not handling interface configuration." + return + fi + if [[ "$CLOUD_NETCONFIG_MANAGE" != "yes" ]]; then + # do not touch interface + debug "Not managing interface ${cfg##*/}" + return + fi + linkstatus=$(get_link_status ${cfg##*/}) + if [[ $linkstatus != UP ]]; then + debug "interface ${cfg##*/} is down" + return + fi + if ! metadata_available ; then + warn "Cannot access instance metadata, skipping interface configuration for ${cfg##*/}" + return + fi + for cfg in ${1}/* ; do + test -f $cfg || continue + get_variable "SERVICE" "$cfg" + case "$SERVICE" in + "wicked-dhcp-ipv4"|"dhcpcd") + configure_interface_ipv4 "$cfg" + ;; + "wicked-dhcp-ipv6"|"dhcp6c") + configure_interface_ipv6 "$cfg" + ;; + esac + done +} + +if_dirs=() +for IFDIR in $STATEDIR/* ; do + test -d $IFDIR -a -d "/sys/class/net/${IFDIR##*/}" || continue + test ${IFDIR##*/} = "lo" && continue + if_dirs+=($IFDIR) +done + +# set single NIC flag if appropriate +if [[ ${#if_dirs[@]} -eq 1 ]]; then + SINGLE_NIC=yes +else + SINGLE_NIC=no +fi + +for IFDIR in ${if_dirs[@]} ; do + manage_interfaceconfig $IFDIR +done