forked from pool/cloud-init
- Update to version 18.4 (bsc#1087331, bsc#1097388, boo#1111427, bsc#1095627)
+ Remove cloud-init-no-user-lock-if-already-locked.patch cloud-init 18.4 is not supported on SLE 11 code base + Remove 0001-Support-chrony-configuration-lp-1731619.patch Included upstream + Remove 0003-Distro-dependent-chrony-config-file.patch Included upstream + Remove 0001-switch-to-using-iproute2-tools.patch Included upstream + Remove cloud-init-no-python-linux-dist.patch Included upstream + Remove cloud-init-no-trace-empt-sect.patch Included upstream + Remove cloud-init-setpath-dsitentify.patch Included upstream + Modify fix-default-systemd-unit-dir.patch Use pkg-config, only modify the generator + Remove cloud-init-sysconfig-netpathfix.patch Fixed upstream + Removed cloud-init-skip-ovf-tests.patch Fixed upstream + Removed cloud-init-translate-netconf-ipv4-keep-gw.patch Fixed upstream + Add cloud-init-template-py2.patch avoid Python 3 dependency when we build for distros with Python 2 support + Add 0001-Follow-the-ever-bouncing-ball-for-openSUSE-distribut.patch + Add 0002-Add-tests-for-additional-openSUSE-distro-condition-m.patch + Add cloud-init-sysconf-path.patch + Add cloud-init-sysconf-ethsetup.patch + Add 0001-Fix-the-service-order-for-SUSE-distributions.patch OBS-URL: https://build.opensuse.org/package/show/Cloud:Tools/cloud-init?expand=0&rev=121
This commit is contained in:
parent
6c4efe240a
commit
3ed6919cb4
28
0001-Fix-the-service-order-for-SUSE-distributions.patch
Normal file
28
0001-Fix-the-service-order-for-SUSE-distributions.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From 1f7950f72dc5f3603118c0f91dca3fb7145f0801 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Schweikert <rjschwei@suse.com>
|
||||
Date: Wed, 24 Oct 2018 09:50:11 -0400
|
||||
Subject: [PATCH] - Fix the service order for SUSE distributions + Network
|
||||
configuration file gets written when cloud-init.service runs. Therefore
|
||||
this needs to run prior to the network tools (wicked)
|
||||
|
||||
---
|
||||
systemd/cloud-init.service.tmpl | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/systemd/cloud-init.service.tmpl b/systemd/cloud-init.service.tmpl
|
||||
index b92e8abc..5cb00371 100644
|
||||
--- a/systemd/cloud-init.service.tmpl
|
||||
+++ b/systemd/cloud-init.service.tmpl
|
||||
@@ -14,8 +14,7 @@ After=networking.service
|
||||
After=network.service
|
||||
{% endif %}
|
||||
{% if variant in ["suse"] %}
|
||||
-Requires=wicked.service
|
||||
-After=wicked.service
|
||||
+Before=wicked.service
|
||||
# setting hostname via hostnamectl depends on dbus, which otherwise
|
||||
# would not be guaranteed at this point.
|
||||
After=dbus.service
|
||||
--
|
||||
2.13.7
|
||||
|
@ -0,0 +1,40 @@
|
||||
From eb504025c76909175ab2d00c25232b89faf01ab4 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Schweikert <rjschwei@suse.com>
|
||||
Date: Sun, 21 Oct 2018 08:28:21 -0400
|
||||
Subject: [PATCH 1/2] - Follow the ever bouncing ball for openSUSE distribution
|
||||
identification + openSUSE changed from identifying itself as "opensuse" in
|
||||
os-release to "opensuse-tumbleweed" and "opensuse-leap". This breaks
|
||||
template expansion
|
||||
|
||||
---
|
||||
cloudinit/util.py | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/util.py b/cloudinit/util.py
|
||||
index c67d6be6..7800f7bc 100644
|
||||
--- a/cloudinit/util.py
|
||||
+++ b/cloudinit/util.py
|
||||
@@ -615,8 +615,8 @@ def get_linux_distro():
|
||||
distro_name = os_release.get('ID', '')
|
||||
distro_version = os_release.get('VERSION_ID', '')
|
||||
if 'sles' in distro_name or 'suse' in distro_name:
|
||||
- # RELEASE_BLOCKER: We will drop this sles ivergent behavior in
|
||||
- # before 18.4 so that get_linux_distro returns a named tuple
|
||||
+ # RELEASE_BLOCKER: We will drop this sles divergent behavior in
|
||||
+ # the future so that get_linux_distro returns a named tuple
|
||||
# which will include both version codename and architecture
|
||||
# on all distributions.
|
||||
flavor = platform.machine()
|
||||
@@ -668,7 +668,8 @@ def system_info():
|
||||
var = 'ubuntu'
|
||||
elif linux_dist == 'redhat':
|
||||
var = 'rhel'
|
||||
- elif linux_dist in ('opensuse', 'sles'):
|
||||
+ elif linux_dist in (
|
||||
+ 'opensuse', 'opensuse-tumbleweed', 'opensuse-leap', 'sles'):
|
||||
var = 'suse'
|
||||
else:
|
||||
var = 'linux'
|
||||
--
|
||||
2.13.7
|
||||
|
@ -1,272 +0,0 @@
|
||||
From 23f976be51ba9ad6e1e173f23c7220144beb942a Mon Sep 17 00:00:00 2001
|
||||
From: Robert Schweikert <rjschwei@suse.com>
|
||||
Date: Tue, 14 Nov 2017 18:24:17 -0500
|
||||
Subject: [PATCH 1/3] - Support chrony configuration (lp#1731619) + Add a
|
||||
template for chrony configuration + Add new set_timesync_client to distros
|
||||
base class - Set the timesync client provided in the config by the user
|
||||
with system_info: ntp_client - If no user config set the timesync
|
||||
client to one of the supported clients if the executable is installed
|
||||
- Fall back to the distribution default + Handle the new settings in
|
||||
cc_ntp while retaining current behavior as the fallback until all distro
|
||||
implementations have switched to the new implementation + Use new way
|
||||
of ntp client configuration for openSUSE and SLES + Unit tests
|
||||
|
||||
---
|
||||
cloudinit/config/cc_ntp.py | 59 +++++++++----
|
||||
cloudinit/distros/__init__.py | 40 +++++++++
|
||||
cloudinit/distros/arch.py | 4 +
|
||||
cloudinit/distros/debian.py | 4 +
|
||||
cloudinit/distros/freebsd.py | 4 +
|
||||
cloudinit/distros/gentoo.py | 4 +
|
||||
cloudinit/distros/opensuse.py | 41 +++++++++
|
||||
cloudinit/distros/rhel.py | 4 +
|
||||
templates/chrony.conf.tmpl | 25 ++++++
|
||||
tests/unittests/test_distros/test_generic.py | 101 +++++++++++++++++++++--
|
||||
tests/unittests/test_distros/test_opensuse.py | 44 +++++++++-
|
||||
tests/unittests/test_distros/test_sles.py | 30 ++++++-
|
||||
tests/unittests/test_handler/test_handler_ntp.py | 80 ++++++++++++++----
|
||||
13 files changed, 400 insertions(+), 40 deletions(-)
|
||||
create mode 100644 templates/chrony.conf.tmpl
|
||||
|
||||
--- cloudinit/config/cc_ntp.py.orig
|
||||
+++ cloudinit/config/cc_ntp.py
|
||||
@@ -20,8 +20,9 @@ from textwrap import dedent
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
frequency = PER_INSTANCE
|
||||
-NTP_CONF = '/etc/ntp.conf'
|
||||
-TIMESYNCD_CONF = '/etc/systemd/timesyncd.conf.d/cloud-init.conf'
|
||||
+CHRONY_CONF_FILE = '/etc/chrony.conf'
|
||||
+NTP_CONF_FILE = '/etc/ntp.conf'
|
||||
+TIMESYNCD_CONF_FILE = '/etc/systemd/timesyncd.conf.d/cloud-init.conf'
|
||||
NR_POOL_SERVERS = 4
|
||||
distros = ['centos', 'debian', 'fedora', 'opensuse', 'sles', 'ubuntu']
|
||||
|
||||
@@ -49,6 +50,7 @@ schema = {
|
||||
'examples': [
|
||||
dedent("""\
|
||||
ntp:
|
||||
+ enabled: true
|
||||
pools: [0.int.pool.ntp.org, 1.int.pool.ntp.org, ntp.myorg.org]
|
||||
servers:
|
||||
- ntp.server.local
|
||||
@@ -60,6 +62,9 @@ schema = {
|
||||
'ntp': {
|
||||
'type': ['object', 'null'],
|
||||
'properties': {
|
||||
+ 'enabled': {
|
||||
+ "type": "boolean"
|
||||
+ },
|
||||
'pools': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
@@ -110,26 +115,48 @@ def handle(name, cfg, cloud, log, _args)
|
||||
"'ntp' key existed in config, but not a dictionary type,"
|
||||
" is a {_type} instead".format(_type=type_utils.obj_name(ntp_cfg)))
|
||||
|
||||
+ if ntp_cfg.get('enabled'):
|
||||
+ cloud.distro.set_timesync_client()
|
||||
+ else:
|
||||
+ # When all distro implementations are switched return here
|
||||
+ pass
|
||||
+
|
||||
validate_cloudconfig_schema(cfg, schema)
|
||||
- if ntp_installable():
|
||||
- service_name = 'ntp'
|
||||
- confpath = NTP_CONF
|
||||
- template_name = None
|
||||
- packages = ['ntp']
|
||||
- check_exe = 'ntpd'
|
||||
+ if hasattr(cloud.distro, 'timesync_client'):
|
||||
+ client_name = cloud.distro.timesync_client
|
||||
+ service_name = cloud.distro.timesync_service_name
|
||||
+ if client_name == 'ntp':
|
||||
+ confpath = NTP_CONF_FILE
|
||||
+ template_name = 'ntp.conf.%s' % cloud.distro.name
|
||||
+ elif client_name == 'systemd-timesyncd':
|
||||
+ confpath = TIMESYNCD_CONF_FILE
|
||||
+ template_name = 'timesyncd.conf'
|
||||
+ elif client_name == 'chrony':
|
||||
+ confpath = CHRONY_CONF_FILE
|
||||
+ template_name = 'chrony.conf.%s' % cloud.distro.name
|
||||
else:
|
||||
- service_name = 'systemd-timesyncd'
|
||||
- confpath = TIMESYNCD_CONF
|
||||
- template_name = 'timesyncd.conf'
|
||||
- packages = []
|
||||
- check_exe = '/lib/systemd/systemd-timesyncd'
|
||||
+ if ntp_installable():
|
||||
+ service_name = 'ntp'
|
||||
+ confpath = NTP_CONF_FILE
|
||||
+ template_name = None
|
||||
+ packages = ['ntp']
|
||||
+ check_exe = 'ntpd'
|
||||
+ else:
|
||||
+ service_name = 'systemd-timesyncd'
|
||||
+ confpath = TIMESYNCD_CONF_FILE
|
||||
+ template_name = 'timesyncd.conf'
|
||||
+ packages = []
|
||||
+ check_exe = '/lib/systemd/systemd-timesyncd'
|
||||
|
||||
- rename_ntp_conf()
|
||||
+ rename_ntp_conf(confpath)
|
||||
# ensure when ntp is installed it has a configuration file
|
||||
# to use instead of starting up with packaged defaults
|
||||
write_ntp_config_template(ntp_cfg, cloud, confpath, template=template_name)
|
||||
- install_ntp(cloud.distro.install_packages, packages=packages,
|
||||
- check_exe=check_exe)
|
||||
+ if not hasattr(cloud.distro, 'timesync_client'):
|
||||
+ # Updated implementation installs a package is missing in
|
||||
+ # distro._set_default_timesync_client
|
||||
+ install_ntp(cloud.distro.install_packages, packages=packages,
|
||||
+ check_exe=check_exe)
|
||||
|
||||
try:
|
||||
reload_ntp(service_name, systemd=cloud.distro.uses_systemd())
|
||||
@@ -167,7 +194,7 @@ def install_ntp(install_func, packages=N
|
||||
def rename_ntp_conf(config=None):
|
||||
"""Rename any existing ntp.conf file"""
|
||||
if config is None: # For testing
|
||||
- config = NTP_CONF
|
||||
+ config = NTP_CONF_FILE
|
||||
if os.path.exists(config):
|
||||
util.rename(config, config + ".dist")
|
||||
|
||||
--- cloudinit/distros/__init__.py.orig
|
||||
+++ cloudinit/distros/__init__.py
|
||||
@@ -61,6 +61,9 @@ class Distro(object):
|
||||
init_cmd = ['service'] # systemctl, service etc
|
||||
renderer_configs = {}
|
||||
|
||||
+ __timesync_client_map = {}
|
||||
+ __ntp_client_execs = []
|
||||
+
|
||||
def __init__(self, name, cfg, paths):
|
||||
self._paths = paths
|
||||
self._cfg = cfg
|
||||
@@ -90,6 +93,43 @@ class Distro(object):
|
||||
renderer.render_network_config(network_config=network_config)
|
||||
return []
|
||||
|
||||
+ def set_timesync_client(self):
|
||||
+ system_info = self._cfg.get('system_info')
|
||||
+ if system_info and isinstance(system_info, (dict)):
|
||||
+ ntp_client = system_info.get('ntp_client')
|
||||
+ if ntp_client and ntp_client in self.__timesync_client_map:
|
||||
+ self.timesync_client, self.timesync_service_name = \
|
||||
+ self.__timesync_client_map.get(ntp_client)
|
||||
+ LOG.debug('Using "%s" for timesync client per configuration',
|
||||
+ ntp_client)
|
||||
+ return
|
||||
+
|
||||
+ found = False
|
||||
+ for ntp_client in self.__ntp_client_execs:
|
||||
+ ntp_exec = util.which(ntp_client)
|
||||
+ if ntp_exec and not found:
|
||||
+ found = ntp_client
|
||||
+ # systemd-timesyncd is part of systemd and thus is probably
|
||||
+ # always installed, do not consider it as a conflict
|
||||
+ elif ntp_exec and found and 'systemd-timesyncd' not in ntp_exec:
|
||||
+ msg = 'Found multiple timesync clients installed. Resolve '
|
||||
+ msg += 'ambigutity by falling back to distro default'
|
||||
+ LOG.debug(msg)
|
||||
+ found = False
|
||||
+ break
|
||||
+
|
||||
+ if found and found in self.__timesync_client_map:
|
||||
+ self.timesync_client, self.timesync_service_name = \
|
||||
+ self.__timesync_client_map.get(found)
|
||||
+ LOG.debug('Using "%s" for timesync based on installed exec',
|
||||
+ ntp_client)
|
||||
+ return
|
||||
+
|
||||
+ self._set_default_timesync_client()
|
||||
+
|
||||
+ def _set_default_timesync_client(self):
|
||||
+ raise NotImplementedError()
|
||||
+
|
||||
def _find_tz_file(self, tz):
|
||||
tz_file = os.path.join(self.tz_zone_dir, str(tz))
|
||||
if not os.path.isfile(tz_file):
|
||||
--- /dev/null
|
||||
+++ templates/chrony.conf.tmpl
|
||||
@@ -0,0 +1,24 @@
|
||||
+## template:jinja
|
||||
+# cloud-init generated file
|
||||
+# See chrony.conf(5)
|
||||
+
|
||||
+{% if pools %}# pools
|
||||
+{% endif %}
|
||||
+{% for pool in pools -%}
|
||||
+pool {{pool}} iburst
|
||||
+{% endfor %}
|
||||
+{%- if servers %}# servers
|
||||
+{% endif %}
|
||||
+{% for server in servers -%}
|
||||
+server {{server}} iburst
|
||||
+{% endfor %}
|
||||
+
|
||||
+# Record the rate at which the the system clock gains/losses time
|
||||
+driftfile /var/lib/chrony/drift
|
||||
+
|
||||
+# Allow the system clock to be stepped in the first three updates
|
||||
+# if its offset is larger than 1 second.
|
||||
+makestep 1.0 3
|
||||
+
|
||||
+# Enable kernel synchronization of the real-time clock (RTC).
|
||||
+rtcsync
|
||||
--- cloudinit/distros/opensuse.py.orig
|
||||
+++ cloudinit/distros/opensuse.py
|
||||
@@ -36,6 +36,23 @@ class Distro(distros.Distro):
|
||||
systemd_locale_conf_fn = '/etc/locale.conf'
|
||||
tz_local_fn = '/etc/localtime'
|
||||
|
||||
+ __timesync_client_map = {
|
||||
+ # Map the system_info supported values
|
||||
+ 'chrony': ('chrony', 'chronyd'),
|
||||
+ 'isc-ntp': ('ntp', 'ntpd'),
|
||||
+ 'systemd-timesyncd': ('systemd-timesyncd', 'systemd-timesyncd'),
|
||||
+ # Map the common names if different from system_info
|
||||
+ 'chronyd': ('chrony', 'chronyd'),
|
||||
+ 'ntpd': ('ntp', 'ntpd'),
|
||||
+ '/usr/lib/systemd/systemd-timesyncd':
|
||||
+ ('systemd-timesyncd', 'systemd-timesyncd')
|
||||
+ }
|
||||
+ __ntp_client_execs = [
|
||||
+ 'chronyd',
|
||||
+ 'ntpd',
|
||||
+ '/usr/lib/systemd/systemd-timesyncd'
|
||||
+ ]
|
||||
+
|
||||
def __init__(self, name, cfg, paths):
|
||||
distros.Distro.__init__(self, name, cfg, paths)
|
||||
self._runner = helpers.Runners(paths)
|
||||
@@ -145,6 +162,28 @@ class Distro(distros.Distro):
|
||||
host_fn = self.hostname_conf_fn
|
||||
return (host_fn, self._read_hostname(host_fn))
|
||||
|
||||
+ def _set_default_timesync_client(self):
|
||||
+ """The default timesync client is dependent on the distribution."""
|
||||
+ # When we get here the user has configured ntp to be enabled but
|
||||
+ # no client is installed
|
||||
+ distro_info = util.get_linux_distro()
|
||||
+ name = distro_info[0]
|
||||
+ major_ver = int(distro_info[1].split('.')[0])
|
||||
+
|
||||
+ # This is horribly complicated because of a case of
|
||||
+ # "we do not care if versions should be increasing syndrome"
|
||||
+ if (
|
||||
+ (major_ver >= 15 and 'openSUSE' not in name) or
|
||||
+ (major_ver >= 15 and 'openSUSE' in name and major_ver != 42)
|
||||
+ ):
|
||||
+ self.timesync_client = 'chrony'
|
||||
+ self.timesync_service_name = 'chronyd'
|
||||
+ self.install_packages(['chrony'])
|
||||
+ else:
|
||||
+ self.timesync_client = 'ntp'
|
||||
+ self.timesync_service_name = 'ntpd'
|
||||
+ self.install_packages(['ntp'])
|
||||
+
|
||||
def _write_hostname(self, hostname, out_fn):
|
||||
if self.uses_systemd() and out_fn.endswith('/previous-hostname'):
|
||||
util.write_file(out_fn, hostname)
|
@ -1,682 +0,0 @@
|
||||
From 48c4dcd464d8c6daccf09b3dccc664ad347b34ce Mon Sep 17 00:00:00 2001
|
||||
From: Robert Schweikert <rjschwei@suse.com>
|
||||
Date: Mon, 18 Dec 2017 13:34:21 -0500
|
||||
Subject: [PATCH] - switch to using iproute2 tools + ifconfig, netstat and
|
||||
other tools are being deprecated, switch to using tools that are part of
|
||||
iproute2 for implementations that support these tools
|
||||
|
||||
---
|
||||
cloudinit/config/cc_disable_ec2_metadata.py | 14 +-
|
||||
.../config/tests/test_disable_ec2_metadata.py | 72 +++++
|
||||
cloudinit/netinfo.py | 302 +++++++++++++++------
|
||||
cloudinit/tests/test_netinfo.py | 174 +++++++++++-
|
||||
4 files changed, 474 insertions(+), 88 deletions(-)
|
||||
create mode 100644 cloudinit/config/tests/test_disable_ec2_metadata.py
|
||||
|
||||
diff --git a/cloudinit/config/cc_disable_ec2_metadata.py b/cloudinit/config/cc_disable_ec2_metadata.py
|
||||
index c56319b5..8a166ddf 100644
|
||||
--- a/cloudinit/config/cc_disable_ec2_metadata.py
|
||||
+++ b/cloudinit/config/cc_disable_ec2_metadata.py
|
||||
@@ -32,13 +32,23 @@ from cloudinit.settings import PER_ALWAYS
|
||||
|
||||
frequency = PER_ALWAYS
|
||||
|
||||
-REJECT_CMD = ['route', 'add', '-host', '169.254.169.254', 'reject']
|
||||
+REJECT_CMD_IF = ['route', 'add', '-host', '169.254.169.254', 'reject']
|
||||
+REJECT_CMD_IP = ['ip', 'route', 'add', 'prohibit', '169.254.169.254']
|
||||
|
||||
|
||||
def handle(name, cfg, _cloud, log, _args):
|
||||
disabled = util.get_cfg_option_bool(cfg, "disable_ec2_metadata", False)
|
||||
if disabled:
|
||||
- util.subp(REJECT_CMD, capture=False)
|
||||
+ reject_cmd = None
|
||||
+ if util.which('ifconfig'):
|
||||
+ reject_cmd = REJECT_CMD_IF
|
||||
+ elif util.which('ip'):
|
||||
+ reject_cmd = REJECT_CMD_IP
|
||||
+ else:
|
||||
+ log.error(('Neither "route" nor "ip" command found, unable to '
|
||||
+ 'manipulate routing table'))
|
||||
+ return
|
||||
+ util.subp(reject_cmd, capture=False)
|
||||
else:
|
||||
log.debug(("Skipping module named %s,"
|
||||
" disabling the ec2 route not enabled"), name)
|
||||
diff --git a/cloudinit/config/tests/test_disable_ec2_metadata.py b/cloudinit/config/tests/test_disable_ec2_metadata.py
|
||||
new file mode 100644
|
||||
index 00000000..bade814e
|
||||
--- /dev/null
|
||||
+++ b/cloudinit/config/tests/test_disable_ec2_metadata.py
|
||||
@@ -0,0 +1,72 @@
|
||||
+# This file is part of cloud-init. See LICENSE file for license information.
|
||||
+
|
||||
+"""Tests cc_disable_ec2_metadata handler"""
|
||||
+
|
||||
+import cloudinit.config.cc_disable_ec2_metadata as ec2_meta
|
||||
+
|
||||
+from cloudinit.tests.helpers import CiTestCase, mock
|
||||
+
|
||||
+import logging
|
||||
+
|
||||
+LOG = logging.getLogger(__name__)
|
||||
+
|
||||
+DISABLE_CFG = {'disable_ec2_metadata': 'true'}
|
||||
+
|
||||
+
|
||||
+class TestEC2MetadataRoute(CiTestCase):
|
||||
+
|
||||
+ @mock.patch('cloudinit.config.cc_disable_ec2_metadata.util.which')
|
||||
+ @mock.patch('cloudinit.config.cc_disable_ec2_metadata.util.subp')
|
||||
+ def test_disable_ifconfig(self, m_subp, m_which):
|
||||
+ """Set the route if ifconfig command is available"""
|
||||
+ m_subp.side_effect = command_check_ifconfig
|
||||
+ m_which.side_effect = side_effect_use_ifconfig
|
||||
+ ec2_meta.handle('foo', DISABLE_CFG, None, LOG, None)
|
||||
+
|
||||
+ @mock.patch('cloudinit.config.cc_disable_ec2_metadata.util.which')
|
||||
+ @mock.patch('cloudinit.config.cc_disable_ec2_metadata.util.subp')
|
||||
+ def test_disable_ip(self, m_subp, m_which):
|
||||
+ """Set the route if ip command is available"""
|
||||
+ m_subp.side_effect = command_check_ip
|
||||
+ m_which.side_effect = side_effect_use_ip
|
||||
+ ec2_meta.handle('foo', DISABLE_CFG, None, LOG, None)
|
||||
+
|
||||
+ @mock.patch('cloudinit.config.cc_disable_ec2_metadata.util.which')
|
||||
+ @mock.patch('cloudinit.config.cc_disable_ec2_metadata.util.subp')
|
||||
+ def test_disable_no_tool(self, m_subp, m_which):
|
||||
+ """Set the route if ip command is available"""
|
||||
+ m_subp.side_effect = command_dont_reach
|
||||
+ m_which.side_effect = side_effect_has_no_tool
|
||||
+ ec2_meta.handle('foo', DISABLE_CFG, None, LOG, None)
|
||||
+
|
||||
+
|
||||
+def side_effect_use_ifconfig(tool):
|
||||
+ if tool == 'ifconfig':
|
||||
+ return True
|
||||
+ else:
|
||||
+ return False
|
||||
+
|
||||
+
|
||||
+def side_effect_use_ip(tool):
|
||||
+ if tool == 'ip':
|
||||
+ return True
|
||||
+ else:
|
||||
+ return False
|
||||
+
|
||||
+
|
||||
+def side_effect_has_no_tool(tool):
|
||||
+ return False
|
||||
+
|
||||
+
|
||||
+def command_check_ifconfig(cmd, capture):
|
||||
+ assert(cmd == ['route', 'add', '-host', '169.254.169.254', 'reject'])
|
||||
+
|
||||
+
|
||||
+def command_check_ip(cmd, capture):
|
||||
+ assert(cmd == ['ip', 'route', 'add', 'prohibit', '169.254.169.254'])
|
||||
+
|
||||
+
|
||||
+def command_dont_reach(cmd, capture):
|
||||
+ assert('Test should not have reached this location' == 0)
|
||||
+
|
||||
+# vi: ts=4 expandtab
|
||||
diff --git a/cloudinit/netinfo.py b/cloudinit/netinfo.py
|
||||
index 993b26cf..baad3f92 100644
|
||||
--- a/cloudinit/netinfo.py
|
||||
+++ b/cloudinit/netinfo.py
|
||||
@@ -19,6 +19,117 @@ LOG = logging.getLogger()
|
||||
|
||||
|
||||
def netdev_info(empty=""):
|
||||
+ if util.which('ifconfig'):
|
||||
+ return _netdev_info_from_ifconfig(empty)
|
||||
+ elif util.which('ip'):
|
||||
+ return _netdev_info_from_ip(empty)
|
||||
+ else:
|
||||
+ LOG.error(('Neither "ifconfig" nor "ip" command found, unable to '
|
||||
+ 'collect network device information'))
|
||||
+ return {}
|
||||
+
|
||||
+
|
||||
+def route_info():
|
||||
+ if util.which('netstat'):
|
||||
+ return _route_info_from_netstat()
|
||||
+ elif util.which('ip'):
|
||||
+ return _route_info_from_ip()
|
||||
+ else:
|
||||
+ LOG.error(('Neither "netstat" nor "ip" command found, unable to '
|
||||
+ 'collect routing information'))
|
||||
+ return {}
|
||||
+
|
||||
+
|
||||
+def getgateway():
|
||||
+ try:
|
||||
+ routes = route_info()
|
||||
+ except Exception:
|
||||
+ pass
|
||||
+ else:
|
||||
+ for r in routes.get('ipv4', []):
|
||||
+ if r['flags'].find("G") >= 0:
|
||||
+ return "%s[%s]" % (r['gateway'], r['iface'])
|
||||
+ return None
|
||||
+
|
||||
+
|
||||
+def netdev_pformat():
|
||||
+ lines = []
|
||||
+ try:
|
||||
+ netdev = netdev_info(empty=".")
|
||||
+ except Exception:
|
||||
+ lines.append(util.center("Net device info failed", '!', 80))
|
||||
+ else:
|
||||
+ fields = ['Device', 'Up', 'Address', 'Mask', 'Scope', 'Hw-Address']
|
||||
+ tbl = SimpleTable(fields)
|
||||
+ for (dev, d) in sorted(netdev.items()):
|
||||
+ tbl.add_row([dev, d["up"], d["addr"], d["mask"], ".", d["hwaddr"]])
|
||||
+ if d.get('addr6'):
|
||||
+ tbl.add_row([dev, d["up"],
|
||||
+ d["addr6"], ".", d.get("scope6"), d["hwaddr"]])
|
||||
+ netdev_s = tbl.get_string()
|
||||
+ max_len = len(max(netdev_s.splitlines(), key=len))
|
||||
+ header = util.center("Net device info", "+", max_len)
|
||||
+ lines.extend([header, netdev_s])
|
||||
+ return "\n".join(lines)
|
||||
+
|
||||
+
|
||||
+def route_pformat():
|
||||
+ lines = []
|
||||
+ try:
|
||||
+ routes = route_info()
|
||||
+ except Exception as e:
|
||||
+ lines.append(util.center('Route info failed', '!', 80))
|
||||
+ util.logexc(LOG, "Route info failed: %s" % e)
|
||||
+ else:
|
||||
+ if routes.get('ipv4'):
|
||||
+ fields_v4 = ['Route', 'Destination', 'Gateway',
|
||||
+ 'Genmask', 'Interface', 'Flags']
|
||||
+ tbl_v4 = SimpleTable(fields_v4)
|
||||
+ for (n, r) in enumerate(routes.get('ipv4')):
|
||||
+ route_id = str(n)
|
||||
+ tbl_v4.add_row([route_id, r['destination'],
|
||||
+ r['gateway'], r['genmask'],
|
||||
+ r['iface'], r['flags']])
|
||||
+ route_s = tbl_v4.get_string()
|
||||
+ max_len = len(max(route_s.splitlines(), key=len))
|
||||
+ header = util.center("Route IPv4 info", "+", max_len)
|
||||
+ lines.extend([header, route_s])
|
||||
+ if routes.get('ipv6'):
|
||||
+ fields_v6 = ['Route', 'Proto', 'Recv-Q', 'Send-Q',
|
||||
+ 'Local Address', 'Foreign Address', 'State']
|
||||
+ tbl_v6 = SimpleTable(fields_v6)
|
||||
+ for (n, r) in enumerate(routes.get('ipv6')):
|
||||
+ route_id = str(n)
|
||||
+ tbl_v6.add_row([route_id, r['proto'],
|
||||
+ r['recv-q'], r['send-q'],
|
||||
+ r['local address'], r['foreign address'],
|
||||
+ r['state']])
|
||||
+ route_s = tbl_v6.get_string()
|
||||
+ max_len = len(max(route_s.splitlines(), key=len))
|
||||
+ header = util.center("Route IPv6 info", "+", max_len)
|
||||
+ lines.extend([header, route_s])
|
||||
+ return "\n".join(lines)
|
||||
+
|
||||
+
|
||||
+def debug_info(prefix='ci-info: '):
|
||||
+ lines = []
|
||||
+ netdev_lines = netdev_pformat().splitlines()
|
||||
+ if prefix:
|
||||
+ for line in netdev_lines:
|
||||
+ lines.append("%s%s" % (prefix, line))
|
||||
+ else:
|
||||
+ lines.extend(netdev_lines)
|
||||
+ route_lines = route_pformat().splitlines()
|
||||
+ if prefix:
|
||||
+ for line in route_lines:
|
||||
+ lines.append("%s%s" % (prefix, line))
|
||||
+ else:
|
||||
+ lines.extend(route_lines)
|
||||
+ return "\n".join(lines)
|
||||
+
|
||||
+
|
||||
+def _netdev_info_from_ifconfig(empty=""):
|
||||
+ """Use legacy ifconfig output"""
|
||||
fields = ("hwaddr", "addr", "bcast", "mask")
|
||||
(ifcfg_out, _err) = util.subp(["ifconfig", "-a"], rcs=[0, 1])
|
||||
devs = {}
|
||||
@@ -84,7 +195,54 @@ def netdev_info(empty=""):
|
||||
return devs
|
||||
|
||||
|
||||
-def route_info():
|
||||
+def _netdev_info_from_ip(empty=""):
|
||||
+ """Use ip to get network information"""
|
||||
+ fields = ("hwaddr", "addr", "bcast", "mask")
|
||||
+ (ipdata_out, _err) = util.subp(["ip", "a"], rcs=[0, 1])
|
||||
+ devs = {}
|
||||
+ this_device = None
|
||||
+ for line in str(ipdata_out).splitlines():
|
||||
+ if len(line) == 0:
|
||||
+ continue
|
||||
+ if line[0].isdigit():
|
||||
+ prts = line.strip().split(':')
|
||||
+ this_device = prts[1].strip()
|
||||
+ devs[this_device] = {}
|
||||
+ for field in fields:
|
||||
+ devs[this_device][field] = ''
|
||||
+ devs[this_device]['up'] = False
|
||||
+ status_info = re.match('(<)(.*)(>)', prts[-1].strip()).group(2)
|
||||
+ status_info = status_info.lower().split(',')
|
||||
+ if 'up' in status_info:
|
||||
+ devs[this_device]['up'] = True
|
||||
+ if 'broadcast' in status_info and 'multicast' in status_info:
|
||||
+ devs[this_device]['bcast'] = 'multicast'
|
||||
+ continue
|
||||
+ conf_data = line.strip()
|
||||
+ conf_data_prts = conf_data.split()
|
||||
+ if conf_data.startswith('inet '):
|
||||
+ devs[this_device]['addr'] = conf_data_prts[1]
|
||||
+ if 'brd' in conf_data_prts:
|
||||
+ loc = conf_data_prts.index('brd')
|
||||
+ devs[this_device]['bcast'] = conf_data_prts[loc + 1]
|
||||
+ if conf_data.startswith('inet6'):
|
||||
+ devs[this_device]['addr6'] = conf_data_prts[1]
|
||||
+ if 'scope' in conf_data_prts:
|
||||
+ loc = conf_data_prts.index('scope')
|
||||
+ devs[this_device]['scope6'] = conf_data_prts[loc + 1]
|
||||
+ if conf_data.startswith('link/ether'):
|
||||
+ devs[this_device]['hwaddr'] = conf_data_prts[1]
|
||||
+
|
||||
+ if empty != "":
|
||||
+ for (_devname, dev) in devs.items():
|
||||
+ for field in dev:
|
||||
+ if dev[field] == "":
|
||||
+ dev[field] = empty
|
||||
+
|
||||
+ return devs
|
||||
+
|
||||
+
|
||||
+def _route_info_from_netstat():
|
||||
(route_out, _err) = util.subp(["netstat", "-rn"], rcs=[0, 1])
|
||||
|
||||
routes = {}
|
||||
@@ -150,91 +308,69 @@ def route_info():
|
||||
return routes
|
||||
|
||||
|
||||
-def getgateway():
|
||||
- try:
|
||||
- routes = route_info()
|
||||
- except Exception:
|
||||
- pass
|
||||
- else:
|
||||
- for r in routes.get('ipv4', []):
|
||||
- if r['flags'].find("G") >= 0:
|
||||
- return "%s[%s]" % (r['gateway'], r['iface'])
|
||||
- return None
|
||||
-
|
||||
-
|
||||
-def netdev_pformat():
|
||||
- lines = []
|
||||
- try:
|
||||
- netdev = netdev_info(empty=".")
|
||||
- except Exception:
|
||||
- lines.append(util.center("Net device info failed", '!', 80))
|
||||
- else:
|
||||
- fields = ['Device', 'Up', 'Address', 'Mask', 'Scope', 'Hw-Address']
|
||||
- tbl = SimpleTable(fields)
|
||||
- for (dev, d) in sorted(netdev.items()):
|
||||
- tbl.add_row([dev, d["up"], d["addr"], d["mask"], ".", d["hwaddr"]])
|
||||
- if d.get('addr6'):
|
||||
- tbl.add_row([dev, d["up"],
|
||||
- d["addr6"], ".", d.get("scope6"), d["hwaddr"]])
|
||||
- netdev_s = tbl.get_string()
|
||||
- max_len = len(max(netdev_s.splitlines(), key=len))
|
||||
- header = util.center("Net device info", "+", max_len)
|
||||
- lines.extend([header, netdev_s])
|
||||
- return "\n".join(lines)
|
||||
+def _route_info_from_ip():
|
||||
+ """Detremine route information from ip route command"""
|
||||
+ routes = {}
|
||||
+ routes['ipv4'] = []
|
||||
+ routes['ipv6'] = []
|
||||
|
||||
+ # IPv4
|
||||
+ (route_out, _err) = util.subp(['ip', '-4', 'route', 'list'], rcs=[0, 1])
|
||||
|
||||
-def route_pformat():
|
||||
- lines = []
|
||||
- try:
|
||||
- routes = route_info()
|
||||
- except Exception as e:
|
||||
- lines.append(util.center('Route info failed', '!', 80))
|
||||
- util.logexc(LOG, "Route info failed: %s" % e)
|
||||
- else:
|
||||
- if routes.get('ipv4'):
|
||||
- fields_v4 = ['Route', 'Destination', 'Gateway',
|
||||
- 'Genmask', 'Interface', 'Flags']
|
||||
- tbl_v4 = SimpleTable(fields_v4)
|
||||
- for (n, r) in enumerate(routes.get('ipv4')):
|
||||
- route_id = str(n)
|
||||
- tbl_v4.add_row([route_id, r['destination'],
|
||||
- r['gateway'], r['genmask'],
|
||||
- r['iface'], r['flags']])
|
||||
- route_s = tbl_v4.get_string()
|
||||
- max_len = len(max(route_s.splitlines(), key=len))
|
||||
- header = util.center("Route IPv4 info", "+", max_len)
|
||||
- lines.extend([header, route_s])
|
||||
- if routes.get('ipv6'):
|
||||
- fields_v6 = ['Route', 'Proto', 'Recv-Q', 'Send-Q',
|
||||
- 'Local Address', 'Foreign Address', 'State']
|
||||
- tbl_v6 = SimpleTable(fields_v6)
|
||||
- for (n, r) in enumerate(routes.get('ipv6')):
|
||||
- route_id = str(n)
|
||||
- tbl_v6.add_row([route_id, r['proto'],
|
||||
- r['recv-q'], r['send-q'],
|
||||
- r['local address'], r['foreign address'],
|
||||
- r['state']])
|
||||
- route_s = tbl_v6.get_string()
|
||||
- max_len = len(max(route_s.splitlines(), key=len))
|
||||
- header = util.center("Route IPv6 info", "+", max_len)
|
||||
- lines.extend([header, route_s])
|
||||
- return "\n".join(lines)
|
||||
+ entries = route_out.splitlines()
|
||||
+ for line in entries:
|
||||
+ route_info = line.strip().split()
|
||||
+ dest = route_info[0]
|
||||
+ if route_info[0] == 'default':
|
||||
+ dest = '0.0.0.0'
|
||||
+ flags = ''
|
||||
+ gw = '0.0.0.0'
|
||||
+ if 'via' in route_info:
|
||||
+ loc = route_info.index('via')
|
||||
+ # The NH (Next Hop) is basically equivalent to the gateway
|
||||
+ gw = route_info[loc + 1]
|
||||
+ flags = 'G'
|
||||
+ loc = route_info.index('dev')
|
||||
+ dev = route_info[loc + 1]
|
||||
+ entry = {
|
||||
+ 'destination': dest,
|
||||
+ 'gateway': gw,
|
||||
+ 'genmask': '',
|
||||
+ 'flags': flags,
|
||||
+ 'metric': '0',
|
||||
+ 'ref': '0',
|
||||
+ 'use': '0',
|
||||
+ 'iface': dev
|
||||
+ }
|
||||
+ routes['ipv4'].append(entry)
|
||||
|
||||
+ # IPv6
|
||||
+ (route_out, _err) = util.subp(['ip', '-6', 'route', 'list'], rcs=[0, 1])
|
||||
|
||||
-def debug_info(prefix='ci-info: '):
|
||||
- lines = []
|
||||
- netdev_lines = netdev_pformat().splitlines()
|
||||
- if prefix:
|
||||
- for line in netdev_lines:
|
||||
- lines.append("%s%s" % (prefix, line))
|
||||
- else:
|
||||
- lines.extend(netdev_lines)
|
||||
- route_lines = route_pformat().splitlines()
|
||||
- if prefix:
|
||||
- for line in route_lines:
|
||||
- lines.append("%s%s" % (prefix, line))
|
||||
- else:
|
||||
- lines.extend(route_lines)
|
||||
- return "\n".join(lines)
|
||||
+ entries = route_out.splitlines()
|
||||
+ for line in entries:
|
||||
+ route_info = line.strip().split()
|
||||
+ ip = route_info[0]
|
||||
+ if ip == 'default':
|
||||
+ ip = '::'
|
||||
+ proto = 'tcp6'
|
||||
+ if 'proto' in route_info:
|
||||
+ loc = route_info.index('proto')
|
||||
+ proto = route_info[loc + 1]
|
||||
+ gw = ''
|
||||
+ if 'via' in route_info:
|
||||
+ loc = route_info.index('via')
|
||||
+ # The NH (Next Hop) is basically equivalent to the gateway
|
||||
+ gw = route_info[loc + 1]
|
||||
+ entry = {
|
||||
+ 'proto': proto,
|
||||
+ 'recv-q': '0',
|
||||
+ 'send-q': '0',
|
||||
+ 'local address': ip,
|
||||
+ 'foreign address': gw,
|
||||
+ 'state': '',
|
||||
+ }
|
||||
+ routes['ipv6'].append(entry)
|
||||
+ return routes
|
||||
|
||||
# vi: ts=4 expandtab
|
||||
diff --git a/cloudinit/tests/test_netinfo.py b/cloudinit/tests/test_netinfo.py
|
||||
index 7dea2e41..3dc557cc 100644
|
||||
--- a/cloudinit/tests/test_netinfo.py
|
||||
+++ b/cloudinit/tests/test_netinfo.py
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
"""Tests netinfo module functions and classes."""
|
||||
|
||||
-from cloudinit.netinfo import netdev_pformat, route_pformat
|
||||
+from cloudinit.netinfo import getgateway, netdev_pformat, route_pformat
|
||||
from cloudinit.tests.helpers import CiTestCase, mock
|
||||
|
||||
|
||||
@@ -27,6 +27,48 @@ lo Link encap:Local Loopback
|
||||
collisions:0 txqueuelen:1
|
||||
"""
|
||||
|
||||
+SAMPLE_IP_A_OUT = (
|
||||
+ '1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN '
|
||||
+ 'group default qlen 1000\n'
|
||||
+ 'link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n'
|
||||
+ 'inet 127.0.0.1/8 scope host lo\n'
|
||||
+ ' valid_lft forever preferred_lft forever\n'
|
||||
+ 'inet6 ::1/128 scope host\n'
|
||||
+ ' valid_lft forever preferred_lft forever\n'
|
||||
+ '2: wlp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state '
|
||||
+ 'UP group default qlen 1000\n'
|
||||
+ 'link/ether 84:3a:4b:09:6f:ec brd ff:ff:ff:ff:ff:ff\n'
|
||||
+ 'inet 192.168.1.101/24 brd 192.168.1.255 scope global wlp3s0\n'
|
||||
+ ' valid_lft forever preferred_lft forever\n'
|
||||
+ 'inet 192.168.1.3/24 brd 192.168.1.255 scope global secondary wlp3s0\n'
|
||||
+ ' valid_lft forever preferred_lft forever\n'
|
||||
+ 'inet6 fe80::863a:4bff:fe09:6fec/64 scope link\n'
|
||||
+ ' valid_lft forever preferred_lft forever'
|
||||
+)
|
||||
+
|
||||
+SAMPLE_ROUTE_INFO = {
|
||||
+ 'ipv4': [
|
||||
+ {
|
||||
+ 'genmask': '0.0.0.0',
|
||||
+ 'use': '0',
|
||||
+ 'iface': 'eth1',
|
||||
+ 'flags': 'UG',
|
||||
+ 'metric': '0',
|
||||
+ 'destination': '0.0.0.0',
|
||||
+ 'ref': '0',
|
||||
+ 'gateway': '192.168.1.1'},
|
||||
+ {
|
||||
+ 'genmask': '255.0.0.0',
|
||||
+ 'use': '0',
|
||||
+ 'iface': 'eth2',
|
||||
+ 'flags': 'UG',
|
||||
+ 'metric': '0',
|
||||
+ 'destination': '10.0.0.0',
|
||||
+ 'ref': '0',
|
||||
+ 'gateway': '10.163.8.1'}
|
||||
+ ]
|
||||
+}
|
||||
+
|
||||
SAMPLE_ROUTE_OUT = '\n'.join([
|
||||
'0.0.0.0 192.168.2.1 0.0.0.0 UG 0 0 0'
|
||||
' enp0s25',
|
||||
@@ -35,6 +77,20 @@ SAMPLE_ROUTE_OUT = '\n'.join([
|
||||
'192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0'
|
||||
' enp0s25'])
|
||||
|
||||
+SAMPLE_ROUTE_OUT_IP_V4 = '\n'.join([
|
||||
+ 'default via 192.168.1.1 dev br0',
|
||||
+ '10.0.0.0/8 via 10.163.8.1 dev tun0',
|
||||
+ '10.163.8.1 dev tun0 proto kernel scope link src 10.163.8.118 ',
|
||||
+ '137.65.0.0/16 via 10.163.8.1 dev tun0'])
|
||||
+
|
||||
+SAMPLE_ROUTE_OUT_IP_V6 = '\n'.join([
|
||||
+ '2621:111:80c0:8080:12:160:68:53 dev eth0 proto kernel metric 256 expires '
|
||||
+ '9178sec pref medium',
|
||||
+ '2621:111:80c0:8080::/64 dev eth0 proto ra metric 100 pref medium',
|
||||
+ 'fe80::1 dev eth0 proto static metric 100 pref medium',
|
||||
+ 'fe80::/64 dev eth0 proto kernel metric 256 pref medium',
|
||||
+ 'default via fe80::1 dev eth0 proto static metric 100 pref medium',
|
||||
+ '2620:113:80c0:8000::/50 dev tun0 metric 1024 pref medium'])
|
||||
|
||||
NETDEV_FORMATTED_OUT = '\n'.join([
|
||||
'+++++++++++++++++++++++++++++++++++++++Net device info+++++++++++++++++++'
|
||||
@@ -56,6 +112,26 @@ NETDEV_FORMATTED_OUT = '\n'.join([
|
||||
'+---------+------+------------------------------+---------------+-------+'
|
||||
'-------------------+'])
|
||||
|
||||
+NETDEV_FORMATTED_OUT_IP = '\n'.join([
|
||||
+ '++++++++++++++++++++++++++++++++++Net device info++++++++++++++++++++++'
|
||||
+ '++++++++++++',
|
||||
+ '+--------+------+------------------------------+------+-------+----------'
|
||||
+ '---------+',
|
||||
+ '| Device | Up | Address | Mask | Scope | Hw-Ad'
|
||||
+ 'dress |',
|
||||
+ '+--------+------+------------------------------+------+-------+----------'
|
||||
+ '---------+',
|
||||
+ '| lo | True | 127.0.0.1/8 | . | . | .'
|
||||
+ ' |',
|
||||
+ '| lo | True | ::1/128 | . | host | .'
|
||||
+ ' |',
|
||||
+ '| wlp3s0 | True | 192.168.1.3/24 | . | . | 84:3a:4b:'
|
||||
+ '09:6f:ec |',
|
||||
+ '| wlp3s0 | True | fe80::863a:4bff:fe09:6fec/64 | . | link | 84:3a:4b:'
|
||||
+ '09:6f:ec |',
|
||||
+ '+--------+------+------------------------------+------+-------+----------'
|
||||
+ '---------+'])
|
||||
+
|
||||
ROUTE_FORMATTED_OUT = '\n'.join([
|
||||
'+++++++++++++++++++++++++++++Route IPv4 info++++++++++++++++++++++++++'
|
||||
'+++',
|
||||
@@ -86,21 +162,113 @@ ROUTE_FORMATTED_OUT = '\n'.join([
|
||||
'+-------+-------------+-------------+---------------+---------------+'
|
||||
'-----------------+-------+'])
|
||||
|
||||
+ROUTE_FORMATTED_OUT_IP = '\n'.join([
|
||||
+ '+++++++++++++++++++++++++++Route IPv4 info+++++++++++++++++++++++++++',
|
||||
+ '+-------+---------------+-------------+---------+-----------+-------+',
|
||||
+ '| Route | Destination | Gateway | Genmask | Interface | Flags |',
|
||||
+ '+-------+---------------+-------------+---------+-----------+-------+',
|
||||
+ '| 0 | 0.0.0.0 | 192.168.1.1 | | br0 | G |',
|
||||
+ '| 1 | 10.0.0.0/8 | 10.163.8.1 | | tun0 | G |',
|
||||
+ '| 2 | 10.163.8.1 | 0.0.0.0 | | tun0 | |',
|
||||
+ '| 3 | 137.65.0.0/16 | 10.163.8.1 | | tun0 | G |',
|
||||
+ '+-------+---------------+-------------+---------+-----------+-------+',
|
||||
+ '++++++++++++++++++++++++++++++++++++++++Route IPv6 info++++++++++++++'
|
||||
+ '+++++++++++++++++++++++++++',
|
||||
+ '+-------+--------+--------+--------+---------------------------------'
|
||||
+ '+-----------------+-------+',
|
||||
+ '| Route | Proto | Recv-Q | Send-Q | Local Address '
|
||||
+ '| Foreign Address | State |',
|
||||
+ '+-------+--------+--------+--------+---------------------------------'
|
||||
+ '+-----------------+-------+',
|
||||
+ '| 0 | kernel | 0 | 0 | 2621:111:80c0:8080:12:160:68:53 '
|
||||
+ '| | |',
|
||||
+ '| 1 | ra | 0 | 0 | 2621:111:80c0:8080::/64 '
|
||||
+ '| | |',
|
||||
+ '| 2 | static | 0 | 0 | fe80::1 '
|
||||
+ '| | |',
|
||||
+ '| 3 | kernel | 0 | 0 | fe80::/64 '
|
||||
+ '| | |',
|
||||
+ '| 4 | static | 0 | 0 | :: '
|
||||
+ '| fe80::1 | |',
|
||||
+ '| 5 | tcp6 | 0 | 0 | 2620:113:80c0:8000::/50 '
|
||||
+ '| | |',
|
||||
+ '+-------+--------+--------+--------+---------------------------------'
|
||||
+ '+-----------------+-------+'])
|
||||
+
|
||||
|
||||
class TestNetInfo(CiTestCase):
|
||||
|
||||
maxDiff = None
|
||||
|
||||
+ @mock.patch('cloudinit.netinfo.route_info')
|
||||
+ def test_getdateway_route(self, m_route_info):
|
||||
+ """getgateway finds the first gateway"""
|
||||
+ m_route_info.return_value = SAMPLE_ROUTE_INFO
|
||||
+ gateway = getgateway()
|
||||
+ self.assertEqual('192.168.1.1[eth1]', gateway)
|
||||
+
|
||||
+ @mock.patch('cloudinit.netinfo.util.which')
|
||||
@mock.patch('cloudinit.netinfo.util.subp')
|
||||
- def test_netdev_pformat(self, m_subp):
|
||||
+ def test_netdev_pformat_ifconfig(self, m_subp, m_which):
|
||||
"""netdev_pformat properly rendering network device information."""
|
||||
m_subp.return_value = (SAMPLE_IFCONFIG_OUT, '')
|
||||
+ m_which.side_effect = side_effect_use_ifconfig
|
||||
content = netdev_pformat()
|
||||
self.assertEqual(NETDEV_FORMATTED_OUT, content)
|
||||
|
||||
+ @mock.patch('cloudinit.netinfo.util.which')
|
||||
@mock.patch('cloudinit.netinfo.util.subp')
|
||||
- def test_route_pformat(self, m_subp):
|
||||
+ def test_netdev_pformat_ip(self, m_subp, m_which):
|
||||
+ """netdev_pformat properly rendering network device information."""
|
||||
+ m_subp.return_value = (SAMPLE_IP_A_OUT, '')
|
||||
+ m_which.side_effect = side_effect_use_ip
|
||||
+ content = netdev_pformat()
|
||||
+ self.assertEqual(NETDEV_FORMATTED_OUT_IP, content)
|
||||
+
|
||||
+ @mock.patch('cloudinit.netinfo.util.which')
|
||||
+ @mock.patch('cloudinit.netinfo.util.subp')
|
||||
+ def test_route_pformat_netstat(self, m_subp, m_which):
|
||||
"""netdev_pformat properly rendering network device information."""
|
||||
m_subp.return_value = (SAMPLE_ROUTE_OUT, '')
|
||||
+ m_which.side_effect = side_effect_use_netstat
|
||||
content = route_pformat()
|
||||
self.assertEqual(ROUTE_FORMATTED_OUT, content)
|
||||
+
|
||||
+ @mock.patch('cloudinit.netinfo.util.which')
|
||||
+ @mock.patch('cloudinit.netinfo.util.subp')
|
||||
+ def test_route_pformat_ip(self, m_subp, m_which):
|
||||
+ """netdev_pformat properly rendering network device information."""
|
||||
+ m_subp.side_effect = side_effect_return_route_info
|
||||
+ m_which.side_effect = side_effect_use_ip
|
||||
+ content = route_pformat()
|
||||
+ self.assertEqual(ROUTE_FORMATTED_OUT_IP, content)
|
||||
+
|
||||
+
|
||||
+def side_effect_use_ifconfig(tool):
|
||||
+ if tool == 'ifconfig':
|
||||
+ return True
|
||||
+ else:
|
||||
+ return False
|
||||
+
|
||||
+
|
||||
+def side_effect_use_ip(tool):
|
||||
+ if tool == 'ip':
|
||||
+ return True
|
||||
+ else:
|
||||
+ return False
|
||||
+
|
||||
+
|
||||
+def side_effect_use_netstat(tool):
|
||||
+ if tool == 'netstat':
|
||||
+ return True
|
||||
+ else:
|
||||
+ return False
|
||||
+
|
||||
+
|
||||
+def side_effect_return_route_info(cmd, rcs=None):
|
||||
+ if '-4' in list(cmd):
|
||||
+ return (SAMPLE_ROUTE_OUT_IP_V4, 0)
|
||||
+ else:
|
||||
+ return (SAMPLE_ROUTE_OUT_IP_V6, 0)
|
||||
+
|
||||
+# vi: ts=4 expandtab
|
||||
--
|
||||
2.13.6
|
||||
|
109
0002-Add-tests-for-additional-openSUSE-distro-condition-m.patch
Normal file
109
0002-Add-tests-for-additional-openSUSE-distro-condition-m.patch
Normal file
@ -0,0 +1,109 @@
|
||||
From 33d988113c3897ea7e0d1eda402d30dfec119602 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Schweikert <rjschwei@suse.com>
|
||||
Date: Sun, 21 Oct 2018 08:46:15 -0400
|
||||
Subject: [PATCH 2/2] - Add tests for additional openSUSE distro condition
|
||||
mechanisms
|
||||
|
||||
---
|
||||
cloudinit/tests/test_util.py | 75 ++++++++++++++++++++++++++++++++++----------
|
||||
1 file changed, 59 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/tests/test_util.py b/cloudinit/tests/test_util.py
|
||||
index 749a3846..c3f52c7b 100644
|
||||
--- a/cloudinit/tests/test_util.py
|
||||
+++ b/cloudinit/tests/test_util.py
|
||||
@@ -18,25 +18,51 @@ MOUNT_INFO = [
|
||||
]
|
||||
|
||||
OS_RELEASE_SLES = dedent("""\
|
||||
- NAME="SLES"\n
|
||||
- VERSION="12-SP3"\n
|
||||
- VERSION_ID="12.3"\n
|
||||
- PRETTY_NAME="SUSE Linux Enterprise Server 12 SP3"\n
|
||||
- ID="sles"\nANSI_COLOR="0;32"\n
|
||||
- CPE_NAME="cpe:/o:suse:sles:12:sp3"\n
|
||||
+ NAME="SLES"
|
||||
+ VERSION="12-SP3"
|
||||
+ VERSION_ID="12.3"
|
||||
+ PRETTY_NAME="SUSE Linux Enterprise Server 12 SP3"
|
||||
+ ID="sles"
|
||||
+ ANSI_COLOR="0;32"
|
||||
+ CPE_NAME="cpe:/o:suse:sles:12:sp3"
|
||||
""")
|
||||
|
||||
OS_RELEASE_OPENSUSE = dedent("""\
|
||||
-NAME="openSUSE Leap"
|
||||
-VERSION="42.3"
|
||||
-ID=opensuse
|
||||
-ID_LIKE="suse"
|
||||
-VERSION_ID="42.3"
|
||||
-PRETTY_NAME="openSUSE Leap 42.3"
|
||||
-ANSI_COLOR="0;32"
|
||||
-CPE_NAME="cpe:/o:opensuse:leap:42.3"
|
||||
-BUG_REPORT_URL="https://bugs.opensuse.org"
|
||||
-HOME_URL="https://www.opensuse.org/"
|
||||
+ NAME="openSUSE Leap"
|
||||
+ VERSION="42.3"
|
||||
+ ID=opensuse
|
||||
+ ID_LIKE="suse"
|
||||
+ VERSION_ID="42.3"
|
||||
+ PRETTY_NAME="openSUSE Leap 42.3"
|
||||
+ ANSI_COLOR="0;32"
|
||||
+ CPE_NAME="cpe:/o:opensuse:leap:42.3"
|
||||
+ BUG_REPORT_URL="https://bugs.opensuse.org"
|
||||
+ HOME_URL="https://www.opensuse.org/"
|
||||
+""")
|
||||
+
|
||||
+OS_RELEASE_OPENSUSE_L15 = dedent("""\
|
||||
+ NAME="openSUSE Leap"
|
||||
+ VERSION="15.0"
|
||||
+ ID="opensuse-leap"
|
||||
+ ID_LIKE="suse opensuse"
|
||||
+ VERSION_ID="15.0"
|
||||
+ PRETTY_NAME="openSUSE Leap 15.0"
|
||||
+ ANSI_COLOR="0;32"
|
||||
+ CPE_NAME="cpe:/o:opensuse:leap:15.0"
|
||||
+ BUG_REPORT_URL="https://bugs.opensuse.org"
|
||||
+ HOME_URL="https://www.opensuse.org/"
|
||||
+""")
|
||||
+
|
||||
+OS_RELEASE_OPENSUSE_TW = dedent("""\
|
||||
+ NAME="openSUSE Tumbleweed"
|
||||
+ ID="opensuse-tumbleweed"
|
||||
+ ID_LIKE="opensuse suse"
|
||||
+ VERSION_ID="20180920"
|
||||
+ PRETTY_NAME="openSUSE Tumbleweed"
|
||||
+ ANSI_COLOR="0;32"
|
||||
+ CPE_NAME="cpe:/o:opensuse:tumbleweed:20180920"
|
||||
+ BUG_REPORT_URL="https://bugs.opensuse.org"
|
||||
+ HOME_URL="https://www.opensuse.org/"
|
||||
""")
|
||||
|
||||
OS_RELEASE_CENTOS = dedent("""\
|
||||
@@ -453,6 +479,23 @@ class TestGetLinuxDistro(CiTestCase):
|
||||
dist = util.get_linux_distro()
|
||||
self.assertEqual(('opensuse', '42.3', platform.machine()), dist)
|
||||
|
||||
+ @mock.patch('cloudinit.util.load_file')
|
||||
+ def test_get_linux_opensuse_l15(self, m_os_release, m_path_exists):
|
||||
+ """Verify we get the correct name and machine arch on OpenSUSE."""
|
||||
+ m_os_release.return_value = OS_RELEASE_OPENSUSE_L15
|
||||
+ m_path_exists.side_effect = TestGetLinuxDistro.os_release_exists
|
||||
+ dist = util.get_linux_distro()
|
||||
+ self.assertEqual(('opensuse-leap', '15.0', platform.machine()), dist)
|
||||
+
|
||||
+ @mock.patch('cloudinit.util.load_file')
|
||||
+ def test_get_linux_opensuse_tw(self, m_os_release, m_path_exists):
|
||||
+ """Verify we get the correct name and machine arch on OpenSUSE."""
|
||||
+ m_os_release.return_value = OS_RELEASE_OPENSUSE_TW
|
||||
+ m_path_exists.side_effect = TestGetLinuxDistro.os_release_exists
|
||||
+ dist = util.get_linux_distro()
|
||||
+ self.assertEqual(
|
||||
+ ('opensuse-tumbleweed', '20180920', platform.machine()), dist)
|
||||
+
|
||||
@mock.patch('platform.dist')
|
||||
def test_get_linux_distro_no_data(self, m_platform_dist, m_path_exists):
|
||||
"""Verify we get no information if os-release does not exist"""
|
||||
--
|
||||
2.13.7
|
||||
|
@ -1,54 +0,0 @@
|
||||
--- /dev/null
|
||||
+++ templates/chrony.conf.sles.tmpl
|
||||
@@ -0,0 +1,24 @@
|
||||
+## template:jinja
|
||||
+# cloud-init generated file
|
||||
+# See chrony.conf(5)
|
||||
+
|
||||
+{% if pools %}# pools
|
||||
+{% endif %}
|
||||
+{% for pool in pools -%}
|
||||
+pool {{pool}} iburst
|
||||
+{% endfor %}
|
||||
+{%- if servers %}# servers
|
||||
+{% endif %}
|
||||
+{% for server in servers -%}
|
||||
+server {{server}} iburst
|
||||
+{% endfor %}
|
||||
+
|
||||
+# Record the rate at which the the system clock gains/losses time
|
||||
+driftfile /var/lib/chrony/drift
|
||||
+
|
||||
+# Allow the system clock to be stepped in the first three updates
|
||||
+# if its offset is larger than 1 second.
|
||||
+makestep 1.0 3
|
||||
+
|
||||
+# Enable kernel synchronization of the real-time clock (RTC).
|
||||
+rtcsync
|
||||
--- /dev/null
|
||||
+++ templates/chrony.conf.opensuse.tmpl
|
||||
@@ -0,0 +1,24 @@
|
||||
+## template:jinja
|
||||
+# cloud-init generated file
|
||||
+# See chrony.conf(5)
|
||||
+
|
||||
+{% if pools %}# pools
|
||||
+{% endif %}
|
||||
+{% for pool in pools -%}
|
||||
+pool {{pool}} iburst
|
||||
+{% endfor %}
|
||||
+{%- if servers %}# servers
|
||||
+{% endif %}
|
||||
+{% for server in servers -%}
|
||||
+server {{server}} iburst
|
||||
+{% endfor %}
|
||||
+
|
||||
+# Record the rate at which the the system clock gains/losses time
|
||||
+driftfile /var/lib/chrony/drift
|
||||
+
|
||||
+# Allow the system clock to be stepped in the first three updates
|
||||
+# if its offset is larger than 1 second.
|
||||
+makestep 1.0 3
|
||||
+
|
||||
+# Enable kernel synchronization of the real-time clock (RTC).
|
||||
+rtcsync
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0224969ebdae6eadffc5f40823bb206d8b05d99a1b730018535102f38b155249
|
||||
size 867297
|
3
cloud-init-18.4.tar.gz
Normal file
3
cloud-init-18.4.tar.gz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f19b969dbf2bda771a6a41fdb22b79b163b8a3b81cf1a45036d17993789bef7f
|
||||
size 965107
|
@ -1,247 +0,0 @@
|
||||
--- setup.py.orig
|
||||
+++ setup.py
|
||||
@@ -26,6 +26,7 @@ import subprocess
|
||||
|
||||
RENDERED_TMPD_PREFIX = "RENDERED_TEMPD"
|
||||
|
||||
+VARIANT = None
|
||||
|
||||
def is_f(p):
|
||||
return os.path.isfile(p)
|
||||
@@ -114,10 +115,20 @@ def render_tmpl(template):
|
||||
atexit.register(shutil.rmtree, tmpd)
|
||||
bname = os.path.basename(template).rstrip(tmpl_ext)
|
||||
fpath = os.path.join(tmpd, bname)
|
||||
- tiny_p([sys.executable, './tools/render-cloudcfg', template, fpath])
|
||||
+ if VARIANT:
|
||||
+ tiny_p([sys.executable, './tools/render-cloudcfg', '--variant',
|
||||
+ VARIANT, template, fpath])
|
||||
+ else:
|
||||
+ tiny_p([sys.executable, './tools/render-cloudcfg', template, fpath])
|
||||
# return path relative to setup.py
|
||||
return os.path.join(os.path.basename(tmpd), bname)
|
||||
|
||||
+# User can set the variant for template rendering
|
||||
+if '--distro' in sys.argv:
|
||||
+ idx = sys.argv.index('--distro')
|
||||
+ VARIANT = sys.argv[idx+1]
|
||||
+ del sys.argv[idx+1]
|
||||
+ sys.argv.remove('--distro')
|
||||
|
||||
INITSYS_FILES = {
|
||||
'sysvinit': [f for f in glob('sysvinit/redhat/*') if is_f(f)],
|
||||
@@ -145,7 +156,6 @@ INITSYS_ROOTS = {
|
||||
}
|
||||
INITSYS_TYPES = sorted([f.partition(".")[0] for f in INITSYS_ROOTS.keys()])
|
||||
|
||||
-
|
||||
# Install everything in the right location and take care of Linux (default) and
|
||||
# FreeBSD systems.
|
||||
USR = "usr"
|
||||
@@ -158,6 +168,19 @@ if os.uname()[0] == 'FreeBSD':
|
||||
elif os.path.isfile('/etc/redhat-release'):
|
||||
USR_LIB_EXEC = "usr/libexec"
|
||||
|
||||
+if VARIANT and sys.argv[1] == 'install':
|
||||
+ base = ETC
|
||||
+ config_dir = '/cloud/cloud.cfg.d'
|
||||
+ if sys.argv.index('--root'):
|
||||
+ root_idx = sys.argv.index('--root')
|
||||
+ root_loc = sys.argv[root_idx+1]
|
||||
+ base = root_loc + '/' + ETC
|
||||
+ if not os.path.exists(base + config_dir):
|
||||
+ os.makedirs(base + config_dir)
|
||||
+ usr_distro = open(base + '/cloud/cloud.cfg.d/cloud-init.user.distro', 'w')
|
||||
+ usr_distro.write(VARIANT)
|
||||
+ usr_distro.close()
|
||||
+
|
||||
|
||||
class MyEggInfo(egg_info):
|
||||
"""This makes sure to not include the rendered files in SOURCES.txt."""
|
||||
@@ -259,7 +282,7 @@ requirements = read_requires()
|
||||
setuptools.setup(
|
||||
name='cloud-init',
|
||||
version=get_version(),
|
||||
- description='EC2 initialisation magic',
|
||||
+ description='Cloud initialisation magic',
|
||||
author='Scott Moser',
|
||||
author_email='scott.moser@canonical.com',
|
||||
url='http://launchpad.net/cloud-init/',
|
||||
--- cloudinit/tests/test_util.py.orig
|
||||
+++ cloudinit/tests/test_util.py
|
||||
@@ -3,6 +3,7 @@
|
||||
"""Tests for cloudinit.util"""
|
||||
|
||||
import logging
|
||||
+import platform
|
||||
from textwrap import dedent
|
||||
|
||||
import cloudinit.util as util
|
||||
@@ -16,6 +17,29 @@ MOUNT_INFO = [
|
||||
'153 68 254:0 / /home rw,relatime shared:101 - xfs /dev/sda2 rw,attr2'
|
||||
]
|
||||
|
||||
+OS_RELEASE_SLES = dedent("""\
|
||||
+NAME="SLES"\n
|
||||
+VERSION="12-SP3"\n
|
||||
+VERSION_ID="12.3"\n
|
||||
+PRETTY_NAME="SUSE Linux Enterprise Server 12 SP3"\n
|
||||
+ID="sles"\nANSI_COLOR="0;32"\n
|
||||
+CPE_NAME="cpe:/o:suse:sles:12:sp3"\n
|
||||
+""")
|
||||
+
|
||||
+OS_RELEASE_UBUNTU = dedent("""\
|
||||
+NAME="Ubuntu"\n
|
||||
+VERSION="16.04.3 LTS (Xenial Xerus)"\n
|
||||
+ID=ubuntu\n
|
||||
+ID_LIKE=debian\n
|
||||
+PRETTY_NAME="Ubuntu 16.04.3 LTS"\n
|
||||
+VERSION_ID="16.04"\n
|
||||
+HOME_URL="http://www.ubuntu.com/"\n
|
||||
+SUPPORT_URL="http://help.ubuntu.com/"\n
|
||||
+BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"\n
|
||||
+VERSION_CODENAME=xenial\n
|
||||
+UBUNTU_CODENAME=xenial\n
|
||||
+""")
|
||||
+
|
||||
|
||||
class FakeCloud(object):
|
||||
|
||||
@@ -65,6 +89,54 @@ class TestUtil(CiTestCase):
|
||||
is_rw = util.mount_is_read_write('/')
|
||||
self.assertEqual(is_rw, False)
|
||||
|
||||
+ @mock.patch('os.path.exists')
|
||||
+ @mock.patch('cloudinit.util.load_file')
|
||||
+ def test_get_linux_distro_quoted_name(self, m_os_release, m_path_exists):
|
||||
+ m_os_release.return_value = OS_RELEASE_SLES
|
||||
+ m_path_exists.side_effect = os_release_exists
|
||||
+ dist = util.get_linux_distro()
|
||||
+ self.assertEqual(('sles', '12.3', platform.machine()), dist)
|
||||
+
|
||||
+ @mock.patch('os.path.exists')
|
||||
+ @mock.patch('cloudinit.util.load_file')
|
||||
+ def test_get_linux_distro_bare_name(self, m_os_release, m_path_exists):
|
||||
+ m_os_release.return_value = OS_RELEASE_UBUNTU
|
||||
+ m_path_exists.side_effect = os_release_exists
|
||||
+ dist = util.get_linux_distro()
|
||||
+ self.assertEqual(('ubuntu', '16.04', platform.machine()), dist)
|
||||
+
|
||||
+ @mock.patch('os.path.exists')
|
||||
+ @mock.patch('platform.dist')
|
||||
+ def test_get_linux_distro_no_data(self, m_platform_dist, m_path_exists):
|
||||
+ m_platform_dist.return_value = ('', '', '')
|
||||
+ m_path_exists.return_value = 0
|
||||
+ dist = util.get_linux_distro()
|
||||
+ self.assertEqual(('', '', ''), dist)
|
||||
+
|
||||
+ @mock.patch('os.path.exists')
|
||||
+ @mock.patch('platform.dist')
|
||||
+ def test_get_linux_distro_no_impl(self, m_platform_dist, m_path_exists):
|
||||
+ m_platform_dist.side_effect = Exception()
|
||||
+ m_path_exists.return_value = 0
|
||||
+ dist = util.get_linux_distro()
|
||||
+ self.assertEqual(('', '', ''), dist)
|
||||
+
|
||||
+ @mock.patch('os.path.exists')
|
||||
+ @mock.patch('platform.dist')
|
||||
+ def test_get_linux_distro_plat_data(self, m_platform_dist, m_path_exists):
|
||||
+ m_platform_dist.return_value = ('foo', '1.1', 'aarch64')
|
||||
+ m_path_exists.return_value = 0
|
||||
+ dist = util.get_linux_distro()
|
||||
+ self.assertEqual(('foo', '1.1', 'aarch64'), dist)
|
||||
+
|
||||
+ @mock.patch('os.path.exists')
|
||||
+ @mock.patch('cloudinit.util.load_file')
|
||||
+ def test_get_linux_distro_user_set(self, m_user_data, m_path_exists):
|
||||
+ m_user_data.return_value = 'debian'
|
||||
+ m_path_exists.side_effect = user_set_distro
|
||||
+ dist = util.get_linux_distro()
|
||||
+ self.assertEqual(('debian', 'not set', platform.machine()), dist)
|
||||
+
|
||||
|
||||
class TestShellify(CiTestCase):
|
||||
|
||||
@@ -212,4 +284,13 @@ class TestBlkid(CiTestCase):
|
||||
capture=True, decode="replace")
|
||||
|
||||
|
||||
+def os_release_exists(path):
|
||||
+ if path == '/etc/os-release':
|
||||
+ return 1
|
||||
+
|
||||
+
|
||||
+def user_set_distro(path):
|
||||
+ if path == '/etc/cloud/cloud.cfg.d/cloud-init.user.distro':
|
||||
+ return 1
|
||||
+
|
||||
# vi: ts=4 expandtab
|
||||
--- cloudinit/util.py.orig
|
||||
+++ cloudinit/util.py
|
||||
@@ -575,6 +575,43 @@ def get_cfg_option_str(yobj, key, defaul
|
||||
def get_cfg_option_int(yobj, key, default=0):
|
||||
return int(get_cfg_option_str(yobj, key, default=default))
|
||||
|
||||
+def get_linux_distro():
|
||||
+ distro_name = ''
|
||||
+ distro_version = ''
|
||||
+ if os.path.exists('/etc/cloud/cloud.cfg.d/cloud-init.user.distro'):
|
||||
+ distro_name = load_file(
|
||||
+ '/etc/cloud/cloud.cfg.d/cloud-init.user.distro')
|
||||
+ distro_version = 'not set'
|
||||
+ elif os.path.exists('/etc/os-release'):
|
||||
+ os_release = load_file('/etc/os-release').split('\n')
|
||||
+ for entry in os_release:
|
||||
+ if entry.startswith('ID='):
|
||||
+ distro_name = entry.split('=')[-1]
|
||||
+ if '"' in distro_name:
|
||||
+ distro_name = distro_name.split('"')[1]
|
||||
+ if entry.startswith('VERSION_ID='):
|
||||
+ # Lets hope for the best that distros stay consistent ;)
|
||||
+ distro_version = entry.split('"')[1]
|
||||
+ else:
|
||||
+ dist = ('', '', '')
|
||||
+ try:
|
||||
+ # Will be removed in 3.7
|
||||
+ dist = platform.dist() # pylint: disable=W1505
|
||||
+ except Exception:
|
||||
+ pass
|
||||
+ finally:
|
||||
+ found = None
|
||||
+ for entry in dist:
|
||||
+ if entry:
|
||||
+ found = 1
|
||||
+ if not found:
|
||||
+ msg = 'Unable to determine distribution, template expansion '
|
||||
+ msg += 'may have unexpected results'
|
||||
+ LOG.warning(msg)
|
||||
+ return dist
|
||||
+
|
||||
+ return (distro_name, distro_version, platform.machine())
|
||||
+
|
||||
|
||||
def system_info():
|
||||
info = {
|
||||
@@ -583,19 +620,19 @@ def system_info():
|
||||
'release': platform.release(),
|
||||
'python': platform.python_version(),
|
||||
'uname': platform.uname(),
|
||||
- 'dist': platform.dist(), # pylint: disable=W1505
|
||||
+ 'dist': get_linux_distro()
|
||||
}
|
||||
system = info['system'].lower()
|
||||
var = 'unknown'
|
||||
if system == "linux":
|
||||
linux_dist = info['dist'][0].lower()
|
||||
- if linux_dist in ('centos', 'fedora', 'debian'):
|
||||
+ if linux_dist in ('centos', 'fedora', 'debian', 'rhel', 'suse'):
|
||||
var = linux_dist
|
||||
elif linux_dist in ('ubuntu', 'linuxmint', 'mint'):
|
||||
var = 'ubuntu'
|
||||
elif linux_dist == 'redhat':
|
||||
var = 'rhel'
|
||||
- elif linux_dist == 'suse':
|
||||
+ elif linux_dist in ('opensuse', 'sles'):
|
||||
var = 'suse'
|
||||
else:
|
||||
var = 'linux'
|
@ -1,13 +0,0 @@
|
||||
--- cloudinit/stages.py.orig
|
||||
+++ cloudinit/stages.py
|
||||
@@ -691,7 +691,9 @@ class Modules(object):
|
||||
module_list = []
|
||||
if name not in self.cfg:
|
||||
return module_list
|
||||
- cfg_mods = self.cfg[name]
|
||||
+ cfg_mods = self.cfg.get(name)
|
||||
+ if not cfg_mods:
|
||||
+ return module_list
|
||||
# Create 'module_list', an array of hashes
|
||||
# Where hash['mod'] = module name
|
||||
# hash['freq'] = frequency
|
@ -1,18 +0,0 @@
|
||||
Index: cloud-init-17.2/cloudinit/distros/__init__.py
|
||||
===================================================================
|
||||
--- cloud-init-17.2.orig/cloudinit/distros/__init__.py
|
||||
+++ cloud-init-17.2/cloudinit/distros/__init__.py
|
||||
@@ -551,8 +551,11 @@ class Distro(object):
|
||||
# about long names.
|
||||
util.subp(['passwd', '-l', name])
|
||||
except Exception as e:
|
||||
- util.logexc(LOG, 'Failed to disable password for user %s', name)
|
||||
- raise e
|
||||
+ if e.exit_code != 3:
|
||||
+ util.logexc(LOG, 'Failed to disable password for user %s', name)
|
||||
+ raise e
|
||||
+ else:
|
||||
+ util.logexc(LOG, 'Password access already locked for user %s', name)
|
||||
|
||||
def set_passwd(self, user, passwd, hashed=False):
|
||||
pass_string = '%s:%s' % (user, passwd)
|
@ -1,27 +0,0 @@
|
||||
--- tools/ds-identify.orig
|
||||
+++ tools/ds-identify
|
||||
@@ -186,6 +186,16 @@ block_dev_with_label() {
|
||||
return 0
|
||||
}
|
||||
|
||||
+ensure_sane_path() {
|
||||
+ local t
|
||||
+ for t in /sbin /usr/sbin /bin /usr/bin; do
|
||||
+ case ":$PATH:" in
|
||||
+ *:$t:*|*:$t/:*) continue;;
|
||||
+ esac
|
||||
+ PATH="${PATH:+${PATH}:}$t"
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
read_fs_info() {
|
||||
cached "${DI_BLKID_OUTPUT}" && return 0
|
||||
# do not rely on links in /dev/disk which might not be present yet.
|
||||
@@ -1420,6 +1430,7 @@ _main() {
|
||||
|
||||
main() {
|
||||
local ret=""
|
||||
+ ensure_sane_path
|
||||
[ -d "$PATH_RUN_CI" ] || mkdir -p "$PATH_RUN_CI"
|
||||
if [ "${1:+$1}" != "--force" ] && [ -f "$PATH_RUN_CI_CFG" ] &&
|
||||
[ -f "$PATH_RUN_DI_RESULT" ]; then
|
@ -1,18 +0,0 @@
|
||||
--- tests/unittests/test_datasource/test_ovf.py.orig
|
||||
+++ tests/unittests/test_datasource/test_ovf.py
|
||||
@@ -119,6 +119,7 @@ class TestDatasourceOVF(CiTestCase):
|
||||
self.tdir = self.tmp_dir()
|
||||
|
||||
def test_get_data_false_on_none_dmi_data(self):
|
||||
+ return
|
||||
"""When dmi for system-product-name is None, get_data returns False."""
|
||||
paths = Paths({'seed_dir': self.tdir})
|
||||
ds = self.datasource(sys_cfg={}, distro={}, paths=paths)
|
||||
@@ -131,6 +132,7 @@ class TestDatasourceOVF(CiTestCase):
|
||||
'DEBUG: No system-product-name found', self.logs.getvalue())
|
||||
|
||||
def test_get_data_no_vmware_customization_disabled(self):
|
||||
+ return
|
||||
"""When vmware customization is disabled via sys_cfg log a message."""
|
||||
paths = Paths({'seed_dir': self.tdir})
|
||||
ds = self.datasource(
|
427
cloud-init-sysconf-ethsetup.patch
Normal file
427
cloud-init-sysconf-ethsetup.patch
Normal file
@ -0,0 +1,427 @@
|
||||
From 6732e10fa677566a2ddcbc7ff6727cf697d35761 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Schweikert <rjschwei@suse.com>
|
||||
Date: Tue, 23 Oct 2018 12:37:19 -0400
|
||||
Subject: [PATCH] - Follow up to db50bc0d9 + ONBOOT is not recognized on
|
||||
openSUSE and SUSE Linux Enterprise, add the STARTMODE setting
|
||||
|
||||
---
|
||||
cloudinit/net/sysconfig.py | 2 +
|
||||
.../unittests/test_distros/test_netconfig.py | 8 ++++
|
||||
tests/unittests/test_net.py | 40 +++++++++++++++++++
|
||||
3 files changed, 50 insertions(+)
|
||||
|
||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||||
index 9c16d3a7..ff847038 100644
|
||||
--- a/cloudinit/net/sysconfig.py
|
||||
+++ b/cloudinit/net/sysconfig.py
|
||||
@@ -242,6 +242,7 @@ class Renderer(renderer.Renderer):
|
||||
('USERCTL', False),
|
||||
('NM_CONTROLLED', False),
|
||||
('BOOTPROTO', 'none'),
|
||||
+ ('STARTMODE', 'auto'),
|
||||
])
|
||||
|
||||
# If these keys exist, then their values will be used to form
|
||||
@@ -336,6 +337,7 @@ class Renderer(renderer.Renderer):
|
||||
iface_cfg.name))
|
||||
if subnet.get('control') == 'manual':
|
||||
iface_cfg['ONBOOT'] = False
|
||||
+ iface_cfg['STARTMODE'] = 'manual'
|
||||
|
||||
# set IPv4 and IPv6 static addresses
|
||||
ipv4_index = -1
|
||||
diff --git a/tests/unittests/test_distros/test_netconfig.py b/tests/unittests/test_distros/test_netconfig.py
|
||||
index 6e339355..e986b593 100644
|
||||
--- a/tests/unittests/test_distros/test_netconfig.py
|
||||
+++ b/tests/unittests/test_distros/test_netconfig.py
|
||||
@@ -468,6 +468,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||
NETMASK=255.255.255.0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -476,6 +477,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||
DEVICE=eth1
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -499,6 +501,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||
IPV6_DEFAULTGW=2607:f0d0:1002:0011::1
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -507,6 +510,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||
DEVICE=eth1
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -559,6 +563,7 @@ class TestNetCfgDistroOpensuse(TestNetCfgDistroBase):
|
||||
NETMASK=255.255.255.0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -567,6 +572,7 @@ class TestNetCfgDistroOpensuse(TestNetCfgDistroBase):
|
||||
DEVICE=eth1
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -587,6 +593,7 @@ class TestNetCfgDistroOpensuse(TestNetCfgDistroBase):
|
||||
IPV6_DEFAULTGW=2607:f0d0:1002:0011::1
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -595,6 +602,7 @@ class TestNetCfgDistroOpensuse(TestNetCfgDistroBase):
|
||||
DEVICE=eth1
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
||||
index 8e383739..d94b9430 100644
|
||||
--- a/tests/unittests/test_net.py
|
||||
+++ b/tests/unittests/test_net.py
|
||||
@@ -144,6 +144,7 @@ IPADDR=172.19.1.34
|
||||
NETMASK=255.255.252.0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
""".lstrip()),
|
||||
@@ -177,6 +178,7 @@ IPADDR=172.19.1.34
|
||||
NETMASK=255.255.252.0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
""".lstrip()),
|
||||
@@ -246,6 +248,7 @@ NETMASK=255.255.252.0
|
||||
NETMASK1=255.255.255.0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
""".lstrip()),
|
||||
@@ -281,6 +284,7 @@ NETMASK=255.255.252.0
|
||||
NETMASK1=255.255.255.0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
""".lstrip()),
|
||||
@@ -372,6 +376,7 @@ IPV6_DEFAULTGW=2001:DB8::1
|
||||
NETMASK=255.255.252.0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
""".lstrip()),
|
||||
@@ -409,6 +414,7 @@ IPV6_DEFAULTGW=2001:DB8::1
|
||||
NETMASK=255.255.252.0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
""".lstrip()),
|
||||
@@ -524,6 +530,7 @@ NETWORK_CONFIGS = {
|
||||
HWADDR=cf:d6:af:48:e8:80
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""),
|
||||
'ifcfg-eth99': textwrap.dedent("""\
|
||||
@@ -539,6 +546,7 @@ NETWORK_CONFIGS = {
|
||||
NETMASK=255.255.255.0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""),
|
||||
},
|
||||
@@ -652,6 +660,7 @@ NETWORK_CONFIGS = {
|
||||
NETMASK=255.255.255.0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
MTU=9000
|
||||
@@ -691,6 +700,7 @@ NETWORK_CONFIGS = {
|
||||
DEVICE=iface0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -894,6 +904,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
MACADDR=aa:bb:cc:dd:ee:ff
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Bond
|
||||
USERCTL=no"""),
|
||||
'ifcfg-bond0.200': textwrap.dedent("""\
|
||||
@@ -902,6 +913,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PHYSDEV=bond0
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
VLAN=yes"""),
|
||||
@@ -919,6 +931,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PRIO=22
|
||||
+ STARTMODE=auto
|
||||
STP=no
|
||||
TYPE=Bridge
|
||||
USERCTL=no"""),
|
||||
@@ -928,6 +941,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
HWADDR=c0:d6:9f:2c:e8:80
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""),
|
||||
'ifcfg-eth0.101': textwrap.dedent("""\
|
||||
@@ -946,6 +960,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PHYSDEV=eth0
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
VLAN=yes"""),
|
||||
@@ -956,6 +971,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
MASTER=bond0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
SLAVE=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""),
|
||||
@@ -966,6 +982,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
MASTER=bond0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
SLAVE=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""),
|
||||
@@ -976,6 +993,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
HWADDR=66:bb:9f:2c:e8:80
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""),
|
||||
'ifcfg-eth4': textwrap.dedent("""\
|
||||
@@ -985,6 +1003,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
HWADDR=98:bb:9f:2c:e8:80
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""),
|
||||
'ifcfg-eth5': textwrap.dedent("""\
|
||||
@@ -993,6 +1012,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
HWADDR=98:bb:9f:2c:e8:8a
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=no
|
||||
+ STARTMODE=manual
|
||||
TYPE=Ethernet
|
||||
USERCTL=no""")
|
||||
},
|
||||
@@ -1282,6 +1302,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
NETMASK1=255.255.255.0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Bond
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -1293,6 +1314,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
SLAVE=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -1309,6 +1331,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
SLAVE=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -1334,6 +1357,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
NETMASK1=255.255.255.0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Bond
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -1345,6 +1369,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
SLAVE=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -1363,6 +1388,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
SLAVE=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -1400,6 +1426,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
HWADDR=aa:bb:cc:dd:e8:00
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""),
|
||||
'ifcfg-en0.99': textwrap.dedent("""\
|
||||
@@ -1418,6 +1445,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PHYSDEV=en0
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
VLAN=yes"""),
|
||||
@@ -1459,6 +1487,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PRIO=22
|
||||
+ STARTMODE=auto
|
||||
STP=no
|
||||
TYPE=Bridge
|
||||
USERCTL=no
|
||||
@@ -1472,6 +1501,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
IPV6INIT=yes
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -1484,6 +1514,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
IPV6INIT=yes
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -1558,6 +1589,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
NETMASK=255.255.255.0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=no
|
||||
+ STARTMODE=manual
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -1568,6 +1600,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
MTU=1480
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+ STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -1577,6 +1610,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
HWADDR=52:54:00:12:34:ff
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=no
|
||||
+ STARTMODE=manual
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""),
|
||||
@@ -1933,6 +1967,7 @@ DEVICE=eth1000
|
||||
HWADDR=07-1C-C6-75-A4-BE
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
""".lstrip()
|
||||
@@ -2054,6 +2089,7 @@ IPADDR=10.0.2.15
|
||||
NETMASK=255.255.255.0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""
|
||||
@@ -2075,6 +2111,7 @@ BOOTPROTO=dhcp
|
||||
DEVICE=eth0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""
|
||||
@@ -2222,6 +2259,7 @@ DEVICE=eth1000
|
||||
HWADDR=07-1C-C6-75-A4-BE
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
""".lstrip()
|
||||
@@ -2343,6 +2381,7 @@ IPADDR=10.0.2.15
|
||||
NETMASK=255.255.255.0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""
|
||||
@@ -2364,6 +2403,7 @@ BOOTPROTO=dhcp
|
||||
DEVICE=eth0
|
||||
NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
+STARTMODE=auto
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
"""
|
||||
--
|
||||
2.19.0
|
||||
|
13
cloud-init-sysconf-path.patch
Normal file
13
cloud-init-sysconf-path.patch
Normal file
@ -0,0 +1,13 @@
|
||||
--- cloudinit/net/sysconfig.py.orig
|
||||
+++ cloudinit/net/sysconfig.py
|
||||
@@ -660,9 +660,7 @@ def available(target=None):
|
||||
if not util.which(p, search=search, target=target):
|
||||
return False
|
||||
|
||||
- expected_paths = [
|
||||
- 'etc/sysconfig/network-scripts/network-functions',
|
||||
- 'etc/sysconfig/network-scripts/ifdown-eth']
|
||||
+ expected_paths = ['etc/sysconfig/network/scripts/functions.netconfig']
|
||||
for p in expected_paths:
|
||||
if not os.path.isfile(util.target_path(target, p)):
|
||||
return False
|
@ -1,37 +0,0 @@
|
||||
Index: cloudinit/net/sysconfig.py
|
||||
===================================================================
|
||||
--- cloudinit/net/sysconfig.py.orig
|
||||
+++ cloudinit/net/sysconfig.py
|
||||
@@ -91,8 +91,8 @@ class ConfigMap(object):
|
||||
class Route(ConfigMap):
|
||||
"""Represents a route configuration."""
|
||||
|
||||
- route_fn_tpl_ipv4 = '%(base)s/network-scripts/route-%(name)s'
|
||||
- route_fn_tpl_ipv6 = '%(base)s/network-scripts/route6-%(name)s'
|
||||
+ route_fn_tpl_ipv4 = '%(base)s/network/route-%(name)s'
|
||||
+ route_fn_tpl_ipv6 = '%(base)s/network/route6-%(name)s'
|
||||
|
||||
def __init__(self, route_name, base_sysconf_dir):
|
||||
super(Route, self).__init__()
|
||||
@@ -169,7 +169,7 @@ class Route(ConfigMap):
|
||||
class NetInterface(ConfigMap):
|
||||
"""Represents a sysconfig/networking-script (and its config + children)."""
|
||||
|
||||
- iface_fn_tpl = '%(base)s/network-scripts/ifcfg-%(name)s'
|
||||
+ iface_fn_tpl = '%(base)s/network/ifcfg-%(name)s'
|
||||
|
||||
iface_types = {
|
||||
'ethernet': 'Ethernet',
|
||||
@@ -616,12 +616,6 @@ def available(target=None):
|
||||
if not util.which(p, search=search, target=target):
|
||||
return False
|
||||
|
||||
- expected_paths = [
|
||||
- 'etc/sysconfig/network-scripts/network-functions',
|
||||
- 'etc/sysconfig/network-scripts/ifdown-eth']
|
||||
- for p in expected_paths:
|
||||
- if not os.path.isfile(util.target_path(target, p)):
|
||||
- return False
|
||||
return True
|
||||
|
||||
|
8
cloud-init-template-py2.patch
Normal file
8
cloud-init-template-py2.patch
Normal file
@ -0,0 +1,8 @@
|
||||
--- tools/render-cloudcfg.orig
|
||||
+++ tools/render-cloudcfg
|
||||
@@ -1,4 +1,4 @@
|
||||
-#!/usr/bin/env python3
|
||||
+#!/usr/bin/env python
|
||||
|
||||
import argparse
|
||||
import os
|
@ -1,46 +0,0 @@
|
||||
--- cloudinit/distros/net_util.py.orig
|
||||
+++ cloudinit/distros/net_util.py
|
||||
@@ -67,6 +67,10 @@
|
||||
# }
|
||||
# }
|
||||
|
||||
+import re
|
||||
+
|
||||
+ipv4 = re.compile("\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}")
|
||||
+
|
||||
def translate_network(settings):
|
||||
# Get the standard cmd, args from the ubuntu format
|
||||
entries = []
|
||||
@@ -88,7 +92,14 @@ def translate_network(settings):
|
||||
consume = {}
|
||||
consume[cmd] = args
|
||||
else:
|
||||
- consume[cmd] = args
|
||||
+ if consume.get(cmd):
|
||||
+ val = consume[cmd]
|
||||
+ if isinstance(val, list):
|
||||
+ consume[cmd].append(args)
|
||||
+ else:
|
||||
+ consume[cmd] = [val, args]
|
||||
+ else:
|
||||
+ consume[cmd] = args
|
||||
# Check if anything left over to consume
|
||||
absorb = False
|
||||
for (cmd, args) in consume.items():
|
||||
@@ -148,6 +159,16 @@ def translate_network(settings):
|
||||
hw_addr = hw_split[1]
|
||||
if hw_addr:
|
||||
iface_info['hwaddress'] = hw_addr
|
||||
+ if 'post-up' in info:
|
||||
+ routes = info['post-up']
|
||||
+ if isinstance(routes, list):
|
||||
+ for route_info in routes:
|
||||
+ if 'default gw' in route_info:
|
||||
+ iface_info['gateway'] = ipv4.search(
|
||||
+ route_info).group(0)
|
||||
+ elif 'default gw' in routes:
|
||||
+ iface_info['gateway'] = ipv4.search(routes).group(0)
|
||||
+
|
||||
# If ipv6 is enabled, device will have multiple IPs, so we need to
|
||||
# update the dictionary instead of overwriting it...
|
||||
if dev_name in real_ifaces:
|
@ -1,3 +1,234 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Oct 25 18:56:13 UTC 2018 - Robert Schweikert <rjschwei@suse.com>
|
||||
|
||||
- Update to version 18.4 (bsc#1087331, bsc#1097388, boo#1111427, bsc#1095627)
|
||||
+ Remove cloud-init-no-user-lock-if-already-locked.patch
|
||||
cloud-init 18.4 is not supported on SLE 11 code base
|
||||
+ Remove 0001-Support-chrony-configuration-lp-1731619.patch
|
||||
Included upstream
|
||||
+ Remove 0003-Distro-dependent-chrony-config-file.patch
|
||||
Included upstream
|
||||
+ Remove 0001-switch-to-using-iproute2-tools.patch
|
||||
Included upstream
|
||||
+ Remove cloud-init-no-python-linux-dist.patch
|
||||
Included upstream
|
||||
+ Remove cloud-init-no-trace-empt-sect.patch
|
||||
Included upstream
|
||||
+ Remove cloud-init-setpath-dsitentify.patch
|
||||
Included upstream
|
||||
+ Modify fix-default-systemd-unit-dir.patch
|
||||
Use pkg-config, only modify the generator
|
||||
+ Remove cloud-init-sysconfig-netpathfix.patch
|
||||
Fixed upstream
|
||||
+ Removed cloud-init-skip-ovf-tests.patch
|
||||
Fixed upstream
|
||||
+ Removed cloud-init-translate-netconf-ipv4-keep-gw.patch
|
||||
Fixed upstream
|
||||
+ Add cloud-init-template-py2.patch avoid Python 3 dependency when we build
|
||||
for distros with Python 2 support
|
||||
+ Add 0001-Follow-the-ever-bouncing-ball-for-openSUSE-distribut.patch
|
||||
+ Add 0002-Add-tests-for-additional-openSUSE-distro-condition-m.patch
|
||||
+ Add cloud-init-sysconf-path.patch
|
||||
+ Add cloud-init-sysconf-ethsetup.patch
|
||||
+ Add 0001-Fix-the-service-order-for-SUSE-distributions.patch
|
||||
+ Add dhcp-client as requirement
|
||||
cloud-init uses dhclient to setup temporary network for
|
||||
metadata retrieval. THis is needed until lp#1733226 is addressed
|
||||
+ add rtd example docs about new standardized keys
|
||||
+ use ds._crawled_metadata instance attribute if set when writing
|
||||
instance-data.json
|
||||
+ ec2: update crawled metadata. add standardized keys
|
||||
+ tests: allow skipping an entire cloud_test without running.
|
||||
+ tests: disable lxd tests on cosmic
|
||||
+ cii-tests: use unittest2.SkipTest in ntp_chrony due to new deps
|
||||
+ lxd: adjust to snap installed lxd.
|
||||
+ docs: surface experimental doc in instance-data.json
|
||||
+ tests: fix ec2 integration tests. process meta_data instead of meta-data
|
||||
+ Add support for Infiniband network interfaces (IPoIB). [Mark Goddard]
|
||||
+ cli: add cloud-init query subcommand to query instance metadata
|
||||
+ tools/tox-venv: update for new features.
|
||||
+ pylint: ignore warning assignment-from-no-return for _write_network
|
||||
+ stages: Fix bug causing datasource to have incorrect sys_cfg.
|
||||
(LP: #1787459)
|
||||
+ Remove dead-code _write_network distro implementations.
|
||||
+ net_util: ensure static configs have netmask in translate_network result
|
||||
[Thomas Berger] (LP: #1792454)
|
||||
+ Fall back to root:root on syslog permissions if other options fail.
|
||||
[Robert Schweikert]
|
||||
+ tests: Add mock for util.get_hostname. [Robert Schweikert] (LP: #1792799)
|
||||
+ ds-identify: doc string cleanup.
|
||||
+ OpenStack: Support setting mac address on bond.
|
||||
[Fabian Wiesel] (LP: #1682064)
|
||||
+ bash_completion/cloud-init: fix shell syntax error.
|
||||
+ EphemeralIPv4Network: Be more explicit when adding default route.
|
||||
(LP: #1792415)
|
||||
+ OpenStack: support reading of newer versions of metdata.
|
||||
+ OpenStack: fix bug causing 'latest' version to be used from network.
|
||||
(LP: #1792157)
|
||||
+ user-data: jinja template to render instance-data.json in cloud-config
|
||||
(LP: #1791781)
|
||||
+ config: disable ssh access to a configured user account
|
||||
+ tests: print failed testname instead of docstring upon failure
|
||||
+ tests: Disallow use of util.subp except for where needed.
|
||||
+ sysconfig: refactor sysconfig to accept distro specific templates paths
|
||||
+ Add unit tests for config/cc_ssh.py [Francis Ginther]
|
||||
+ Fix the built-in cloudinit/tests/helpers:skipIf
|
||||
+ read-version: enhance error message [Joshua Powers]
|
||||
+ hyperv_reporting_handler: simplify threaded publisher
|
||||
+ VMWare: Fix a network config bug in vm with static IPv4 and no gateway.
|
||||
[Pengpeng Sun] (LP: #1766538)
|
||||
+ logging: Add logging config type hyperv for reporting via Azure KVP
|
||||
[Andy Liu]
|
||||
+ tests: disable other snap test as well [Joshua Powers]
|
||||
+ tests: disable snap, fix write_files binary [Joshua Powers]
|
||||
+ Add datasource Oracle Compute Infrastructure (OCI).
|
||||
+ azure: allow azure to generate network configuration from IMDS per boot.
|
||||
+ Scaleway: Add network configuration to the DataSource [Louis Bouchard]
|
||||
+ docs: Fix example cloud-init analyze command to match output.
|
||||
[Wesley Gao]
|
||||
+ netplan: Correctly render macaddress on a bonds and bridges when
|
||||
provided. (LP: #1784699)
|
||||
+ tools: Add 'net-convert' subcommand command to 'cloud-init devel'.
|
||||
+ redhat: remove ssh keys on new instance. (LP: #1781094)
|
||||
+ Use typeset or local in profile.d scripts. (LP: #1784713)
|
||||
+ OpenNebula: Fix null gateway6 [Akihiko Ota] (LP: #1768547)
|
||||
+ oracle: fix detect_openstack to report True on OracleCloud.com DMI data
|
||||
(LP: #1784685)
|
||||
+ tests: improve LXDInstance trying to workaround or catch bug.
|
||||
+ update_metadata re-config on every boot comments and tests not quite
|
||||
right [Mike Gerdts]
|
||||
+ tests: Collect build_info from system if available.
|
||||
+ pylint: Fix pylint warnings reported in pylint 2.0.0.
|
||||
+ get_linux_distro: add support for rhel via redhat-release.
|
||||
+ get_linux_distro: add support for centos6 and rawhide flavors of redhat
|
||||
(LP: #1781229)
|
||||
+ tools: add '--debug' to tools/net-convert.py
|
||||
+ tests: bump the version of paramiko to 2.4.1.
|
||||
+ docs: note in rtd about avoiding /tmp when writing files (LP: #1727876)
|
||||
+ ubuntu,centos,debian: get_linux_distro to align with platform.dist
|
||||
(LP: #1780481)
|
||||
+ Fix boothook docs on environment variable name (INSTANCE_I ->
|
||||
INSTANCE_ID) [Marc Tamsky]
|
||||
+ update_metadata: a datasource can support network re-config every boot
|
||||
+ tests: drop salt-minion integration test (LP: #1778737)
|
||||
+ Retry on failed import of gpg receive keys.
|
||||
+ tools: Fix run-container when neither source or binary package requested.
|
||||
+ docs: Fix a small spelling error. [Oz N Tiram]
|
||||
+ tox: use simplestreams from git repository rather than bzr.
|
||||
- From 18.3
|
||||
+ docs: represent sudo:false in docs for user_groups config module
|
||||
+ Explicitly prevent `sudo` access for user module
|
||||
[Jacob Bednarz] (LP: #1771468)
|
||||
+ lxd: Delete default network and detach device if lxd-init created them.
|
||||
(LP: #1776958)
|
||||
+ openstack: avoid unneeded metadata probe on non-openstack platforms
|
||||
(LP: #1776701)
|
||||
+ stages: fix tracebacks if a module stage is undefined or empty
|
||||
[Robert Schweikert] (LP: #1770462)
|
||||
+ Be more safe on string/bytes when writing multipart user-data to disk.
|
||||
(LP: #1768600)
|
||||
+ Fix get_proc_env for pids that have non-utf8 content in environment.
|
||||
(LP: #1775371)
|
||||
+ tests: fix salt_minion integration test on bionic and later
|
||||
+ tests: provide human-readable integration test summary when --verbose
|
||||
+ tests: skip chrony integration tests on lxd running artful or older
|
||||
+ test: add optional --preserve-instance arg to integraiton tests
|
||||
+ netplan: fix mtu if provided by network config for all rendered types
|
||||
(LP: #1774666)
|
||||
+ tests: remove pip install workarounds for pylxd, take upstream fix.
|
||||
+ subp: support combine_capture argument.
|
||||
+ tests: ordered tox dependencies for pylxd install
|
||||
+ util: add get_linux_distro function to replace platform.dist
|
||||
[Robert Schweikert] (LP: #1745235)
|
||||
+ pyflakes: fix unused variable references identified by pyflakes 2.0.0.
|
||||
+ Do not use the systemd_prefix macro, not available in this environment
|
||||
[Robert Schweikert]
|
||||
+ doc: Add config info to ec2, openstack and cloudstack datasource docs
|
||||
+ Enable SmartOS network metadata to work with netplan via per-subnet
|
||||
routes [Dan McDonald] (LP: #1763512)
|
||||
+ openstack: Allow discovery in init-local using dhclient in a sandbox.
|
||||
(LP: #1749717)
|
||||
+ tests: Avoid using https in httpretty, improve HttPretty test case.
|
||||
(LP: #1771659)
|
||||
+ yaml_load/schema: Add invalid line and column nums to error message
|
||||
+ Azure: Ignore NTFS mount errors when checking ephemeral drive
|
||||
[Paul Meyer]
|
||||
+ packages/brpm: Get proper dependencies for cmdline distro.
|
||||
+ packages: Make rpm spec files patch in package version like in debs.
|
||||
+ tools/run-container: replace tools/run-centos with more generic.
|
||||
+ Update version.version_string to contain packaged version. (LP: #1770712)
|
||||
+ cc_mounts: Do not add devices to fstab that are already present.
|
||||
[Lars Kellogg-Stedman]
|
||||
+ ds-identify: ensure that we have certain tokens in PATH. (LP: #1771382)
|
||||
+ tests: enable Ubuntu Cosmic in integration tests [Joshua Powers]
|
||||
+ read_file_or_url: move to url_helper, fix bug in its FileResponse.
|
||||
+ cloud_tests: help pylint [Ryan Harper]
|
||||
+ flake8: fix flake8 errors in previous commit.
|
||||
+ typos: Fix spelling mistakes in cc_mounts.py log messages [Stephen Ford]
|
||||
+ tests: restructure SSH and initial connections [Joshua Powers]
|
||||
+ ds-identify: recognize container-other as a container, test SmartOS.
|
||||
+ cloud-config.service: run After snap.seeded.service. (LP: #1767131)
|
||||
+ tests: do not rely on host /proc/cmdline in test_net.py
|
||||
[Lars Kellogg-Stedman] (LP: #1769952)
|
||||
+ ds-identify: Remove dupe call to is_ds_enabled, improve debug message.
|
||||
+ SmartOS: fix get_interfaces for nics that do not have addr_assign_type.
|
||||
+ tests: fix package and ca_cert cloud_tests on bionic
|
||||
(LP: #1769985)
|
||||
+ ds-identify: make shellcheck 0.4.6 happy with ds-identify.
|
||||
+ pycodestyle: Fix deprecated string literals, move away from flake8.
|
||||
+ azure: Add reported ready marker file. [Joshua Chan] (LP: #1765214)
|
||||
+ tools: Support adding a release suffix through packages/bddeb.
|
||||
+ FreeBSD: Invoke growfs on ufs filesystems such that it does not prompt.
|
||||
[Harm Weites] (LP: #1404745)
|
||||
+ tools: Re-use the orig tarball in packages/bddeb if it is around.
|
||||
+ netinfo: fix netdev_pformat when a nic does not have an address
|
||||
assigned. (LP: #1766302)
|
||||
+ collect-logs: add -v flag, write to stderr, limit journal to single
|
||||
boot. (LP: #1766335)
|
||||
+ IBMCloud: Disable config-drive and nocloud only if IBMCloud is enabled.
|
||||
(LP: #1766401)
|
||||
+ Add reporting events and log_time around early source of blocking time
|
||||
[Ryan Harper]
|
||||
+ IBMCloud: recognize provisioning environment during debug boots.
|
||||
(LP: #1767166)
|
||||
+ net: detect unstable network names and trigger a settle if needed
|
||||
[Ryan Harper] (LP: #1766287)
|
||||
+ IBMCloud: improve documentation in datasource.
|
||||
+ sysconfig: dhcp6 subnet type should not imply dhcpv4 [Vitaly Kuznetsov]
|
||||
+ packages/debian/control.in: add missing dependency on iproute2.
|
||||
(LP: #1766711)
|
||||
+ DataSourceSmartOS: add locking of serial device.
|
||||
[Mike Gerdts] (LP: #1746605)
|
||||
+ DataSourceSmartOS: sdc:hostname is ignored [Mike Gerdts] (LP: #1765085)
|
||||
+ DataSourceSmartOS: list() should always return a list
|
||||
[Mike Gerdts] (LP: #1763480)
|
||||
+ schema: in validation, raise ImportError if strict but no jsonschema.
|
||||
+ set_passwords: Add newline to end of sshd config, only restart if
|
||||
updated. (LP: #1677205)
|
||||
+ pylint: pay attention to unused variable warnings.
|
||||
+ doc: Add documentation for AliYun datasource. [Junjie Wang]
|
||||
+ Schema: do not warn on duplicate items in commands. (LP: #1764264)
|
||||
+ net: Depend on iproute2's ip instead of net-tools ifconfig or route
|
||||
+ DataSourceSmartOS: fix hang when metadata service is down
|
||||
[Mike Gerdts] (LP: #1667735)
|
||||
+ DataSourceSmartOS: change default fs on ephemeral disk from ext3 to
|
||||
ext4. [Mike Gerdts] (LP: #1763511)
|
||||
+ pycodestyle: Fix invalid escape sequences in string literals.
|
||||
+ Implement bash completion script for cloud-init command line
|
||||
[Ryan Harper]
|
||||
+ tools: Fix make-tarball cli tool usage for development
|
||||
+ renderer: support unicode in render_from_file.
|
||||
+ Implement ntp client spec with auto support for distro selection
|
||||
[Ryan Harper] (LP: #1749722)
|
||||
+ Apport: add Brightbox, IBM, LXD, and OpenTelekomCloud to list of clouds.
|
||||
+ tests: fix ec2 integration network metadata validation
|
||||
+ tests: fix integration tests to support lxd 3.0 release
|
||||
+ correct documentation to match correct attribute name usage.
|
||||
[Dominic Schlegel] (LP: #1420018)
|
||||
+ cc_resizefs, util: handle no /dev/zfs [Ryan Harper]
|
||||
+ doc: Fix links in OpenStack datasource documentation.
|
||||
[Dominic Schlegel] (LP: #1721660)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Aug 24 21:42:43 UTC 2018 - rjschwei@suse.com
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
%global configver 0.7
|
||||
|
||||
Name: cloud-init
|
||||
Version: 18.2
|
||||
Version: 18.4
|
||||
Release: 0
|
||||
License: GPL-3.0 and AGPL-3.0
|
||||
Summary: Cloud node initialization tool
|
||||
@ -28,45 +28,28 @@ Source0: %{name}-%{version}.tar.gz
|
||||
Source1: rsyslog-cloud-init.cfg
|
||||
|
||||
|
||||
# FIXME cloud-init-translate-netconf-ipv4-keep-gw (bsc#1064854)
|
||||
# proposed for upstream merge (lp#1732966)
|
||||
Patch8: cloud-init-translate-netconf-ipv4-keep-gw.patch
|
||||
Patch10: cloud-init-no-user-lock-if-already-locked.patch
|
||||
# FIXME
|
||||
# proposed for upstream merge
|
||||
# https://code.launchpad.net/~rjschwei/cloud-init/+git/cloud-init/+merge/356098
|
||||
Patch12: fix-default-systemd-unit-dir.patch
|
||||
# python2 disables SIGPIPE, causing broken pipe errors in shell scripts (bsc#903449)
|
||||
Patch20: cloud-init-python2-sigpipe.patch
|
||||
Patch27: cloud-init-sysconfig-netpathfix.patch
|
||||
Patch21: cloud-init-template-py2.patch
|
||||
Patch29: datasourceLocalDisk.patch
|
||||
Patch34: cloud-init-tests-set-exec.patch
|
||||
# FIXME chrony support upstream
|
||||
# These patches represent a working appraoch to supporting chrony
|
||||
# Upstream is seeking a significant re-write which is not likely to happen
|
||||
# before we need chrony support
|
||||
Patch37: 0001-Support-chrony-configuration-lp-1731619.patch
|
||||
Patch39: 0003-Distro-dependent-chrony-config-file.patch
|
||||
# FIXME switch to iproute2 tools
|
||||
# Proposed for merging upstream
|
||||
Patch40: 0001-switch-to-using-iproute2-tools.patch
|
||||
# FIXME do not use platform.dist() function
|
||||
# Proposed for merging upstream
|
||||
Patch41: cloud-init-no-python-linux-dist.patch
|
||||
# Disable OVF tests
|
||||
Patch42: cloud-init-skip-ovf-tests.patch
|
||||
# FIXME no traceback for empt stage
|
||||
# #lp1770462
|
||||
# https://code.launchpad.net/~rjschwei/cloud-init/+git/cloud-init/+merge/345377
|
||||
Patch43: cloud-init-no-trace-empt-sect.patch
|
||||
# FIXME cloud-init-setpath-gen.patch (boo#1093501)
|
||||
# Merged upstream remove for 18.3
|
||||
Patch44: cloud-init-setpath-dsitentify.patch
|
||||
# We are going to fix the network setup upstream, two parts:
|
||||
# 1. clod-init will get it's own dhcp setup to no longer rely on dhclient
|
||||
# 2. we will switch the SUSE implementation to the sysconfig renderer to
|
||||
# fix network config setup issues
|
||||
# Until then, expected with 18.4 or 18.5 we will carry this patch
|
||||
Patch45: cloud-init-network-online.patch
|
||||
# The generator will become a template upstream, 18.4 or 18.5, until then
|
||||
# fix the generator directly
|
||||
Patch46: fix-default-systemd-unit-dir.patch
|
||||
# FIXME
|
||||
# https://code.launchpad.net/~rjschwei/cloud-init/+git/cloud-init/+merge/357644
|
||||
Patch36: 0001-Follow-the-ever-bouncing-ball-for-openSUSE-distribut.patch
|
||||
Patch37: 0002-Add-tests-for-additional-openSUSE-distro-condition-m.patch
|
||||
# FIXME no proposed solution
|
||||
Patch38: cloud-init-sysconf-path.patch
|
||||
# FIXME (lp#1799540)
|
||||
# https://code.launchpad.net/~rjschwei/cloud-init/+git/cloud-init/+merge/357710
|
||||
Patch39: cloud-init-sysconf-ethsetup.patch
|
||||
# FIXME (lp#1799709)
|
||||
# https://code.launchpad.net/~rjschwei/cloud-init/+git/cloud-init/+merge/357752
|
||||
Patch40: 0001-Fix-the-service-order-for-SUSE-distributions.patch
|
||||
|
||||
BuildRequires: fdupes
|
||||
BuildRequires: filesystem
|
||||
# pkg-config is needed to find correct systemd unit dir
|
||||
@ -102,6 +85,7 @@ BuildRequires: sles-release
|
||||
%endif
|
||||
BuildRequires: util-linux
|
||||
Requires: bash
|
||||
Requires: dhcp-client
|
||||
Requires: file
|
||||
Requires: growpart
|
||||
Requires: e2fsprogs
|
||||
@ -198,23 +182,18 @@ Documentation and examples for cloud-init tools
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
%patch8
|
||||
%patch10 -p1
|
||||
%patch12
|
||||
%if 0%{?suse_version} < 1315
|
||||
%patch20
|
||||
%patch21
|
||||
%endif
|
||||
%patch27
|
||||
%patch29 -p0
|
||||
%patch34
|
||||
%patch37
|
||||
%patch36 -p1
|
||||
%patch37 -p1
|
||||
%patch38
|
||||
%patch39 -p1
|
||||
%patch40 -p1
|
||||
%patch41
|
||||
%patch42
|
||||
%patch43
|
||||
%patch44
|
||||
%patch45 -p1
|
||||
%patch46 -p1
|
||||
|
||||
%build
|
||||
%if 0%{?suse_version} && 0%{?suse_version} <= 1315
|
||||
@ -255,11 +234,13 @@ mv %{buildroot}%{_datadir}/doc/%{name} %{buildroot}%{docdir}
|
||||
# copy the LICENSE
|
||||
cp LICENSE %{buildroot}%{docdir}
|
||||
# Set the distribution indicator
|
||||
%if 0%{?suse_version}
|
||||
%if 0%{?is_opensuse}
|
||||
sed -i s/suse/opensuse/ %{buildroot}/%{_sysconfdir}/cloud/cloud.cfg
|
||||
%else
|
||||
sed -i s/suse/sles/ %{buildroot}/%{_sysconfdir}/cloud/cloud.cfg
|
||||
%endif
|
||||
%endif
|
||||
mkdir -p %{buildroot}/%{_sysconfdir}/rsyslog.d
|
||||
mkdir -p %{buildroot}/usr/lib/udev/rules.d/
|
||||
cp -a %{SOURCE1} %{buildroot}/%{_sysconfdir}/rsyslog.d/21-cloudinit.conf
|
||||
@ -309,6 +290,7 @@ popd
|
||||
%config(noreplace) %{_sysconfdir}/cloud/templates
|
||||
%{_sysconfdir}/dhcp/dhclient-exit-hooks.d/hook-dhclient
|
||||
%{_sysconfdir}/NetworkManager/dispatcher.d/hook-network-manager
|
||||
%{_sysconfdir}/bash_completion.d/cloud-init
|
||||
%if 0%{?suse_version} && 0%{?suse_version} <= 1315
|
||||
%{python_sitelib}/cloudinit
|
||||
%{python_sitelib}/cloud_init-%{version}-py%{py_ver}.egg-info
|
||||
|
@ -1,7 +1,7 @@
|
||||
Index: cloud-init-18.2/systemd/cloud-init-generator
|
||||
Index: systemd/cloud-init-generator
|
||||
===================================================================
|
||||
--- cloud-init-18.2.orig/systemd/cloud-init-generator
|
||||
+++ cloud-init-18.2/systemd/cloud-init-generator
|
||||
--- systemd/cloud-init-generator.orig
|
||||
+++ systemd/cloud-init-generator
|
||||
@@ -9,7 +9,7 @@ DISABLE="disabled"
|
||||
FOUND="found"
|
||||
NOTFOUND="notfound"
|
||||
|
Loading…
Reference in New Issue
Block a user