From 1609354cf9e911a75336d183c4637ddefc0babaa431000dd97458665fde50b28 Mon Sep 17 00:00:00 2001 From: Robert Schweikert Date: Tue, 6 Dec 2016 13:17:52 +0000 Subject: [PATCH 1/4] Accepting request 443055 from home:kukuk:branches:Cloud:Tools - Fix datasourceLocalDisk module in case directory exists but is empty. - Add Conflicts for otherproviders of cloud-init-config. - Add require for python-six (used by several modules) - Add LocalDisk datasource [FATE#321107] - Reworked zypp_add_repos.diff to behave similar to zypper ar - Move cloud.cfg into an own sub-package, so that we can have a product specific version. [FATE#322039] OBS-URL: https://build.opensuse.org/request/show/443055 OBS-URL: https://build.opensuse.org/package/show/Cloud:Tools/cloud-init?expand=0&rev=67 --- cloud-init.changes | 28 ++++++++++ cloud-init.spec | 24 +++++++-- datasourceLocalDisk.patch | 104 ++++++++++++++++++++++++++++++++++++++ zypp_add_repos.diff | 30 ++++++----- 4 files changed, 171 insertions(+), 15 deletions(-) create mode 100644 datasourceLocalDisk.patch diff --git a/cloud-init.changes b/cloud-init.changes index af785f3..b4d8a79 100644 --- a/cloud-init.changes +++ b/cloud-init.changes @@ -1,3 +1,31 @@ +------------------------------------------------------------------- +Thu Dec 1 12:31:09 CET 2016 - kukuk@suse.de + +- Fix datasourceLocalDisk module in case directory exists but is + empty. + +------------------------------------------------------------------- +Wed Nov 30 08:48:11 UTC 2016 - kukuk@suse.com + +- Add Conflicts for otherproviders of cloud-init-config. +- Add require for python-six (used by several modules) + +------------------------------------------------------------------- +Mon Nov 28 07:20:13 UTC 2016 - kukuk@suse.com + +- Add LocalDisk datasource [FATE#321107] + +------------------------------------------------------------------- +Wed Nov 23 15:05:06 CET 2016 - kukuk@suse.de + +- Reworked zypp_add_repos.diff to behave similar to zypper ar + +------------------------------------------------------------------- +Tue Nov 22 10:57:01 CET 2016 - kukuk@suse.de + +- Move cloud.cfg into an own sub-package, so that we can have + a product specific version. [FATE#322039] + ------------------------------------------------------------------- Sun Nov 13 13:33:41 CET 2016 - kukuk@suse.de diff --git a/cloud-init.spec b/cloud-init.spec index 21883d1..e0ce6df 100644 --- a/cloud-init.spec +++ b/cloud-init.spec @@ -50,7 +50,8 @@ Patch24: cloud-init-handle-no-carrier.patch Patch25: cloud-init-digital-ocean-datasource.patch Patch26: cloud-init-digital-ocean-datasource-enable-by-default.patch Patch27: cloud-init-sysconfig-netpathfix.patch -Patch28: zypp_add_repos.diff +Patch28: zypp_add_repos.diff +Patch29: datasourceLocalDisk.patch BuildRequires: fdupes BuildRequires: filesystem BuildRequires: python-devel @@ -92,9 +93,11 @@ Requires: python-pyserial Requires: python-PyYAML Requires: python-requests Requires: python-setuptools +Requires: python-six Requires: python-xml Requires: sudo Requires: util-linux +Requires: cloud-init-config BuildRoot: %{_tmppath}/%{name}-%{version}-build %define docdir %{_defaultdocdir}/%{name} %if 0%{?suse_version} && 0%{?suse_version} <= 1110 @@ -134,6 +137,16 @@ Requires: sysconfig-network Cloud-init is an init script that initializes a cloud node (VM) according to the fetched configuration data from the admin node. +%package config-suse +Summary: Configuration file for Cloud node initialization tool +Requires: cloud-init = %{version} +Provides: cloud-init-config +Conflicts: otherproviders(cloud-init-config) + +%description config-suse +This package contains the product specific configuration file +for cloud-init. + %package doc Summary: Cloud node initialization tool - Documentation Group: System/Management @@ -178,6 +191,7 @@ Unit tests for the cloud-init tools %patch26 -p1 %patch27 %patch28 -p0 +%patch29 -p0 %if 0%{?suse_version} <= 1130 # disable ecdsa for SLE 11 (not available) @@ -268,7 +282,9 @@ popd %{docdir}/LICENSE %{_bindir}/cloud-init %{_bindir}/cloud-init-per -%config(noreplace) %{_sysconfdir}/cloud/ +%dir %{_sysconfdir}/cloud +%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d +%config(noreplace) %{_sysconfdir}/cloud/templates %{_sysconfdir}/dhcp/dhclient-exit-hooks.d/hook-dhclient %{_sysconfdir}/NetworkManager/dispatcher.d/hook-network-manager %{python_sitelib}/cloudinit @@ -309,7 +325,9 @@ popd %dir /etc/dhcp %dir /etc/dhcp/dhclient-exit-hooks.d - +%files config-suse +%defattr(-,root,root) +%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg %files doc %defattr(-,root,root) diff --git a/datasourceLocalDisk.patch b/datasourceLocalDisk.patch new file mode 100644 index 0000000..e4865f0 --- /dev/null +++ b/datasourceLocalDisk.patch @@ -0,0 +1,104 @@ +--- cloudinit/sources/DataSourceLocalDisk.py 2016/11/25 19:01:00 1.1 ++++ cloudinit/sources/DataSourceLocalDisk.py 2016/11/26 20:42:02 +@@ -0,0 +1,101 @@ ++# vi: ts=4 expandtab ++# ++# Copyright (C) 2016 SUSE Linux GmbH ++# ++# Author: Thorsten Kukuk ++# ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License version 3, as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++import os ++ ++from cloudinit import log as logging ++from cloudinit import sources ++from cloudinit import util ++ ++LOG = logging.getLogger(__name__) ++ ++DEFAULT_IID = "iid-localdisk" ++ ++ ++class DataSourceLocalDisk(sources.DataSource): ++ def __init__(self, sys_cfg, distro, paths): ++ sources.DataSource.__init__(self, sys_cfg, distro, paths) ++ self.seed = None ++ self.seed_dir = os.path.join(paths.seed_dir, 'localdisk') ++ ++ def __str__(self): ++ root = sources.DataSource.__str__(self) ++ return "%s [seed=%s][dsmode=%s]" % (root, self.seed, self.dsmode) ++ ++ def get_data(self): ++ if not os.path.isdir('/cloud-init-config') ++ return False ++ ++ defaults = {"instance-id": DEFAULT_IID} ++ ++ found = [] ++ mydata = {'meta-data': {}, 'user-data': "", 'vendor-data': ""} ++ ++ # Check to see if the seed dir has data. ++ try: ++ seeded = util.pathprefix2dict(self.seed_dir, ['user-data','meta-data'],['vendor-data']) ++ found.append(self.seed_dir) ++ mydata = _merge_new_seed(mydata, seeded) ++ except ValueError as e: ++ pass ++ ++ try: ++ seeded = util.pathprefix2dict('/cloud-init-config', ['user-data','meta-data'],['vendor-data']) ++ found.append('/cloud-init-config') ++ mydata = _merge_new_seed(mydata, seeded) ++ except ValueError as e: ++ return False ++ ++ # Merge in the defaults ++ mydata['meta-data'] = util.mergemanydict([mydata['meta-data'], ++ defaults]) ++ ++ self.seed = ",".join(found) ++ self.metadata = mydata['meta-data'] ++ self.userdata_raw = mydata['user-data'] ++ self.vendordata_raw = mydata['vendor-data'] ++ return True ++ ++ def check_instance_id(self, sys_cfg): ++ # quickly (local check only) if self.instance_id is still valid ++ return sources.instance_id_matches_system_uuid(self.get_instance_id()) ++ ++def _merge_new_seed(cur, seeded): ++ ret = cur.copy() ++ ++ newmd = seeded.get('meta-data', {}) ++ if not isinstance(seeded['meta-data'], dict): ++ newmd = util.load_yaml(seeded['meta-data']) ++ ret['meta-data'] = util.mergemanydict([cur['meta-data'], newmd]) ++ ++ if 'user-data' in seeded: ++ ret['user-data'] = seeded['user-data'] ++ if 'vendor-data' in seeded: ++ ret['vendor-data'] = seeded['vendor-data'] ++ return ret ++ ++ ++# Used to match classes to dependencies ++datasources = [ ++ (DataSourceLocalDisk, (sources.DEP_FILESYSTEM, )), ++] ++ ++ ++# Return a list of data sources that match this set of dependencies ++def get_datasource_list(depends): ++ return sources.list_from_depends(depends, datasources) diff --git a/zypp_add_repos.diff b/zypp_add_repos.diff index d3bc2eb..0606c17 100644 --- a/zypp_add_repos.diff +++ b/zypp_add_repos.diff @@ -1,9 +1,13 @@ --- cloudinit/config/cc_zypp_add_repo.py -+++ cloudinit/config/cc_zypp_add_repo.py 2016/11/13 16:56:21 -@@ -0,0 +1,106 @@ ++++ cloudinit/config/cc_zypp_add_repo.py 2016/11/23 13:10:49 +@@ -0,0 +1,112 @@ +# vi: ts=4 expandtab +# -+# This file is based on cc_yum_add_repo.py: ++# Copyright (C) 2016 SUSE LLC. ++# This file is based on cc_yum_add_repo.py and was rewritten by ++# Thorsten Kukuk for zypp repos. ++# ++# Original file was: +# +# Copyright (C) 2012 Yahoo! Inc. +# @@ -56,7 +60,6 @@ + # of zypper repos and don't verify keys/values further + to_be[repo_id][k] = _format_repo_value(v) + lines = to_be.write() -+ lines.insert(0, "# Created by cloud-init on %s" % (util.time_rfc2822())) + return "\n".join(lines) + + @@ -77,7 +80,7 @@ + log.info("Skipping repo %s, file %s already exists!", + repo_id, repo_fn_pth) + continue -+ elif canon_repo_id in repo_locations: ++ elif repo_id in repo_locations: + log.info("Skipping repo %s, file %s already pending!", + repo_id, repo_fn_pth) + continue @@ -97,9 +100,12 @@ + " configuration 'required' entry"), + repo_id, req_field) + missing_required += 1 ++ for field in ['enabled', 'autorefresh']: ++ if field not in repo_config: ++ repo_config[field] = '1' + if not missing_required: -+ repo_configs[canon_repo_id] = repo_config -+ repo_locations[canon_repo_id] = repo_fn_pth ++ repo_configs[repo_id] = repo_config ++ repo_locations[repo_id] = repo_fn_pth + else: + log.warn("Repository %s is missing %s required fields, skipping!", + repo_id, missing_required) @@ -108,23 +114,23 @@ + repo_configs.get(c_repo_id)) + util.write_file(path, repo_blob) --- doc/examples/cloud-config-zypp-repo.txt -+++ doc/examples/cloud-config-zypp-repo.txt 2016/11/13 17:04:12 ++++ doc/examples/cloud-config-zypp-repo.txt 2016/11/23 12:59:42 @@ -0,0 +1,18 @@ +#cloud-config +# vim: syntax=yaml +# +# Add zypper repository configuration to the system +# -+# The following example adds the file /etc/zypp/repos.d/EPEL_TESTING.repo ++# The following example adds the file /etc/zypp/repos.d/Test_Repo.repo +# which can then subsequently be used by zypper for later operations. +zypp_repos: + # The name of the repository -+ EPEL_Testing: ++ "Test Repo": + # Any repository configuration options + name: Extra Packages for Testing + enabled: true + autorefresh: true + keeppackages: false -+ baseurl: http://download.example.com/ibs/EPEL/1.0/standard/ ++ baseurl: http://download.example.com/ibs/TEST/1.0/standard/ + gpgcheck: true -+ gpgkey: http://download.example.com/ibs/EPEL/1.0/standard/repodata/repomd.xml.key ++ gpgkey: http://download.example.com/ibs/TEST/1.0/standard/repodata/repomd.xml.key From 60ccce8b3e8fab79849277e4b1d2d471023f04d3909469d71466ed3e35f7297e Mon Sep 17 00:00:00 2001 From: Robert Schweikert Date: Tue, 6 Dec 2016 13:47:20 +0000 Subject: [PATCH 2/4] - Add LocalDisk datasource datasourceLocalDisk.patch [FATE#321107] OBS-URL: https://build.opensuse.org/package/show/Cloud:Tools/cloud-init?expand=0&rev=68 --- cloud-init.changes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud-init.changes b/cloud-init.changes index b4d8a79..7c387f5 100644 --- a/cloud-init.changes +++ b/cloud-init.changes @@ -13,7 +13,7 @@ Wed Nov 30 08:48:11 UTC 2016 - kukuk@suse.com ------------------------------------------------------------------- Mon Nov 28 07:20:13 UTC 2016 - kukuk@suse.com -- Add LocalDisk datasource [FATE#321107] +- Add LocalDisk datasource datasourceLocalDisk.patch [FATE#321107] ------------------------------------------------------------------- Wed Nov 23 15:05:06 CET 2016 - kukuk@suse.de From 0548ac26cd02518a95e9a442b642f411bb73f679f2829905e9c8c7af6ee2b1a7 Mon Sep 17 00:00:00 2001 From: Dirk Mueller Date: Thu, 8 Dec 2016 12:36:16 +0000 Subject: [PATCH 3/4] - fix the cloud.cfg split, cyclic non-versioned dependencies are bad. also fix changelog entries - add datasourceLocalDisk.patch: * Fix datasourceLocalDisk module in case directory exists but is OBS-URL: https://build.opensuse.org/package/show/Cloud:Tools/cloud-init?expand=0&rev=69 --- cloud-init.changes | 9 ++++++++- cloud-init.spec | 5 ++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/cloud-init.changes b/cloud-init.changes index 7c387f5..e71f894 100644 --- a/cloud-init.changes +++ b/cloud-init.changes @@ -1,7 +1,14 @@ +------------------------------------------------------------------- +Thu Dec 8 12:35:51 UTC 2016 - dmueller@suse.com + +- fix the cloud.cfg split, cyclic non-versioned dependencies are + bad. also fix changelog entries + ------------------------------------------------------------------- Thu Dec 1 12:31:09 CET 2016 - kukuk@suse.de -- Fix datasourceLocalDisk module in case directory exists but is +- add datasourceLocalDisk.patch: + * Fix datasourceLocalDisk module in case directory exists but is empty. ------------------------------------------------------------------- diff --git a/cloud-init.spec b/cloud-init.spec index e0ce6df..a8d5c61 100644 --- a/cloud-init.spec +++ b/cloud-init.spec @@ -97,7 +97,7 @@ Requires: python-six Requires: python-xml Requires: sudo Requires: util-linux -Requires: cloud-init-config +Requires: cloud-init-config = %{version} BuildRoot: %{_tmppath}/%{name}-%{version}-build %define docdir %{_defaultdocdir}/%{name} %if 0%{?suse_version} && 0%{?suse_version} <= 1110 @@ -139,8 +139,7 @@ according to the fetched configuration data from the admin node. %package config-suse Summary: Configuration file for Cloud node initialization tool -Requires: cloud-init = %{version} -Provides: cloud-init-config +Provides: cloud-init-config = %{version} Conflicts: otherproviders(cloud-init-config) %description config-suse From ef7ff0197fbbf6b3b670efda7a0d65c970cdd338e8550a740722bea1d3e3a0a0 Mon Sep 17 00:00:00 2001 From: Robert Schweikert Date: Fri, 9 Dec 2016 12:50:46 +0000 Subject: [PATCH 4/4] Accepting request 445052 from home:jgleissner:branches:Cloud:Tools fix handling of user maintained hostname OBS-URL: https://build.opensuse.org/request/show/445052 OBS-URL: https://build.opensuse.org/package/show/Cloud:Tools/cloud-init?expand=0&rev=70 --- cloud-init-python26.patch | 23 +++++++++++++++++++++++ cloud-init.changes | 9 +++++++++ cloud-init.spec | 6 ++++++ suseIntegratedHandler.patch | 21 ++++++++++++++++----- 4 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 cloud-init-python26.patch diff --git a/cloud-init-python26.patch b/cloud-init-python26.patch new file mode 100644 index 0000000..d540409 --- /dev/null +++ b/cloud-init-python26.patch @@ -0,0 +1,23 @@ +Index: cloud-init-0.7.8/cloudinit/util.py +=================================================================== +--- cloud-init-0.7.8.orig/cloudinit/util.py ++++ cloud-init-0.7.8/cloudinit/util.py +@@ -283,9 +283,6 @@ class ProcessExecutionError(IOError): + 'reason': self.reason, + } + IOError.__init__(self, message) +- # For backward compatibility with Python 2. +- if not hasattr(self, 'message'): +- self.message = message + + + class SeLinuxGuard(object): +@@ -1816,7 +1813,7 @@ def subp(args, data=None, rcs=None, env= + def ldecode(data, m='utf-8'): + if not isinstance(data, bytes): + return data +- return data.decode(m, errors=decode) ++ return data.decode(m, decode) + + out = ldecode(out) + err = ldecode(err) diff --git a/cloud-init.changes b/cloud-init.changes index e71f894..6aee8a0 100644 --- a/cloud-init.changes +++ b/cloud-init.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Fri Dec 9 09:50:50 UTC 2016 - jgleissner@suse.com + +- Modify suseIntegratedHandler.patch (bsc#998103) + + Store previous hostname so update_hostname module does not + overwrite manually set hostnames +- cloud-init-python26.patch + + Compatibility fixes with Python 2.6 + ------------------------------------------------------------------- Thu Dec 8 12:35:51 UTC 2016 - dmueller@suse.com diff --git a/cloud-init.spec b/cloud-init.spec index a8d5c61..927a808 100644 --- a/cloud-init.spec +++ b/cloud-init.spec @@ -112,6 +112,7 @@ Requires: dmidecode %endif %if 0%{?suse_version} && 0%{?suse_version} <= 1210 %define initsys sysvinit_suse +Patch40: cloud-init-python26.patch %else %define initsys systemd BuildRequires: systemd @@ -139,7 +140,9 @@ according to the fetched configuration data from the admin node. %package config-suse Summary: Configuration file for Cloud node initialization tool +Requires: cloud-init = %{version} Provides: cloud-init-config = %{version} +Group: System/Management Conflicts: otherproviders(cloud-init-config) %description config-suse @@ -191,6 +194,9 @@ Unit tests for the cloud-init tools %patch27 %patch28 -p0 %patch29 -p0 +%if 0%{?suse_version} && 0%{?suse_version} <= 1210 +%patch40 -p1 +%endif %if 0%{?suse_version} <= 1130 # disable ecdsa for SLE 11 (not available) diff --git a/suseIntegratedHandler.patch b/suseIntegratedHandler.patch index c411035..e48d281 100644 --- a/suseIntegratedHandler.patch +++ b/suseIntegratedHandler.patch @@ -1,6 +1,8 @@ +Index: cloudinit/distros/opensuse.py +=================================================================== --- /dev/null +++ cloudinit/distros/opensuse.py -@@ -0,0 +1,226 @@ +@@ -0,0 +1,233 @@ +# vi: ts=4 expandtab +# +# Copyright (C) 2016 SUSE LLC @@ -134,9 +136,14 @@ + + + def _read_hostname(self, filename, default=None): -+ (out, _err) = util.subp(['hostname']) -+ if len(out): -+ return out ++ if self.systemdDist and filename.endswith('/previous-hostname'): ++ return util.load_file(filename).strip() ++ elif self.systemdDist: ++ (out, _err) = util.subp(['hostname']) ++ if len(out): ++ return out ++ else: ++ return default + else: + try: + conf = self._read_hostname_conf(filename) @@ -160,7 +167,9 @@ + return (host_fn, self._read_hostname(host_fn)) + + def _write_hostname(self, hostname, out_fn): -+ if self.systemdDist: ++ if self.systemdDist and out_fn.endswith('/previous-hostname'): ++ util.write_file(out_fn, hostname) ++ elif self.systemdDist: + util.subp(['hostnamectl', 'set-hostname', str(hostname)]) + else: + conf = None @@ -227,6 +236,8 @@ +# ns = parse_net_config_data(netconfig) +# self._net_renderer.render_network_state("/", ns) +# return [] +Index: cloudinit/distros/sles.py +=================================================================== --- cloudinit/distros/sles.py.orig +++ cloudinit/distros/sles.py @@ -1,10 +1,9 @@