Hello community,

here is the log from the commit of package cloud-init for openSUSE:Factory 
checked in at 2018-01-30 15:46:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cloud-init (Old)
 and      /work/SRC/openSUSE:Factory/.cloud-init.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "cloud-init"

Tue Jan 30 15:46:07 2018 rev:46 rq:571062 version:17.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/cloud-init/cloud-init.changes    2018-01-25 
12:41:03.489213778 +0100
+++ /work/SRC/openSUSE:Factory/.cloud-init.new/cloud-init.changes       
2018-01-30 15:46:09.961668525 +0100
@@ -1,0 +2,28 @@
+Tue Jan 30 13:20:57 UTC 2018 - dmuel...@suse.com
+
+- drop dependency on boto (only used in examples, and
+  should really be ported to botocore/boto3 instead)
+
+-------------------------------------------------------------------
+Mon Jan 29 18:35:49 UTC 2018 - rjsch...@suse.com
+
+- Update to version 17.2 (boo#1069635, bsc#1072811)
+  + Add cloud-init-skip-ovf-tests.patch
+  + Add cloud-init-no-python-linux-dist.patch
+  + Add 0001-switch-to-using-iproute2-tools.patch
+  + Add 0001-Support-chrony-configuration-lp-1731619.patch
+  + Add 0002-Disable-method-deprecation-warning-for-pylint.patch
+  + Add 0003-Distro-dependent-chrony-config-file.patch
+  + removed cloud-init-add-variant-cloudcfg.patch replaced by
+    cloud-init-no-python-linux-dist.patch
+  + removed zypp_add_repos.diff included upstream
+  + removed zypp_add_repo_test.patch included upstream
+  + removed cloud-init-hosts-template.patch included upstream
+  + removed cloud-init-more-tasks.patch included upstream
+  + removed cloud-init-final-no-apt.patch included upstream
+  + removed cloud-init-ntp-conf-suse.patch included upstream
+  + removed cloud-init-break-cycle-local-service.patch included upstream
+  + removed cloud-init-reproduce-build.patch included upstream
+  + For the complete changelog see https://launchpad.net/cloud-init/trunk/17.2
+
+-------------------------------------------------------------------

Old:
----
  cloud-init-17.1.tar.gz
  cloud-init-add-variant-cloudcfg.patch
  cloud-init-break-cycle-local-service.patch
  cloud-init-final-no-apt.patch
  cloud-init-hosts-template.patch
  cloud-init-more-tasks.patch
  cloud-init-ntp-conf-suse.patch
  cloud-init-reproduce-build.patch
  zypp_add_repo_test.patch
  zypp_add_repos.diff

New:
----
  0001-Support-chrony-configuration-lp-1731619.patch
  0001-switch-to-using-iproute2-tools.patch
  0002-Disable-method-deprecation-warning-for-pylint.patch
  0003-Distro-dependent-chrony-config-file.patch
  cloud-init-17.2.tar.gz
  cloud-init-no-python-linux-dist.patch
  cloud-init-skip-ovf-tests.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ cloud-init.spec ++++++
--- /var/tmp/diff_new_pack.QsTuoM/_old  2018-01-30 15:46:10.841627445 +0100
+++ /var/tmp/diff_new_pack.QsTuoM/_new  2018-01-30 15:46:10.845627259 +0100
@@ -18,7 +18,7 @@
 %global configver 0.7
 
 Name:           cloud-init
-Version:        17.1
+Version:        17.2
 Release:        0
 License:        GPL-3.0 and AGPL-3.0
 Summary:        Cloud node initialization tool
@@ -26,34 +26,35 @@
 Group:          System/Management
 Source0:        %{name}-%{version}.tar.gz
 Source1:        rsyslog-cloud-init.cfg
-# Remove Patch 4 & 5 for next source updated, included upstream
-Patch4:         zypp_add_repos.diff
-Patch5:         zypp_add_repo_test.patch
-# Remove Patch 6 for next source updated, included upstream (bsc#1064594)
-Patch6:         cloud-init-hosts-template.patch
-# FIXME cloud-init-ntp-conf-suse.patch proposed for upstream merge (lp#1726572)
-Patch7:         cloud-init-ntp-conf-suse.patch
+
 # 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
-# FIXME cloud-init-break-cycle-local-service.patch
-Patch9:         cloud-init-break-cycle-local-service.patch
 Patch10:        cloud-init-no-user-lock-if-already-locked.patch
 Patch12:        fix-default-systemd-unit-dir.patch
-# Remove Patch 13 for next source updated, included upstream
-Patch13:        cloud-init-more-tasks.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
 Patch29:        datasourceLocalDisk.patch
 Patch34:        cloud-init-tests-set-exec.patch
-Patch35:        cloud-init-final-no-apt.patch
 # FIXME cloud-init-resize-ro-btrfs.patch
 # proposed for upstream merge (lp#1734787)
 Patch36:        cloud-init-resize-ro-btrfs.patch
-# FIXME cloud-init-reproduce-build.patch, expecting upstream merge
-Patch37:        cloud-init-reproduce-build.patch
-Patch38:       cloud-init-add-variant-cloudcfg.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
+Patch38:        0002-Disable-method-deprecation-warning-for-pylint.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
 BuildRequires:  fdupes
 BuildRequires:  filesystem
 # pkg-config is needed to find correct systemd unit dir
@@ -65,7 +66,6 @@
 BuildRequires:  python3-setuptools
 # Test requirements
 BuildRequires:  python3-Jinja2
-BuildRequires:  python3-PrettyTable
 BuildRequires:  python3-PyYAML
 BuildRequires:  python3-configobj >= 5.0.2
 BuildRequires:  python3-httpretty
@@ -88,23 +88,19 @@
 %else
 BuildRequires:  sles-release
 %endif
+BuildRequires:  util-linux
 Requires:       bash
 Requires:       file
 Requires:       growpart
 Requires:       e2fsprogs
 Requires:          net-tools
-%if 0%{?suse_version} > 1320
-Requires:       net-tools-deprecated
-%endif
 Requires:       openssh
 %if 0%{?suse_version} > 1320
-Requires:       python3-boto >= 2.7
 Requires:       python3-configobj >= 5.0.2
 Requires:       python3-Jinja2
 Requires:       python3-jsonpatch
 Requires:       python3-jsonschema
 Requires:       python3-oauthlib
-Requires:       python3-PrettyTable
 Requires:       python3-pyserial
 Requires:       python3-PyYAML
 Requires:       python3-requests
@@ -113,13 +109,11 @@
 Requires:       python3-xml
 %else
 Requires:       python-argparse
-Requires:       python-boto >= 2.7
 Requires:       python-configobj >= 5.0.2
 Requires:       python-Jinja2
 Requires:       python-jsonpatch
 Requires:       python-jsonschema
 Requires:       python-oauthlib
-Requires:       python-PrettyTable
 Requires:       python-pyserial
 Requires:       python-PyYAML
 Requires:       python-requests
@@ -132,16 +126,9 @@
 Requires:       cloud-init-config = %configver
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 %define         docdir %{_defaultdocdir}/%{name}
-%if 0%{?suse_version} && 0%{?suse_version} <= 1110
-%{!?python_sitelib: %global python_sitelib %(python -c "from 
distutils.sysconfig import get_python_lib; print get_python_lib()")}
-%ifarch %ix86 x86_64
-Requires:       pmtools
-%endif
-%else
 %ifarch %ix86 x86_64
 Requires:       dmidecode
 %endif
-%endif
 %if 0%{?suse_version} && 0%{?suse_version} <= 1210
 %define initsys sysvinit_suse
 %else
@@ -158,12 +145,8 @@
 %if 0%{?suse_version} && 0%{?suse_version} >= 1315
 Requires:      wicked-service
 %else
-%if 0%{?suse_version} && 0%{?suse_version} <= 1110
-Requires:      sysconfig
-%else
 Requires:      sysconfig-network
 %endif
-%endif
 
 %description
 Cloud-init is an init script that initializes a cloud node (VM)
@@ -203,25 +186,20 @@
 
 %prep
 %setup -q
-%patch4  -p0
-%patch5  -p0
-%patch6
-%patch7
 %patch8
-%patch9
 %patch10 -p1
 %patch12
-%patch13
 %patch20
 %patch27
 %patch29 -p0
 %patch34
-%patch35 -p1
 %patch36
-%patch37
-%if 0%{?suse_version} && 0%{?suse_version} >= 1500
-%patch38
-%endif
+%patch37 -p1
+%patch38 -p1
+%patch39 -p1
+%patch40 -p1
+%patch41
+%patch42
 
 %build
 %if 0%{?suse_version} && 0%{?suse_version} <= 1315
@@ -259,32 +237,20 @@
 # move documentation
 mkdir -p %{buildroot}%{_defaultdocdir}
 mv %{buildroot}%{_datadir}/doc/%{name} %{buildroot}%{docdir}
-%if 0%{?suse_version} <= 1130
-# disable ecdsa for SLE 11 (not available)
-echo "ssh_genkeytypes: ['rsa', 'dsa']" >> 
%{buildroot}/%{_sysconfdir}/cloud/cloud.cfg
-%endif
 # copy the LICENSE
 cp LICENSE %{buildroot}%{docdir}
 # Set the distribution indicator
 %if 0%{?suse_version}
-%if 0%{?suse_version} < 1130
-#SLE 11, openSUSE 11.x is EOL
-sed -i s/suse/sles/ %{buildroot}/%{_sysconfdir}/cloud/cloud.cfg
-%endif
-%if 0%{?suse_version} > 1140
 %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
-%endif
-%if 0%{?suse_version} && 0%{?suse_version} > 1110
 mkdir -p %{buildroot}/%{_sysconfdir}/rsyslog.d
 mkdir -p %{buildroot}/usr/lib/udev/rules.d/
 cp -a %{SOURCE1} %{buildroot}/%{_sysconfdir}/rsyslog.d/21-cloudinit.conf
 mv %{buildroot}/lib/udev/rules.d/66-azure-ephemeral.rules 
%{buildroot}/usr/lib/udev/rules.d/
-%endif
 
 # remove debian/ubuntu specific profile.d file (bnc#779553)
 rm -f %{buildroot}%{_sysconfdir}/profile.d/Z99-cloud-locale-test.sh

++++++ 0001-Support-chrony-configuration-lp-1731619.patch ++++++
++++ 782 lines (skipped)

++++++ 0001-switch-to-using-iproute2-tools.patch ++++++
++++ 682 lines (skipped)

++++++ 0002-Disable-method-deprecation-warning-for-pylint.patch ++++++
>From d94392bb6e54a6860c8b6ea7967e853d8e263d7a Mon Sep 17 00:00:00 2001
From: Robert Schweikert <rjsch...@suse.com>
Date: Fri, 8 Dec 2017 17:03:01 -0500
Subject: [PATCH 2/3] - Disable method deprecation warning for pylint

---
 cloudinit/distros/opensuse.py | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/cloudinit/distros/opensuse.py b/cloudinit/distros/opensuse.py
index 092d6a11..86318eae 100644
--- a/cloudinit/distros/opensuse.py
+++ b/cloudinit/distros/opensuse.py
@@ -8,6 +8,10 @@
 #
 # This file is part of cloud-init. See LICENSE file for license information.
 
+# pylint: disable=W1505
+# platform.linux_distribution is deprecated (W1505) we need to decide if
+# cloud-init will implement it's own or add a new dependency on the
+# distro module
 import platform
 
 from cloudinit import distros
-- 
2.13.6

++++++ 0003-Distro-dependent-chrony-config-file.patch ++++++
>From 42cb1841035befa5b5823b3321c8fe92f2cb9087 Mon Sep 17 00:00:00 2001
From: Robert Schweikert <rjsch...@suse.com>
Date: Mon, 18 Dec 2017 14:54:10 -0500
Subject: [PATCH 3/3] - Distro dependent chrony config file   + We all like to
 stor ethe drift file in different places and name it     differently :(

---
 cloudinit/config/cc_ntp.py                         |  8 +++++--
 ...{chrony.conf.tmpl => chrony.conf.opensuse.tmpl} |  0
 templates/chrony.conf.sles.tmpl                    | 25 ++++++++++++++++++++++
 3 files changed, 31 insertions(+), 2 deletions(-)
 rename templates/{chrony.conf.tmpl => chrony.conf.opensuse.tmpl} (100%)
 create mode 100644 templates/chrony.conf.sles.tmpl

diff --git a/cloudinit/config/cc_ntp.py b/cloudinit/config/cc_ntp.py
index 2f662a9e..1db648bc 100644
--- a/cloudinit/config/cc_ntp.py
+++ b/cloudinit/config/cc_ntp.py
@@ -50,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
@@ -61,6 +62,9 @@ schema = {
         'ntp': {
             'type': ['object', 'null'],
             'properties': {
+                'enabled':  {
+                    "type": "boolean"
+                },
                 'pools': {
                     'type': 'array',
                     'items': {
@@ -109,7 +113,7 @@ def handle(name, cfg, cloud, log, _args):
     if not isinstance(ntp_cfg, (dict)):
         raise RuntimeError(("'ntp' key existed in config,"
                             " but not a dictionary type,"
-                            " is a %s %instead"), type_utils.obj_name(ntp_cfg))
+                            " is a %s instead"), type_utils.obj_name(ntp_cfg))
 
     if ntp_cfg.get('enabled') and ntp_cfg.get('enabled') == 'true':
         cloud.distro.set_timesync_client()
@@ -129,7 +133,7 @@ def handle(name, cfg, cloud, log, _args):
             template_name = 'timesyncd.conf'
         elif client_name == 'chrony':
             confpath = CHRONY_CONF_FILE
-            template_name = 'chrony.conf'
+            template_name = 'chrony.conf.%s' % cloud.distro.name
     else:
         if ntp_installable():
             service_name = 'ntp'
diff --git a/templates/chrony.conf.tmpl b/templates/chrony.conf.opensuse.tmpl
similarity index 100%
rename from templates/chrony.conf.tmpl
rename to templates/chrony.conf.opensuse.tmpl
diff --git a/templates/chrony.conf.sles.tmpl b/templates/chrony.conf.sles.tmpl
new file mode 100644
index 00000000..38e84d85
--- /dev/null
+++ b/templates/chrony.conf.sles.tmpl
@@ -0,0 +1,25 @@
+## 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
+
-- 
2.13.6

++++++ cloud-init-17.1.tar.gz -> cloud-init-17.2.tar.gz ++++++
++++ 16203 lines of diff (skipped)

++++++ cloud-init-no-python-linux-dist.patch ++++++
--- /dev/null
+++ cloudinit/tests/test_util.py
@@ -0,0 +1,129 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
+"""Tests for cloudinit.util"""
+
+import logging
+import platform
+
+import cloudinit.util as util
+
+from cloudinit.tests.helpers import CiTestCase, mock
+from textwrap import dedent
+
+LOG = logging.getLogger(__name__)
+
+MOUNT_INFO = [
+    '68 0 8:3 / / ro,relatime shared:1 - btrfs /dev/sda1 ro,attr2,inode64',
+    '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 TestUtil(CiTestCase):
+
+    def test_parse_mount_info_no_opts_no_arg(self):
+        result = util.parse_mount_info('/home', MOUNT_INFO, LOG)
+        self.assertEqual(('/dev/sda2', 'xfs', '/home'), result)
+
+    def test_parse_mount_info_no_opts_arg(self):
+        result = util.parse_mount_info('/home', MOUNT_INFO, LOG, False)
+        self.assertEqual(('/dev/sda2', 'xfs', '/home'), result)
+
+    def test_parse_mount_info_with_opts(self):
+        result = util.parse_mount_info('/', MOUNT_INFO, LOG, True)
+        self.assertEqual(
+            ('/dev/sda1', 'btrfs', '/', 'ro,relatime'),
+            result
+        )
+
+    @mock.patch('cloudinit.util.get_mount_info')
+    def test_mount_is_rw(self, m_mount_info):
+        m_mount_info.return_value = ('/dev/sda1', 'btrfs', '/', 'rw,relatime')
+        is_rw = util.mount_is_read_write('/')
+        self.assertEqual(is_rw, True)
+
+    @mock.patch('cloudinit.util.get_mount_info')
+    def test_mount_is_ro(self, m_mount_info):
+        m_mount_info.return_value = ('/dev/sda1', 'btrfs', '/', 'ro,relatime')
+        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)
+
+
+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
--- cloudinit/util.py.orig
+++ cloudinit/util.py
@@ -570,6 +570,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 = {
@@ -578,19 +615,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', 'debian', 'fedora', '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'
@@ -2053,7 +2090,7 @@ def expand_package_list(version_fmt, pkg
     return pkglist
 
 
-def parse_mount_info(path, mountinfo_lines, log=LOG):
+def parse_mount_info(path, mountinfo_lines, log=LOG, get_mnt_opts=False):
     """Return the mount information for PATH given the lines from
     /proc/$$/mountinfo."""
 
@@ -2115,11 +2152,16 @@ def parse_mount_info(path, mountinfo_lin
 
         match_mount_point = mount_point
         match_mount_point_elements = mount_point_elements
+        mount_options = parts[5]
 
-    if devpth and fs_type and match_mount_point:
-        return (devpth, fs_type, match_mount_point)
+    if get_mnt_opts:
+        if devpth and fs_type and match_mount_point and mount_options:
+            return (devpth, fs_type, match_mount_point, mount_options)
     else:
-        return None
+        if devpth and fs_type and match_mount_point:
+            return (devpth, fs_type, match_mount_point)
+
+    return None
 
 
 def parse_mtab(path):
@@ -2189,7 +2231,7 @@ def parse_mount(path):
     return None
 
 
-def get_mount_info(path, log=LOG):
+def get_mount_info(path, log=LOG, get_mnt_opts=False):
     # Use /proc/$$/mountinfo to find the device where path is mounted.
     # This is done because with a btrfs filesystem using os.stat(path)
     # does not return the ID of the device.
@@ -2221,7 +2263,7 @@ def get_mount_info(path, log=LOG):
     mountinfo_path = '/proc/%s/mountinfo' % os.getpid()
     if os.path.exists(mountinfo_path):
         lines = load_file(mountinfo_path).splitlines()
-        return parse_mount_info(path, lines, log)
+        return parse_mount_info(path, lines, log, get_mnt_opts)
     elif os.path.exists("/etc/mtab"):
         return parse_mtab(path)
     else:
@@ -2329,7 +2371,8 @@ def pathprefix2dict(base, required=None,
                 missing.append(f)
 
     if len(missing):
-        raise ValueError("Missing required files: %s", ','.join(missing))
+        raise ValueError(
+            'Missing required files: {files}'.format(files=','.join(missing)))
 
     return ret
 
@@ -2606,4 +2649,10 @@ def wait_for_files(flist, maxwait, naple
     return need
 
 
+def mount_is_read_write(mount_point):
+    """Check whether the given mount point is mounted rw"""
+    result = get_mount_info(mount_point, get_mnt_opts=True)
+    mount_opts = result[-1].split(',')
+    return mount_opts[0] == 'rw'
+
 # vi: ts=4 expandtab
--- setup.py.orig
+++ setup.py
@@ -1,3 +1,4 @@
+
 # Copyright (C) 2009 Canonical Ltd.
 # Copyright (C) 2012 Yahoo! Inc.
 #
@@ -25,7 +26,7 @@ from distutils.errors import DistutilsAr
 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)],
@@ -227,6 +238,19 @@ if not in_virtualenv():
     for k in INITSYS_ROOTS.keys():
         INITSYS_ROOTS[k] = "/" + INITSYS_ROOTS[k]
 
+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()
+
 data_files = [
     (ETC + '/cloud', [render_tmpl("config/cloud.cfg.tmpl")]),
     (ETC + '/cloud/cloud.cfg.d', glob('config/cloud.cfg.d/*')),
@@ -259,7 +283,7 @@ requirements = read_requires()
 setuptools.setup(
     name='cloud-init',
     version=get_version(),
-    description='EC2 initialisation magic',
+    description='Cloud instance initialisation magic',
     author='Scott Moser',
     author_email='scott.mo...@canonical.com',
     url='http://launchpad.net/cloud-init/',
++++++ cloud-init-skip-ovf-tests.patch ++++++
--- 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(

Reply via email to