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-01-09 17:24:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cloud-netconfig (Old)
and /work/SRC/openSUSE:Factory/.cloud-netconfig.new.32243 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cloud-netconfig"
Mon Jan 9 17:24:14 2023 rev:14 rq:1057067 version:1.7
Changes:
--------
--- /work/SRC/openSUSE:Factory/cloud-netconfig/cloud-netconfig.changes
2022-10-06 07:42:38.276745257 +0200
+++
/work/SRC/openSUSE:Factory/.cloud-netconfig.new.32243/cloud-netconfig.changes
2023-01-09 17:24:17.951327063 +0100
@@ -1,0 +2,13 @@
+Fri Dec 16 14:32:31 UTC 2022 - Joachim Gleissner <[email protected]>
+
+- Update to version 1.7:
+ + Overhaul policy routing setup (issue #19)
+ + Support alias IPv4 ranges (issue #14)
+ + Add support for NetworkManager (bsc#1204549)
+ + Remove dependency on netconfig
+ + Install into libexec directory
+ + Clear stale ifcfg files for accelerated NICs (bsc#1199853)
+ + More debug messages
+ + Documentation update
+
+-------------------------------------------------------------------
Old:
----
cloud-netconfig-1.6.tar.bz2
New:
----
cloud-netconfig-1.7.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ cloud-netconfig.spec ++++++
--- /var/tmp/diff_new_pack.W2Kt76/_old 2023-01-09 17:24:18.623330866 +0100
+++ /var/tmp/diff_new_pack.W2Kt76/_new 2023-01-09 17:24:18.627330889 +0100
@@ -1,7 +1,7 @@
#
# spec file
#
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -36,13 +36,18 @@
%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.6
+Version: 1.7
Release: 0
-Summary: Network configuration scripts for %{csp_string}
License: GPL-3.0-or-later
-Group: System/Management
+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
@@ -55,6 +60,9 @@
Requires: sysconfig-netconfig
%endif
BuildRequires: pkgconfig(udev)
+%if 0%{?sle_version} > 150100
+BuildRequires: NetworkManager
+%endif
Requires: curl
Requires: udev
%if 0%{?sles_version} == 11
@@ -67,11 +75,28 @@
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.
+%if 0%{?sle_version} > 150100
+%package -n %{base_name}-nm
+Summary: Network configuration scripts for %{csp_string}
+Group: System/Management
+Requires: NetworkManager
+Requires: cloud-netconfig
+
+%description -n %{base_name}-nm
+Dispatch script for NetworkManager that automatically runs cloud-netconfig.
+%endif
+
%prep
%setup -q -n %{base_name}-%{version}
@@ -82,11 +107,11 @@
DESTDIR=%{buildroot} \
PREFIX=%{_usr} \
SYSCONFDIR=%{_sysconfdir} \
+ DISTCONFDIR=%{_distconfdir} \
+ SCRIPTDIR=%{_scriptdir} \
UDEVRULESDIR=%{_udevrulesdir} \
- %if 0%{?suse_version} > 1550
- NETCONFDIR=%{_libexecdir}/netconfig/netconfig.d \
- %endif
- UNITDIR=%{_unitdir}
+ 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.
@@ -95,15 +120,19 @@
ln -s /dev/null
%{buildroot}/%{_sysconfdir}/udev/rules.d/75-persistent-net-generator.rules
%endif
+%if 0%{?sle_version} <= 150100
+rm -r %{buildroot}/usr/lib/NetworkManager
+%endif
+
%files -n %{base_name}%{flavor_suffix}
%defattr(-,root,root)
-%config(noreplace) %{_sysconfdir}/default/cloud-netconfig
-%if 0%{?suse_version} > 1550
-%{_libexecdir}/netconfig/netconfig.d/cloud-netconfig
+%{_scriptdir}
+%if %{defined no_config}
+%config(noreplace) %{_distconfdir}/default/cloud-netconfig
%else
-%{_sysconfdir}/netconfig.d/cloud-netconfig
+%{_distconfdir}/default/cloud-netconfig
%endif
-%{_sysconfdir}/sysconfig/network/scripts/*
+%{_netconfigdir}
%if 0%{?suse_version} >= 1315
%{_sysconfdir}/udev/rules.d
%endif
@@ -112,6 +141,11 @@
%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
++++++ cloud-netconfig-1.6.tar.bz2 -> cloud-netconfig-1.7.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloud-netconfig-1.6/Makefile
new/cloud-netconfig-1.7/Makefile
--- old/cloud-netconfig-1.6/Makefile 2020-11-04 17:34:18.857419551 +0100
+++ new/cloud-netconfig-1.7/Makefile 2022-12-16 15:29:58.365590361 +0100
@@ -1,21 +1,26 @@
.PHONY: common help install-azure install-ec2
PREFIX?=/usr
SYSCONFDIR?=/etc
+DISTCONFDIR?=/usr/etc
+LIBEXECDIR?=/usr/libexec
UDEVRULESDIR?=$(PREFIX)/lib/udev/rules.d
-NETCONFDIR?=$(SYSCONFDIR)/netconfig.d
-SCRIPTDIR?=$(SYSCONFDIR)/sysconfig/network/scripts
+SCRIPTDIR?=$(LIBEXECDIR)/cloud-netconfig
UNITDIR?=$(PREFIX)/lib/systemd/system
-DEFAULTDIR?=$(SYSCONFDIR)/default
+DEFAULTDIR?=$(DISTCONFDIR)/default
+NETCONFIGDIR?=$(SYSCONFDIR)/netconfig.d
+NMDISPATCHDIR?=/usr/lib/NetworkManager/dispatcher.d
DESTDIR?=
-DEST_NETCONFDIR=$(DESTDIR)$(NETCONFDIR)
DEST_UDEVRULESDIR=$(DESTDIR)$(UDEVRULESDIR)
DEST_SCRIPTDIR=$(DESTDIR)$(SCRIPTDIR)
DEST_UNITDIR=$(DESTDIR)$(UNITDIR)
DEST_DEFAULTDIR=$(DESTDIR)$(DEFAULTDIR)
+DEST_NETCONFIGDIR=$(DESTDIR)$(NETCONFIGDIR)
+DEST_NMDISPATCHDIR=$(DESTDIR)$(NMDISPATCHDIR)
+NM_DISPATCH_SCRIPT=90-cloud-netconfig
verSrc = $(shell cat VERSION)
-verSpec = $(shell rpm -q --specfile --qf '%{VERSION}' cloud-netconfig.spec
2>/dev/null)
+verSpec = $(shell sed -n -r -e '/^Version:/ s/(Version: *)([^ ]+)/\2/p'
cloud-netconfig.spec)
ifneq "$(verSrc)" "$(verSpec)"
$(error "Version mismatch source and spec, aborting")
@@ -24,34 +29,48 @@
help:
@echo "Type 'make install-ec2' for installation on EC2"
@echo "Type 'make install-azure' for installation on Azure"
+ @echo "Type 'make install-gce' for installation on GCE"
@echo "Use var DESTDIR for installing into a different root."
common:
- mkdir -p $(DEST_NETCONFDIR)
- mkdir -p $(DEST_UDEVRULESDIR)
- mkdir -p $(DEST_SCRIPTDIR)
- mkdir -p $(DEST_UNITDIR)
- mkdir -p $(DEST_DEFAULTDIR)
- install -m 755 common/cloud-netconfig $(DEST_NETCONFDIR)
- install -m 755 common/cloud-netconfig-cleanup $(DEST_SCRIPTDIR)
- install -m 644 common/cloud-netconfig-default
$(DEST_DEFAULTDIR)/cloud-netconfig
- install -m 755 common/cloud-netconfig-hotplug $(DEST_SCRIPTDIR)
- install -m 644 systemd/cloud-netconfig.service $(DEST_UNITDIR)
- install -m 644 systemd/cloud-netconfig.timer $(DEST_UNITDIR)
+ mkdir -p $(DESTDIR)$(UDEVRULESDIR)
+ mkdir -p $(DESTDIR)$(SCRIPTDIR)
+ mkdir -p $(DESTDIR)$(UNITDIR)
+ mkdir -p $(DESTDIR)$(DEFAULTDIR)
+ mkdir -p $(DESTDIR)$(NETCONFIGDIR)
+ mkdir -p $(DESTDIR)$(NMDISPATCHDIR)
+ install -m 755 common/cloud-netconfig $(DESTDIR)$(SCRIPTDIR)
+ install -m 755 common/cloud-netconfig-cleanup $(DESTDIR)$(SCRIPTDIR)
+ install -m 644 common/cloud-netconfig-default
$(DESTDIR)$(DEFAULTDIR)/cloud-netconfig
+ install -m 755 common/cloud-netconfig-hotplug $(DESTDIR)$(SCRIPTDIR)
+ install -m 755 common/cloud-netconfig-wrapper
$(DESTDIR)$(NETCONFIGDIR)/cloud-netconfig
+ install -m 755 common/cloud-netconfig-nm
$(DESTDIR)$(NMDISPATCHDIR)/$(NM_DISPATCH_SCRIPT)
+ install -m 644 systemd/cloud-netconfig.service $(DESTDIR)$(UNITDIR)
+ install -m 644 systemd/cloud-netconfig.timer $(DESTDIR)$(UNITDIR)
+ sed -i -r -e "s;SCRIPTDIR=.*;SCRIPTDIR=${SCRIPTDIR};g"
$(DESTDIR)$(SCRIPTDIR)/cloud-netconfig
+ sed -i -r -e "s;SCRIPTDIR=.*;SCRIPTDIR=${SCRIPTDIR};g"
$(DESTDIR)$(SCRIPTDIR)/cloud-netconfig-hotplug
+ sed -i -r -e "s;DISTCONFDIR=.*;DISTCONFDIR=${DISTCONFDIR};g"
$(DESTDIR)$(SCRIPTDIR)/cloud-netconfig-hotplug
+ sed -i -r -e "s;SCRIPTDIR=.*;SCRIPTDIR=${SCRIPTDIR};g"
$(DESTDIR)$(NETCONFIGDIR)/cloud-netconfig
+ sed -i -r -e "s;SCRIPTDIR=.*;SCRIPTDIR=${SCRIPTDIR};g"
$(DESTDIR)$(NMDISPATCHDIR)/$(NM_DISPATCH_SCRIPT)
+ sed -i -r -e "s;%SCRIPTDIR%;${SCRIPTDIR};g"
$(DESTDIR)$(UNITDIR)/cloud-netconfig.service
install-azure: common
- install -m 644 azure/61-cloud-netconfig-hotplug.rules
$(DEST_UDEVRULESDIR)
- install -m 755 azure/functions.cloud-netconfig $(DEST_SCRIPTDIR)
+ install -m 644 azure/61-cloud-netconfig-hotplug.rules
$(DESTDIR)$(UDEVRULESDIR)
+ install -m 755 azure/functions.cloud-netconfig $(DESTDIR)$(SCRIPTDIR)
+ install -m 755 azure/cleanup-stale-ifcfg $(DESTDIR)$(SCRIPTDIR)
+ sed -i -e "s;%SCRIPTDIR%;${SCRIPTDIR};g"
$(DESTDIR)$(UDEVRULESDIR)/*hotplug.rules
install-ec2: common
- install -m 644 common/75-cloud-persistent-net-generator.rules
$(DEST_UDEVRULESDIR)
- install -m 644 ec2/51-cloud-netconfig-hotplug.rules $(DEST_UDEVRULESDIR)
- install -m 755 ec2/functions.cloud-netconfig $(DEST_SCRIPTDIR)
+ install -m 644 common/75-cloud-persistent-net-generator.rules
$(DESTDIR)$(UDEVRULESDIR)
+ install -m 644 ec2/51-cloud-netconfig-hotplug.rules
$(DESTDIR)$(UDEVRULESDIR)
+ install -m 755 ec2/functions.cloud-netconfig $(DESTDIR)$(SCRIPTDIR)
+ sed -i -e "s;%SCRIPTDIR%;${SCRIPTDIR};g"
$(DESTDIR)$(UDEVRULESDIR)/*hotplug.rules
install-gce: common
- install -m 644 common/75-cloud-persistent-net-generator.rules
$(DEST_UDEVRULESDIR)
- install -m 644 gce/51-cloud-netconfig-hotplug.rules $(DEST_UDEVRULESDIR)
- install -m 755 gce/functions.cloud-netconfig $(DEST_SCRIPTDIR)
+ install -m 644 common/75-cloud-persistent-net-generator.rules
$(DESTDIR)$(UDEVRULESDIR)
+ install -m 644 gce/51-cloud-netconfig-hotplug.rules
$(DESTDIR)$(UDEVRULESDIR)
+ install -m 755 gce/functions.cloud-netconfig $(DESTDIR)$(SCRIPTDIR)
+ sed -i -e "s;%SCRIPTDIR%;${SCRIPTDIR};g"
$(DESTDIR)$(UDEVRULESDIR)/*hotplug.rules
tarball:
@test -n "$(verSrc)"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloud-netconfig-1.6/README.html
new/cloud-netconfig-1.7/README.html
--- old/cloud-netconfig-1.6/README.html 2021-04-20 15:03:26.582059289 +0200
+++ new/cloud-netconfig-1.7/README.html 1970-01-01 01:00:00.000000000 +0100
@@ -1,65 +0,0 @@
-<h1>cloud-netconfig</h1>
-<p><strong>cloud-netconfig</strong> is a collection of scripts for
automatically configuring
-network interfaces in cloud frameworks. Currently supported are Amazon EC2,
-Microsoft Azure, and Google Compute Engine. It requires netconfig (package
-<strong>sysconfig-netconfig</strong> on openSUSE and SUSE Linux Enterprise
distributions).</p>
-<h3>Installation</h3>
-<p>If you are installing from source, run as root <code>make
install-ec2</code>, <code>make
-install-azure</code>, or <code>make install-gce</code> depending on your
platform. Then reload
-the udev rules by running <code>udevadm control -R</code>. Afterwards add
-<strong>cloud-netconfig</strong> to the variable
<strong>NETCONFIG__MODULES__ORDER</strong> in
-<code>/etc/sysconfig/network/config</code> and restart networking
(<code>systemctl restart
-wicked.serice</code> on SUSE Linux Enterprise Server or openSUSE
distributions). On
-EC2 and Azure you may want to enable the systemd timer too (see below for
-details on its purpose). To do that, run <code>systemctl enable --now
-cloud-netconfig.timer</code>.</p>
-<h3>Mode of Operation</h3>
-<p><strong>cloud-netconfig</strong> handles three different tasks:</p>
-<ul>
-<li>Set up unconfigured interfaces</li>
-</ul>
-<p>For any network interface that does not have an associated configuration
file
-in <code>/etc/sysconfig/network</code>, a DHCP based configuration will be
generated and
-<code>ifup</code> will be called, which triggers interface configuration
through <code>wicked</code>.</p>
-<ul>
-<li>Apply secondary IPv4 addresses</li>
-</ul>
-<p>For all interfaces managed by <strong>cloud-netconfig</strong>, it will
look up secondary
-IPv4 addresses from the framework's metadta server and configure them on the
-interface. This does not apply to Google Compute Engine, as secondary IPv4
-addresses are not assigned directly through the framework.</p>
-<ul>
-<li>Create routing policies</li>
-</ul>
-<p>In case the system has more than one network interface,
<strong>cloud-netconfig</strong>
-sets up routing in a way that packets are routed through the interface
-associated with the source address of the packet. To do that, it creates a
-separate routing table for each interface with a default route according to the
-interface configration. It also creates a routing policy to use that table for
-packets using any of the interface's source addresses. This ensures that
-packets are routed via the correct interface.</p>
-<p>Note: DHCP servers of cloud frameworks (this applies to Microsoft Azure at
the
-time of writing) may not include a gateway address in DHCP leases for secondary
-IPv4 addresses. This is presumably to avoid default routes to clash. To enable
-full connectivity in this case, <strong>cloud-netconfig</strong> assumes the
gateway host to
-be the first host of the sub-network assigned to the interface.</p>
-<p>Interface configurations will be checked periodically on each DHCP lease
-renewal and additionally, if the systemd timer is enabled (default on Amazon
-EC2 and Microsoft Azure SUSE Linux Enterprise Server images), every 60 seconds.
-<strong>cloud-netconfig</strong> detects changes in the metadata configuration
and updates
-interface configuration and routing policies accordingly. This means that IP
-addresses that were removed from the virtual interface configuration will be
-removed from the interface, but only addresses that were automatically added by
-<strong>cloud-netconfig</strong> will be removed. Addresses added manually by
the
-administrator or by another tool (e.g. high-availability software) will not be
-touched.</p>
-<h3>Configuration</h3>
-<p><strong>cloud-netconfig</strong> does not require any configuration, but it
should be noted
-that it will not overwrite existing interface configurations. This allows to
-use specific interface configurations. <strong>cloud-netconfig</strong> will
still set up
-secondary IP addresses and routing policies. If you do not want that, set the
-variable <strong>CLOUD__NETCONFIG__MANAGE</strong> to <strong>no</strong> in
the <code>ifcfg</code> file in
-<code>/etc/sysconfig/network</code> to disable it for the associated
interface. You can
-also change the default value of <strong>CLOUD__NETCONFIG__MANAGE</strong> for
in
-<code>/etc/default/cloud-netconfig</code>. The default applies to newly
created <code>ifcfg</code>
-files, not for existing ones.</p>
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloud-netconfig-1.6/README.md
new/cloud-netconfig-1.7/README.md
--- old/cloud-netconfig-1.6/README.md 2021-08-11 14:01:06.647719396 +0200
+++ new/cloud-netconfig-1.7/README.md 2022-12-16 15:29:58.369590436 +0100
@@ -20,7 +20,7 @@
### Mode of Operation
-**cloud-netconfig** handles three different tasks:
+**cloud-netconfig** handles the following tasks:
- Set up unconfigured interfaces
@@ -35,32 +35,46 @@
interface. This does not apply to Google Compute Engine, as secondary IPv4
addresses are not assigned directly through the framework.
+- Configure alias IPv4 ranges
+
+When running in Google Compute Engine or Amazon AWS, **cloud-netconfig** can
+additionally set up alias IPv4 ranges on managed interfaces. For that purpose,
+it will look up those ranges from the metedata server and add them to the
+`local` routing table, which will cause the kernel to consider addresses
+falling into those ranges as local ones.
+
- Create routing policies
In case the system has more than one network interface, **cloud-netconfig**
sets up routing in a way that packets are routed through the interface
associated with the source address of the packet. To do that, it creates a
-separate routing table for each interface with a default route according to the
-interface configration. It also creates a routing policy to use that table for
-packets using any of the interface's source addresses. This ensures that
-packets are routed via the correct interface.
-
-Note: DHCP servers of cloud frameworks (this applies to Microsoft Azure at the
-time of writing) may not include a gateway address in DHCP leases for secondary
-IPv4 addresses. This is presumably to avoid default routes to clash. To enable
-full connectivity in this case, **cloud-netconfig** assumes the gateway host to
-be the first host of the sub-network assigned to the interface.
+separate routing table for each interface with a default route according to
+the interface configration. It also creates routing policies to use that table
+for packets using any of the interface's source addresses. This ensures that
+packets are routed via the correct interface. In case alias IPv4 ranges are
+associated with the interface, routing policies will be created for those as
+well.
+
+Note: DHCP servers of cloud frameworks may not include a gateway address in
+DHCP leases for secondary IPv4 addresses. This is presumably to avoid default
+routes to clash and potentially render the instance without functioning
+external connectivity. With routing policies in place, multiple default routes
+are feasible and **cloud-netconfig** will try to configure them where
+applicable. In Google Compute Engine, the gateway address is available from
+the metadata and **cloud-netconfig** will look it up and apply accordingly. If
+no gateway information is available (which is the case in Microsoft Azure at
+the time of writing), **cloud-netconfig** assumes the gateway host to be the
+first host of the sub-network assigned to the interface.
Interface configurations will be checked periodically on each DHCP lease
-renewal and additionally, if the systemd timer is enabled (default on Amazon
-EC2 and Microsoft Azure SUSE Linux Enterprise Server images), every 60 seconds.
-**cloud-netconfig** detects changes in the metadata configuration and updates
-interface configurations and routing policies accordingly. This means that IP
-addresses that were removed from the virtual interface configuration will be
-removed from the interface, but only addresses that were automatically added by
-**cloud-netconfig** will be removed. Addresses added manually by the
-administrator or by another tool (e.g. high-availability software) will not be
-touched.
+renewal and additionally, if the systemd timer is enabled, every 60
+seconds. **cloud-netconfig** detects changes in the metadata configuration and
+updates interface configurations and routing policies accordingly. This means
+that IP addresses and ranges that were removed from the virtual interface
+configuration will be removed from the interface, but only addresses and
+ranges that were automatically added by **cloud-netconfig** will be
+removed. Addresses added manually by the administrator or by another tool
+(e.g. high-availability software) will not be touched.
### Configuration
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloud-netconfig-1.6/VERSION
new/cloud-netconfig-1.7/VERSION
--- old/cloud-netconfig-1.6/VERSION 2021-08-27 12:26:02.523795379 +0200
+++ new/cloud-netconfig-1.7/VERSION 2022-12-16 15:29:58.369590436 +0100
@@ -1 +1 @@
-1.6
+1.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/cloud-netconfig-1.6/azure/61-cloud-netconfig-hotplug.rules
new/cloud-netconfig-1.7/azure/61-cloud-netconfig-hotplug.rules
--- old/cloud-netconfig-1.6/azure/61-cloud-netconfig-hotplug.rules
2018-07-10 18:22:11.173301719 +0200
+++ new/cloud-netconfig-1.7/azure/61-cloud-netconfig-hotplug.rules
2022-12-16 15:29:58.369590436 +0100
@@ -1 +1,2 @@
-SUBSYSTEM=="net", KERNEL=="eth*", DRIVERS=="hv_netvsc",
RUN+="/etc/sysconfig/network/scripts/cloud-netconfig-hotplug"
+SUBSYSTEM=="net", KERNEL=="eth*", DRIVERS=="hv_netvsc",
RUN+="%SCRIPTDIR%/cloud-netconfig-hotplug"
+SUBSYSTEM=="net", KERNEL=="eth*", DRIVERS=="mlx5_core",
RUN+="%SCRIPTDIR%/cleanup-stale-ifcfg"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloud-netconfig-1.6/azure/cleanup-stale-ifcfg
new/cloud-netconfig-1.7/azure/cleanup-stale-ifcfg
--- old/cloud-netconfig-1.6/azure/cleanup-stale-ifcfg 1970-01-01
01:00:00.000000000 +0100
+++ new/cloud-netconfig-1.7/azure/cleanup-stale-ifcfg 2022-12-16
15:29:58.369590436 +0100
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# Copyright (c) 2022 SUSE Software Solutions ltd
+#
+# 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/>.
+
+
+test -z "$INTERFACE" && exit 1
+ifcfg="/etc/sysconfig/network/ifcfg-${INTERFACE}"
+
+if [[ -f $ifcfg ]]; then
+ if grep -q -E "^CLOUD_NETCONFIG_MANAGE=[\'\"]?yes" $ifcfg ; then
+ logger -t cloud-netconfig "ifcfg file for $INTERFACE seems stale,
deleting"
+ rm "/etc/sysconfig/network/ifcfg-${INTERFACE}"
+ fi
+fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloud-netconfig-1.6/azure/functions.cloud-netconfig
new/cloud-netconfig-1.7/azure/functions.cloud-netconfig
--- old/cloud-netconfig-1.6/azure/functions.cloud-netconfig 2021-08-27
16:55:30.278959254 +0200
+++ new/cloud-netconfig-1.7/azure/functions.cloud-netconfig 2022-12-16
15:29:58.369590436 +0100
@@ -37,7 +37,7 @@
return
fi
sleep 0.5
- result=$($CURL $url 2>/dev/null)
+ result=$($CURL $url | tr -d ' \n' 2>/dev/null)
done
echo -n $result
@@ -47,7 +47,7 @@
# -------------------------------------------------------------------
# get the MAC address from the metadata server
# format is uppercase without semicolons
-#
+#
get_iface_mac()
{
local if_idx="$1"
@@ -59,7 +59,7 @@
# -------------------------------------------------------------------
# gets all IPv4 address from the Azure metadata server for given
# interface index
-#
+#
get_ipv4_addresses_by_index()
{
local if_idx="$1" count=0 prefixlen="$2"
@@ -75,8 +75,8 @@
}
# -------------------------------------------------------------------
-# get IPv4 address from the Azure metadata server and return them
-#
+# get IPv4 addresses from the Azure metadata server and return them
+#
get_ipv4_addresses_from_metadata()
{
local idx hwaddr="$1"
@@ -93,6 +93,22 @@
}
# -------------------------------------------------------------------
+# dummy, no IP ranges in Azure
+#
+get_ipv4_ranges_from_metadata()
+{
+ return 0
+}
+
+# -------------------------------------------------------------------
+# dummy, no gateway information in metadata
+#
+get_gateway_from_metadata()
+{
+ return 0
+}
+
+# -------------------------------------------------------------------
# check whether metadata server is available
#
metadata_available()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloud-netconfig-1.6/cloud-netconfig.spec
new/cloud-netconfig-1.7/cloud-netconfig.spec
--- old/cloud-netconfig-1.6/cloud-netconfig.spec 2021-08-27
12:26:02.523795379 +0200
+++ new/cloud-netconfig-1.7/cloud-netconfig.spec 2022-12-16
15:29:58.373590508 +0100
@@ -35,8 +35,13 @@
%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.6
+Version: 1.7
Release: 0
License: GPL-3.0-or-later
Summary: Network configuration scripts for %{csp_string}
@@ -54,6 +59,7 @@
Requires: sysconfig-netconfig
%endif
BuildRequires: pkgconfig(udev)
+BuildRequires: NetworkManager
Requires: udev
Requires: curl
%if 0%{?sles_version} == 11
@@ -66,11 +72,27 @@
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}
@@ -81,8 +103,11 @@
DESTDIR=%{buildroot} \
PREFIX=%{_usr} \
SYSCONFDIR=%{_sysconfdir} \
+ DISTCONFDIR=%{_distconfdir} \
+ SCRIPTDIR=%{_scriptdir} \
UDEVRULESDIR=%{_udevrulesdir} \
- UNITDIR=%{_unitdir}
+ 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.
@@ -91,11 +116,16 @@
ln -s /dev/null
%{buildroot}/%{_sysconfdir}/udev/rules.d/75-persistent-net-generator.rules
%endif
+
%files -n %{base_name}%{flavor_suffix}
%defattr(-,root,root)
-%config(noreplace) %{_sysconfdir}/default/cloud-netconfig
-%{_sysconfdir}/netconfig.d/cloud-netconfig
-%{_sysconfdir}/sysconfig/network/scripts/*
+%{_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
@@ -104,6 +134,9 @@
%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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloud-netconfig-1.6/common/cloud-netconfig
new/cloud-netconfig-1.7/common/cloud-netconfig
--- old/cloud-netconfig-1.6/common/cloud-netconfig 2021-08-27
15:23:21.154649724 +0200
+++ new/cloud-netconfig-1.7/common/cloud-netconfig 2022-12-16
15:29:58.373590508 +0100
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright (c) 2017 SUSE Linux GmbH
+# Copyright (c) 2022 SUSE LLC
#
# This file is part of cloud-netconfig.
#
@@ -18,20 +18,135 @@
# 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/etc/sysconfig/network/scripts/functions.netconfig"
-# for get_ipv4_addresses_from_metadata()
-. "$r/etc/sysconfig/network/scripts/functions.cloud-netconfig"
+SCRIPTDIR=/usr/libexec/cloud-netconfig
+STATEDIR=/run/wicked
+ADDRDIR=/run/cloud-netconfig
+LOCKFILE=/run/cloud-netconfig/lock
+
+. ${SCRIPTDIR}/functions.cloud-netconfig
+
+LOGGER_OPTS="-t $PROGNAME"
+tty -s && LOGGER_OPTS="$LOGGER_OPTS -s"
+
+# -------------------------------------------------------------------
+# log debug message
+#
+debug () {
+ test "$QUIET" = "yes" && return
+ test "$DEBUG" = "yes" || return
+ logger $LOGGER_OPTS -p debug "$*"
+}
+
+# -------------------------------------------------------------------
+# log warning message
+#
+warn () {
+ test "$QUIET" = "yes" && return
+ logger $LOGGER_OPTS -p warn -t "$*"
+}
+
+# -------------------------------------------------------------------
+# log info message
+#
+log () {
+ test "$QUIET" = "yes" && return
+ logger $LOGGER_OPTS "$*"
+}
+
+# -------------------------------------------------------------------
+# get variable from file
+#
+function get_variable()
+{
+ local line
+ while read line; do
+ eval $line
+ done < <(grep "^[[:space:]]*$1=" $2 2>/dev/null)
+}
+
+# -------------------------------------------------------------------
+# print network service in use
+#
+get_network_service()
+{
+ IFS="=."
+ NET_SERVICE=(`systemctl --no-pager -p Id show network.service`)
+ echo "${NET_SERVICE[1]}"
+}
+
+# -------------------------------------------------------------------
+# print relevant information from wicked lease info
+#
+get_wicked_lease_info()
+{
+ local iface="$1" cfg="${STATEDIR}/leaseinfo.${iface}.dhcp.ipv4"
+ if [ -e "$cfg" ]; then
+ grep -E '^IPADDR|^NETWORK|^NETMASK|^BROADCAST|^GATEWAYS|^ROUTES' $cfg
+ else
+ return 1
+ fi
+}
+
+# -------------------------------------------------------------------
+# print network info from given IPv4 address and netmask
+#
+calculate_network()
+{
+ local addr=$1 netmask=$2
+ test -z "$addr" -o -z "$netmask" && return 1
+ IFS=. read -r i1 i2 i3 i4 <<< "$addr"
+ IFS=. read -r m1 m2 m3 m4 <<< "$netmask"
+ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4
& m4))"
+}
+
+
+# -------------------------------------------------------------------
+# get relevant information from NetworkManager, map to expected
+# variable names and print them
+#
+get_nm_lease_info()
+{
+ local iface="$1"
+ test -z `type -p nmcli` && { warn "nmcli not found, cannot configure
interface" ; return 1 ; }
+ local ipaddr network netmask broadcast gateways prefixlen
+ ipaddr=`nmcli -f DHCP4 -t d show $iface | grep ':ip_address' | cut -d= -f2
| tr -d ' '`
+ netmask=`nmcli -f DHCP4 -t d show $iface | grep ':subnet_mask' | cut -d=
-f2 | tr -d ' '`
+ broadcast=`nmcli -f DHCP4 -t d show $iface | grep ':broadcast_address' |
cut -d= -f2 | tr -d ' '`
+ gateways=`nmcli -f DHCP4 -t d show $iface | grep ':routers' | cut -d= -f2
| tr ',' ' '`
+ echo "IPADDR=$ipaddr"
+ echo -n "NETWORK="
+ calculate_network $ipaddr $netmask
+ echo "NETMASK=$netmask"
+ echo "BROADCAST=$broadcast"
+ echo "GATEWAYS=($gateways)"
+}
+
+
+# -------------------------------------------------------------------
+# print relevant lease information from used network system
+#
+get_lease_info()
+{
+ local iface="$1"
+ test -z "$iface" && return 1
+ netsys=`get_network_service`
+ case "$netsys" in
+ "wicked")
+ get_wicked_lease_info "$iface"
+ ;;
+ "NetworkManager")
+ get_nm_lease_info "$iface"
+ ;;
+ "*")
+ return 1
+ ;;
+ esac
+}
-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"
@@ -43,7 +158,7 @@
# -------------------------------------------------------------------
# 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"
@@ -60,7 +175,7 @@
# -------------------------------------------------------------------
# compare arrays and return the ones that are in the first but not
# the second
-#
+#
get_extra_elements()
{
local actual=(${!1}) target=(${!2})
@@ -93,46 +208,16 @@
}
# -------------------------------------------------------------------
-# 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"
+ local addr_type="$2"
test -z "$iface" && return 1
- if [[ -e ${ADDRDIR}/${iface} ]]; then
- echo $(cat ${ADDRDIR}/${iface})
+ if [[ -e ${ADDRDIR}/${addr_type}${iface} ]]; then
+ echo $(cat ${ADDRDIR}/${addr_type}${iface})
fi
}
@@ -154,9 +239,10 @@
{
local iface="$1"
local addr="$2"
+ local addr_type="$3"
test -z "$iface" -o -z "$addr" && return 1
- addr_log_file="${ADDRDIR}/${iface}"
+ addr_log_file="${ADDRDIR}/${addr_type}${iface}"
if [[ -e ${addr_log_file} ]]; then
grep -q -x "${addr}" "${addr_log_file}" || echo "${addr}" >>
"${addr_log_file}"
else
@@ -172,9 +258,10 @@
{
local iface="$1"
local addr="$2"
+ local addr_type="$3"
test -z "$iface" -o -z "$addr" && return 1
- addr_log_file="${ADDRDIR}/${iface}"
+ addr_log_file="${ADDRDIR}/${addr_type}${iface}"
if [[ -e ${addr_log_file} ]]; then
addr_log_file_tmp=$(mktemp ${ADDRDIR}/${iface}.XXXXXXXX)
if [ $? -ne 0 ]; then
@@ -190,34 +277,75 @@
# copy routes from default table to given table and remove routes
# that do not exist in default table (if any)
#
-update_routing_table()
+update_routing_tables()
{
- local rtable="$1"
+ local ipv="$1"
local iface="$2"
+ local dest_table="$3"
+ local gw_table="$4"
- test -z "$rtable" && return 1
+ test -z "$gw_table" && 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
+ # copy destination specific routes from default table
+ ip $ipv route show dev $iface | grep -v "^default" | while read route ; do
+ # expires arg can't be used as is, drop it
+ route=$(echo $route | sed -e 's/expires [^ ]*//')
+ debug "creating/replacing route $route dev $iface table $dest_table"
+ ip $ipv route replace $route dev $iface table $dest_table
+ done
+
+ # copy gateway route(s) from default table
+ ip $ipv route show default dev $iface | while read route ; do
+ route=$(echo $route | sed -e 's/expires [^ ]*//')
+ debug "creating/replacing route $route dev $iface table $gw_table"
+ ip $ipv route replace $route dev $iface table $gw_table
+ done
+
+ # check if there are any leftover routes and delete them
+ ip $ipv route show all table $dest_table | grep -v "^default" | while read
route; do
+ ip_out="$(ip $ipv route show $route)"
+ if [[ -z "$ip_out" ]]; then
+ debug "deleting obsolete route $route from table $dest_table"
+ ip $ipv route del $route table $dest_table
+ fi
+ 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
+# -------------------------------------------------------------------
+# copy routes from default table to given table and remove routes
+# that do not exist in default table (if any)
+#
+update_routing_policies()
+{
+ local ipv="$1"
+ local iface="$2"
+ local dest_table="$3"
+ local gw_table="$4"
+ local -n addrs=$5
- # 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
+ # update routing policies so connections from addresses on
+ # secondary interfaces are routed via those
+ # also include IP rangers
+ local found prio from ip rest
+ for addr in ${addrs[@]} ; do
+ found=0
+ while read -r prio from ip rest ; do
+ if [[ "${addr%/32}" == "$ip" ]]; then
+ found=1
+ break
+ fi
+ done < <(ip $ipv rule show)
+ if [[ $found == 0 ]]; then
+ debug "creating policy rule for src address ${addr%/32}"
+ ip $ipv rule add from ${addr%/32} priority $dest_table lookup
$dest_table
+ ip $ipv rule add from ${addr%/32} priority $gw_table lookup
$gw_table
+ fi
done
+
+ # create main (w/o default) lookup rule, if necessary
+ if [[ -z "$(ip $ipv rule show prio 30399)" ]]; then
+ ip $ipv rule add from all table main prio 30399 suppress_prefixlength 0
+ fi
}
# -------------------------------------------------------------------
@@ -226,23 +354,38 @@
#
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 INTERFACE="$1"
+ test -z "$INTERFACE" && return 1
+ local IPADDR NETWORK NETMASK BROADCAST GATEWAYS
+ eval `get_lease_info $INTERFACE`
+ if [ -z "$IPADDR" ]; then
+ warn "Could not determine address from DHCP4 lease info"
+ return 1
+ fi
local HWADDR="$(cat /sys/class/net/${INTERFACE}/address)"
- local RTABLE="10${INTERFACE: -1}"
+ if [ -z "$HWADDR" ]; then
+ warn "Could not determine MAC address for $INTERFACE"
+ return 1
+ fi
+ local ifindex="$(cat /sys/class/net/${INTERFACE}/ifindex)"
+ if [ -z "$ifindex" ]; then
+ warn "Could not determine interface index for $INTERFACE"
+ return 1
+ fi
+ local dest_table="$((ifindex+30000))"
+ local gw_table="$((ifindex+30400))"
# get active and configured addresses
local laddrs=($(get_ipv4_addresses_from_interface $INTERFACE))
- local raddrs=($(get_ipv4_addresses_from_metadata $HWADDR))
+ local raddrs addr
+ for addr in $(get_ipv4_addresses_from_metadata $HWADDR) ; do
+ # validate whether element looks like an IPv4 address
+ if [[ $addr =~
^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/[0-9]{1,2}$ ]]; then
+ raddrs+=($addr)
+ else
+ warn "IPv4 address \"${addr}\" from instance metadata does not
look valid, skipping"
+ fi
+ done
# get differences
local addr_to_remove=($(get_extra_elements laddrs[@] raddrs[@]))
@@ -256,7 +399,6 @@
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
@@ -286,6 +428,28 @@
add_addr_to_log $INTERFACE $addr
done
+ local ip_ranges=$(get_ipv4_ranges_from_metadata $HWADDR)
+ local local_route
+ for ipr in $ip_ranges; do
+ local_route=$(ip r show $ipr type local table local)
+ if [[ -z $local_route ]]; then
+ debug "No local route for IP range $ipr, creating one"
+ ip -4 r add local $ipr dev $INTERFACE table local
+ add_addr_to_log $INTERFACE $ipr aliases_
+ fi
+ done
+ # check if cloud-netconfig configured IP aliases were removed
+ local cn_ip_ranges=$(get_cn_assigned_addrs $INTERFACE ranges_)
+ if [[ -n $cn_ip_ranges ]]; then
+ for ipr in $cn_ip_ranges ; do
+ if [[ " $ip_ranges " == *" $ipr "* ]]; then
+ debug "IP range $ipr was removed, dropping local route"
+ ip -4 r del local $ipr dev $INTERFACE table local
+ remove_addr_from_log $INTERFACE $ipr ranges_
+ fi
+ done
+ fi
+
# If we have a single NIC configuration, skip routing policies
if [[ $SINGLE_NIC = yes ]]; then
return
@@ -295,26 +459,18 @@
# 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
+ if [ -z "$(ip -4 route show default dev $INTERFACE)" ]; 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
+ # GCE does not provide a gateway for secondary NICs in the
+ # lease info but is available via meta data.
+ GW=$(get_gateway_from_metadata $HWADDR)
+ if [ -z $GW ]; then
+ debug "No gateway info available for $INTERFACE, guessing"
# we assume the gateway is the first host of the network
local netstart=${NETWORK##*.}
local gw_host_part=$((netstart+1))
@@ -322,32 +478,47 @@
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"
+ debug "adding default route via $GW for $INTERFACE table $GW_TABLE"
+ ip -4 route add default via $GW dev "$INTERFACE" metric
$((ifindex+20000))
else
warn "No default route for $INTERFACE"
fi
fi
# copy specific routes from the default routing table
- update_routing_table $RTABLE $INTERFACE
+ update_routing_tables -4 $INTERFACE $dest_table $gw_table
# update routing policies so connections from addresses on
# secondary interfaces are routed via those
- local found prio from ip rest
+ # also include IP rangers
+ #local found prio from ip rest
+ #for addr in ${raddrs[@]} $ip_ranges ; do
+ # found=0
+ # while read -r prio from ip rest ; do
+ # if [[ "${addr%/32}" == "$ip" ]]; then
+ # found=1
+ # break
+ # fi
+ # done < <(ip -4 rule show)
+ # if [[ $found == 0 ]]; then
+ # debug "creating policy rule for src address ${addr%/32}"
+ # #priority=$(get_free_priority $LOCAL_TABLE 4)
+ # ip -4 rule add from ${addr%/32} priority $dest_table lookup
$dest_table
+ # #priority=$(get_free_priority $GW_TABLE 4)
+ # ip -4 rule add from ${addr%/32} priority $gw_table lookup
$gw_table
+ # fi
+ #done
+ local all_addrs=()
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
+ all_addrs+=("${addr%/*}")
done
+ all_addrs+=($ip_ranges)
+ update_routing_policies -4 $INTERFACE $dest_table $gw_table all_addrs
+
+ # create main (w/o default) lookup rule, if necessary
+ if [[ -z "$(ip -4 rule show prio 30399)" ]]; then
+ ip -4 rule add from all table main prio 30399 suppress_prefixlength 0
+ fi
}
# -------------------------------------------------------------------
@@ -355,23 +526,20 @@
#
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 INTERFACE="$1"
+ test -z "$INTERFACE" && return 1
+
+ local ifindex="$(cat /sys/class/net/${INTERFACE}/ifindex)"
+ if [ -z "$ifindex" ]; then
+ warn "Could not determine interface index for $INTERFACE"
+ return 1
+ fi
- local RTABLE="10${INTERFACE: -1}"
+ local dest_table="$((ifindex+30000))"
+ local gw_table="$((ifindex+30400))"
# if necessary, create route table with default route for interface
- if [ -z "$(ip -6 route show default dev $INTERFACE table $RTABLE)" ]; then
+ if [ -z "$(ip -6 route show default dev $INTERFACE table $RTABLE
2>/dev/null)" ]; 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
@@ -384,28 +552,54 @@
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
+ update_routing_tables -6 $INTERFACE $dest_table $gw_table
+ local laddrs=($(get_ipv6_addresses_from_interface $INTERFACE))
+ update_routing_policies -6 $INTERFACE $dest_table $gw_table laddrs
+
+ #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)
+ # debug "creating policy rule for address ${addr%/*}"
+ # ip -6 rule add from ${addr%/*} priority $priority table $RTABLE
+ # fi
+ #done
+
+ ## create main (w/o default) lookup rule, if necessary
+ #if [[ -z "$(ip -6 rule show prio 30399)" ]]; then
+ # ip -6 rule add from all table main prio 30399 suppress_prefixlength 0
+ #fi
+}
+
+# -------------------------------------------------------------------
+# Check if interface has a DHCP lease. Takes interface name
+# and IP version.
+#
+iface_has_lease()
+{
+ local iface="$1" ipv="$2"
+ test -z "$iface" && return 1
+ test "$ipv" != "4" -a "$ipv" != "6" && return 1
+
+ local netsys=`get_network_service`
+ if [ "$netsys" == "wicked" ]; then
+ test -e /run/wicked/leaseinfo.${iface}.dhcp.ipv${ipv}
+ return $?
+ elif [ "$netsys" == "NetworkManager" ]; then
+ nmcli -f DHCP${ipv} -t d show $iface | grep -q -E ':ip6?_address'
+ return $?
+ fi
+ return 1
}
# -------------------------------------------------------------------
@@ -415,55 +609,68 @@
#
manage_interfaceconfig()
{
- local cfg="$1"
- test -z "$cfg" -o ! -d "$cfg" && return 1
- local ifcfg="/etc/sysconfig/network/ifcfg-${cfg##*/}"
+ local iface="$1"
+ test -z "$iface" && return 1
+ local netsys=`get_network_service`
local CLOUD_NETCONFIG_MANAGE
- if [[ -f "${ifcfg}" ]]; then
- get_variable "CLOUD_NETCONFIG_MANAGE" "${ifcfg}"
+ 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
+ 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##*/}"
+ debug "Not managing interface ${iface}"
return
fi
- linkstatus=$(get_link_status ${cfg##*/})
+ linkstatus=$(get_link_status ${iface})
if [[ $linkstatus != UP ]]; then
- debug "interface ${cfg##*/} is down"
+ debug "interface ${iface} is down"
return
fi
if ! metadata_available ; then
- warn "Cannot access instance metadata, skipping interface
configuration for ${cfg##*/}"
+ warn "Cannot access instance metadata, skipping interface
configuration for ${iface}"
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
+ iface_has_lease $iface 4 && configure_interface_ipv4 $iface
+ iface_has_lease $iface 6 && configure_interface_ipv6 $iface
}
-if_dirs=()
-for IFDIR in $STATEDIR/* ; do
- test -d $IFDIR -a -d "/sys/class/net/${IFDIR##*/}" || continue
- test ${IFDIR##*/} = "lo" && continue
- if_dirs+=($IFDIR)
+if [ ! -d $ADDRDIR ]; then
+ rm -f $ADDRDIR
+ mkdir $ADDRDIR
+fi
+
+test -e "$LOCKFILE" && exit 0
+
+trap "rm -f $LOCKFILE" EXIT
+touch $LOCKFILE
+
+get_variable DEBUG /etc/sysconfig/network/config
+
+nics=()
+for IFDIR in /sys/class/net/* ; do
+ # skip virtual and bonded interfaces
+ test -e $IFDIR/device || continue
+ test -e $IFDIR/master && continue
+ nics+=(${IFDIR##*/})
done
# set single NIC flag if appropriate
-if [[ ${#if_dirs[@]} -eq 1 ]]; then
+if [[ ${#nics[@]} -eq 1 ]]; then
SINGLE_NIC=yes
else
SINGLE_NIC=no
fi
-for IFDIR in ${if_dirs[@]} ; do
- manage_interfaceconfig $IFDIR
+for nic in ${nics[@]} ; do
+ manage_interfaceconfig $nic
done
+
+exit 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloud-netconfig-1.6/common/cloud-netconfig-default
new/cloud-netconfig-1.7/common/cloud-netconfig-default
--- old/cloud-netconfig-1.6/common/cloud-netconfig-default 2020-02-04
18:31:10.628357312 +0100
+++ new/cloud-netconfig-1.7/common/cloud-netconfig-default 2022-12-16
15:29:58.373590508 +0100
@@ -1,2 +1,4 @@
-# Default value cloud-netconfig should use when creating new ifcfg files
+# Default value cloud-netconfig should use when creating new ifcfg files.
+# On systems that use NetworkManager systems, this globally enables or
+# disables cloud-netconfig.
CLOUD_NETCONFIG_MANAGE="yes"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloud-netconfig-1.6/common/cloud-netconfig-hotplug
new/cloud-netconfig-1.7/common/cloud-netconfig-hotplug
--- old/cloud-netconfig-1.6/common/cloud-netconfig-hotplug 2020-02-04
18:31:10.628357312 +0100
+++ new/cloud-netconfig-1.7/common/cloud-netconfig-hotplug 2022-12-16
15:29:58.373590508 +0100
@@ -1,6 +1,6 @@
-#!/bin/sh
+#!/bin/bash
-# Copyright (c) 2017 SUSE Linux GmbH
+# Copyright (c) 2022 SUSE LLC
#
# This file is part of cloud-netconfig.
#
@@ -17,10 +17,13 @@
# You should have received a copy of the GNU General Public License
# along with cloud-netconfig. If not, see <http://www.gnu.org/licenses/>.
+SCRIPTDIR=/usr/libexec/cloud-netconfig
+DISTCONFDIR=/usr/etc
test -z "$INTERFACE" && exit 1
test "$INTERFACE" == "eth0" && exit 0
+test -f ${DISTCONFDIR}/default/cloud-netconfig && .
${DISTCONFDIR}/default/cloud-netconfig
test -f /etc/default/cloud-netconfig && . /etc/default/cloud-netconfig
test -z "$CLOUD_NETCONFIG_MANAGE" && CLOUD_NETCONFIG_MANAGE=yes
@@ -100,7 +103,7 @@
;;
remove)
- /etc/sysconfig/network/scripts/cloud-netconfig-cleanup
+ ${SCRIPTDIR}/cloud-netconfig-cleanup
;;
esac
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloud-netconfig-1.6/common/cloud-netconfig-nm
new/cloud-netconfig-1.7/common/cloud-netconfig-nm
--- old/cloud-netconfig-1.6/common/cloud-netconfig-nm 1970-01-01
01:00:00.000000000 +0100
+++ new/cloud-netconfig-1.7/common/cloud-netconfig-nm 2022-12-16
15:29:58.373590508 +0100
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+# Copyright (c) 2022 SUSE LLC
+#
+# 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/
+
+# This is a NetworkManager dispatcher script. It runs cloud-netconfig setup on
+# interface up and cloud-netconfig cleanup on interface down.
+
+SCRIPTDIR=/usr/libexec/cloud-netconfig
+
+if [ "$2" == "up" ]; then
+ ${SCRIPTDIR}/cloud-netconfig
+elif [ "$2" == "down" ]; then
+ ${SCRIPTDIR}/cloud-netconfig-cleanup
+fi
+
+echo $?
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloud-netconfig-1.6/common/cloud-netconfig-wrapper
new/cloud-netconfig-1.7/common/cloud-netconfig-wrapper
--- old/cloud-netconfig-1.6/common/cloud-netconfig-wrapper 1970-01-01
01:00:00.000000000 +0100
+++ new/cloud-netconfig-1.7/common/cloud-netconfig-wrapper 2022-12-16
15:29:58.373590508 +0100
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+# Copyright (c) 2022 SUSE LLC
+#
+# 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/
+
+# Netconfig wrapper script for cloud-netconfig
+
+SCRIPTDIR=/usr/libexec/cloud-netconfig
+IFS="=."
+NET_SERVICE=(`systemctl --no-pager -p Id show network.service`)
+
+if [ "${NET_SERVICE[1]}" == "NetworkManager" ]; then
+ # handled via NetworkManager dispatch script
+ exit 0
+fi
+
+exec $SCRIPTDIR/cloud-netconfig
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/cloud-netconfig-1.6/ec2/51-cloud-netconfig-hotplug.rules
new/cloud-netconfig-1.7/ec2/51-cloud-netconfig-hotplug.rules
--- old/cloud-netconfig-1.6/ec2/51-cloud-netconfig-hotplug.rules
2018-07-10 18:22:11.177301751 +0200
+++ new/cloud-netconfig-1.7/ec2/51-cloud-netconfig-hotplug.rules
2022-12-16 15:29:58.377590583 +0100
@@ -1,2 +1,2 @@
ACTION=="add", SUBSYSTEM=="net", KERNEL=="eth*", IMPORT{program}="/bin/sleep 1"
-SUBSYSTEM=="net", KERNEL=="eth*",
RUN+="/etc/sysconfig/network/scripts/cloud-netconfig-hotplug"
+SUBSYSTEM=="net", KERNEL=="eth*", RUN+="%SCRIPTDIR%/cloud-netconfig-hotplug"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloud-netconfig-1.6/ec2/functions.cloud-netconfig
new/cloud-netconfig-1.7/ec2/functions.cloud-netconfig
--- old/cloud-netconfig-1.6/ec2/functions.cloud-netconfig 2021-08-27
16:55:30.278959254 +0200
+++ new/cloud-netconfig-1.7/ec2/functions.cloud-netconfig 2022-12-16
15:29:58.377590583 +0100
@@ -16,7 +16,7 @@
#
# You should have received a copy of the GNU General Public License
-API_VERSION="2018-09-24"
+API_VERSION="latest"
METADATA_URL_BASE="http://169.254.169.254/${API_VERSION}"
METADATA_URL_IFACE="${METADATA_URL_BASE}/meta-data/network/interfaces/macs"
CURL="curl -m 3 --noproxy 169.254.169.254"
@@ -65,7 +65,7 @@
# -------------------------------------------------------------------
# get IPv4 address from the EC2 meta data server and return them
-#
+#
get_ipv4_addresses_from_metadata()
{
local addr count=0 hwaddr="$1" prefixlen
@@ -93,11 +93,34 @@
}
# -------------------------------------------------------------------
+# get IPv4 range (prefix in EC2 term) for interface
+#
+get_ipv4_ranges_from_metadata()
+{
+ local hwaddr="$1" prefixes
+ test -z "$hwaddr" && return
+ set_from_metadata prefixes "${METADATA_URL_IFACE}/${hwaddr}/ipv4-prefix"
|| return 1
+ echo $prefixes
+}
+
+# -------------------------------------------------------------------
+# dummy, EC2 provides gateway information in DHCP4 offer
+#
+get_gateway_from_metadata()
+{
+ return 0
+}
+
+# -------------------------------------------------------------------
# check if metadata server is available
-#
+#
metadata_available()
{
check_url "${METADATA_URL_BASE}/meta-data/"
return $?
}
+# if eth0 and eth1 are on the same subnet, packets may be disrouted and
+# since policy rules may not be in place yet render IMDS inaccessible;
+# force eth0 as work-around
+metadata_available || test -e /sys/class/net/eth0 && CURL="$CURL --interface
eth0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/cloud-netconfig-1.6/gce/51-cloud-netconfig-hotplug.rules
new/cloud-netconfig-1.7/gce/51-cloud-netconfig-hotplug.rules
--- old/cloud-netconfig-1.6/gce/51-cloud-netconfig-hotplug.rules
2020-11-04 17:33:04.668500917 +0100
+++ new/cloud-netconfig-1.7/gce/51-cloud-netconfig-hotplug.rules
2022-12-16 15:29:58.377590583 +0100
@@ -1,2 +1,2 @@
ACTION=="add", SUBSYSTEM=="net", KERNEL=="eth*", IMPORT{program}="/bin/sleep 1"
-SUBSYSTEM=="net", KERNEL=="eth*",
RUN+="/etc/sysconfig/network/scripts/cloud-netconfig-hotplug"
+SUBSYSTEM=="net", KERNEL=="eth*", RUN+="%SCRIPTDIR%/cloud-netconfig-hotplug"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloud-netconfig-1.6/gce/functions.cloud-netconfig
new/cloud-netconfig-1.7/gce/functions.cloud-netconfig
--- old/cloud-netconfig-1.6/gce/functions.cloud-netconfig 2020-11-04
17:33:04.668500917 +0100
+++ new/cloud-netconfig-1.7/gce/functions.cloud-netconfig 2022-12-16
15:29:58.377590583 +0100
@@ -16,30 +16,95 @@
#
# You should have received a copy of the GNU General Public License
+METADATA_BASE_URL="http://169.254.169.254/computeMetadata/v1/instance/network-interfaces/"
+URL_HDR="Metadata-Flavor:Google"
+CURL="curl -m 3 --noproxy 169.254.169.254 -H $URL_HDR"
+
+# -------------------------------------------------------------------
+# look up a meta data item
+#
+get_from_metadata()
+{
+ local url="${METADATA_BASE_URL}${1}"
+ local result=$($CURL $url 2>/dev/null)
+ echo -n $result
+}
+
# -------------------------------------------------------------------
# no metadata lookup in GCE required due to no secondary IP addresses
# simply look up local addresses
#
get_ipv4_addresses_from_metadata()
{
- local iface status mac if_match addr hwaddr="$1"
+ local hwaddr="$1"
test -z "$hwaddr" && return 1
- while read -r iface status mac rest ; do
+
+ local nics=$(get_from_metadata)
+ for idx in $nics ; do
+ local mac=$(get_from_metadata "${idx}mac")
+ if [[ $mac == $hwaddr ]]; then
+ local addr=$(get_from_metadata ${idx}ip)
+ if [[ ${addr} == ${addr%/*} ]]; then
+ addr="${addr}/32"
+ fi
+ echo $addr
+ return 0
+ fi
+ done
+ return 1
+}
+
+# -------------------------------------------------------------------
+# look up gateway information in metadata
+#
+get_gateway_from_metadata()
+{
+ local hwaddr="$1"
+ test -z "$hwaddr" && return 1
+
+ local nics=$(get_from_metadata)
+ for idx in $nics ; do
+ local mac=$(get_from_metadata "${idx}mac")
+ if [[ $mac == $hwaddr ]]; then
+ get_from_metadata ${idx}gateway
+ return 0
+ fi
+ done
+ return 1
+}
+
+# -------------------------------------------------------------------
+# look up IP range information for interface
+#
+get_ipv4_ranges_from_metadata()
+{
+ local hwaddr="$1" mac ipalias ipaliases aliases_str
+ test -z "$hwaddr" && return 1
+
+ local nics=$(get_from_metadata)
+ for idx in $nics ; do
+ mac=$(get_from_metadata "${idx}mac")
if [[ $mac == $hwaddr ]]; then
- if_match=$iface
- break
+ ipaliases=$(get_from_metadata ${idx}ip-aliases/)
+ if [[ -n $ipaliases ]]; then
+ for ipalias in $ipaliases ; do
+ aliases_str="$aliases_str `get_from_metadata
"${idx}ip-aliases/${ipalias}" | tr -d '\n'`"
+ done
+ echo $aliases_str
+ fi
+ return 0
fi
- done < <(ip -br -o -4 link show)
- if [[ -n $if_match ]]; then
- ip -br -4 -o addr show dev $if_match | awk '{ print $3 }'
- fi
+ done
+ return 1
}
# -------------------------------------------------------------------
-# dummy function, metadata not used
+# check whether metadata is available
#
metadata_available()
{
- return 0
+ local resp=$($CURL
"http://metadata.google.internal/computeMetadata/v1/instance/id" 2>/dev/null)
+ [[ -n "$resp" ]]
+ return $?
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloud-netconfig-1.6/systemd/cloud-netconfig.service
new/cloud-netconfig-1.7/systemd/cloud-netconfig.service
--- old/cloud-netconfig-1.6/systemd/cloud-netconfig.service 2019-01-31
14:11:27.891295667 +0100
+++ new/cloud-netconfig-1.7/systemd/cloud-netconfig.service 2022-12-16
15:29:58.377590583 +0100
@@ -3,4 +3,4 @@
[Service]
Type=oneshot
-ExecStart=-/bin/bash -c '/sbin/netconfig -m cloud-netconfig update'
+ExecStart=-/bin/bash -c '%SCRIPTDIR%/cloud-netconfig'