summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Padgett <gpadgett@redhat.com>2013-04-10 12:19:37 -0400
committerScott Moser <smoser@ubuntu.com>2013-04-10 12:19:37 -0400
commitb9c6f197b6865987e9cdd2cd71fa1a5a9dff11c5 (patch)
tree05953e7b1d262fb783068209cffb9fd4a76080ce
parent1c2adfa3835e031a0f946cef0d99fcfe3dfc1c95 (diff)
parent984c72e522c585c6d3f6b3d3aec39fb21dd84028 (diff)
downloadvyos-cloud-init-b9c6f197b6865987e9cdd2cd71fa1a5a9dff11c5.tar.gz
vyos-cloud-init-b9c6f197b6865987e9cdd2cd71fa1a5a9dff11c5.zip
improvments to systemd/fedora 18 support
This branch contains fixes found while investigating integration of cloud-init into oVirt. They're in 3 categories: - compatibility with systemd configuration management (as used in Fedora 18) - workaround for a 2.6 kernel quirk which prevented 'blkid' from displaying /dev/sr0 in some cases - writing sysconfig files in typical convention, with a newline preceding EOF, to make some parsers happy
-rw-r--r--ChangeLog2
-rw-r--r--cloudinit/distros/rhel.py73
-rw-r--r--cloudinit/sources/DataSourceConfigDrive.py3
-rw-r--r--cloudinit/sources/DataSourceNoCloud.py3
-rw-r--r--cloudinit/util.py1
-rw-r--r--tests/unittests/test_datasource/test_configdrive.py5
6 files changed, 65 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 11a8b9c9..06c9de25 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -54,6 +54,8 @@
python-requests, we get https support (LP: #1067888).
- make apt-get invoke 'dist-upgrade' rather than 'upgrade' for
package_upgrade. (LP: #1164147)
+ - improvements for systemd with Fedora 18
+ - workaround 2.6 kernel issue that stopped blkid from showing /dev/sr0
0.7.1:
- sysvinit: fix missing dependency in cloud-init job for RHEL 5.6
diff --git a/cloudinit/distros/rhel.py b/cloudinit/distros/rhel.py
index 9fee5fd1..174da3ab 100644
--- a/cloudinit/distros/rhel.py
+++ b/cloudinit/distros/rhel.py
@@ -47,8 +47,10 @@ class Distro(distros.Distro):
# See: http://tiny.cc/6r99fw
clock_conf_fn = "/etc/sysconfig/clock"
locale_conf_fn = '/etc/sysconfig/i18n'
+ systemd_locale_conf_fn = '/etc/locale.conf'
network_conf_fn = "/etc/sysconfig/network"
hostname_conf_fn = "/etc/sysconfig/network"
+ systemd_hostname_conf_fn = "/etc/hostname"
network_script_tpl = '/etc/sysconfig/network-scripts/ifcfg-%s'
resolve_conf_fn = "/etc/resolv.conf"
tz_local_fn = "/etc/localtime"
@@ -143,21 +145,36 @@ class Distro(distros.Distro):
]
if not exists:
lines.insert(0, util.make_header())
- util.write_file(fn, "\n".join(lines), 0644)
+ util.write_file(fn, "\n".join(lines) + "\n", 0644)
+
+ def _dist_uses_systemd(self):
+ # Fedora 18 and RHEL 7 were the first adopters in their series
+ (dist, vers) = util.system_info()['dist'][:2]
+ major = (int)(vers.split('.')[0])
+ return ((dist.startswith('Red Hat Enterprise Linux') and major >= 7)
+ or (dist.startswith('Fedora') and major >= 18))
def apply_locale(self, locale, out_fn=None):
- if not out_fn:
- out_fn = self.locale_conf_fn
+ if self._dist_uses_systemd():
+ if not out_fn:
+ out_fn = self.systemd_locale_conf_fn
+ out_fn = self.systemd_locale_conf_fn
+ else:
+ if not out_fn:
+ out_fn = self.locale_conf_fn
locale_cfg = {
'LANG': locale,
}
self._update_sysconfig_file(out_fn, locale_cfg)
def _write_hostname(self, hostname, out_fn):
- host_cfg = {
- 'HOSTNAME': hostname,
- }
- self._update_sysconfig_file(out_fn, host_cfg)
+ if self._dist_uses_systemd():
+ util.subp(['hostnamectl', 'set-hostname', str(hostname)])
+ else:
+ host_cfg = {
+ 'HOSTNAME': hostname,
+ }
+ self._update_sysconfig_file(out_fn, host_cfg)
def _select_hostname(self, hostname, fqdn):
# See: http://bit.ly/TwitgL
@@ -167,15 +184,25 @@ class Distro(distros.Distro):
return hostname
def _read_system_hostname(self):
- return (self.network_conf_fn,
- self._read_hostname(self.network_conf_fn))
+ if self._dist_uses_systemd():
+ host_fn = self.systemd_hostname_conf_fn
+ else:
+ host_fn = self.hostname_conf_fn
+ return (host_fn, self._read_hostname(host_fn))
def _read_hostname(self, filename, default=None):
- (_exists, contents) = self._read_conf(filename)
- if 'HOSTNAME' in contents:
- return contents['HOSTNAME']
+ if self._dist_uses_systemd():
+ (out, _err) = util.subp(['hostname'])
+ if len(out):
+ return out
+ else:
+ return default
else:
- return default
+ (_exists, contents) = self._read_conf(filename)
+ if 'HOSTNAME' in contents:
+ return contents['HOSTNAME']
+ else:
+ return default
def _read_conf(self, fn):
exists = False
@@ -200,13 +227,19 @@ class Distro(distros.Distro):
if not os.path.isfile(tz_file):
raise RuntimeError(("Invalid timezone %s,"
" no file found at %s") % (tz, tz_file))
- # Adjust the sysconfig clock zone setting
- clock_cfg = {
- 'ZONE': str(tz),
- }
- self._update_sysconfig_file(self.clock_conf_fn, clock_cfg)
- # This ensures that the correct tz will be used for the system
- util.copy(tz_file, self.tz_local_fn)
+ if self._dist_uses_systemd():
+ # Currently, timedatectl complains if invoked during startup
+ # so for compatibility, create the link manually.
+ util.del_file(self.tz_local_fn)
+ util.sym_link(tz_file, self.tz_local_fn)
+ else:
+ # Adjust the sysconfig clock zone setting
+ clock_cfg = {
+ 'ZONE': str(tz),
+ }
+ self._update_sysconfig_file(self.clock_conf_fn, clock_cfg)
+ # This ensures that the correct tz will be used for the system
+ util.copy(tz_file, self.tz_local_fn)
def package_command(self, command, args=None, pkgs=None):
if pkgs is None:
diff --git a/cloudinit/sources/DataSourceConfigDrive.py b/cloudinit/sources/DataSourceConfigDrive.py
index 5f152299..d3443c2b 100644
--- a/cloudinit/sources/DataSourceConfigDrive.py
+++ b/cloudinit/sources/DataSourceConfigDrive.py
@@ -258,6 +258,9 @@ def find_candidate_devs():
* labeled with 'config-2'
"""
+ # Query optical drive to get it in blkid cache for 2.6 kernels
+ util.find_devs_with(path="/dev/sr0")
+
by_fstype = (util.find_devs_with("TYPE=vfat") +
util.find_devs_with("TYPE=iso9660"))
by_label = util.find_devs_with("LABEL=config-2")
diff --git a/cloudinit/sources/DataSourceNoCloud.py b/cloudinit/sources/DataSourceNoCloud.py
index 08a853cc..01c99028 100644
--- a/cloudinit/sources/DataSourceNoCloud.py
+++ b/cloudinit/sources/DataSourceNoCloud.py
@@ -87,6 +87,9 @@ class DataSourceNoCloud(sources.DataSource):
label = self.ds_cfg.get('fs_label', "cidata")
if label is not None:
+ # Query optical drive to get it in blkid cache for 2.6 kernels
+ util.find_devs_with(path="/dev/sr0")
+
fslist = util.find_devs_with("TYPE=vfat")
fslist.extend(util.find_devs_with("TYPE=iso9660"))
diff --git a/cloudinit/util.py b/cloudinit/util.py
index 36e9b83b..50de55fe 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -408,6 +408,7 @@ def system_info():
'release': platform.release(),
'python': platform.python_version(),
'uname': platform.uname(),
+ 'dist': platform.linux_distribution(),
}
diff --git a/tests/unittests/test_datasource/test_configdrive.py b/tests/unittests/test_datasource/test_configdrive.py
index 930086db..d5935294 100644
--- a/tests/unittests/test_datasource/test_configdrive.py
+++ b/tests/unittests/test_datasource/test_configdrive.py
@@ -259,8 +259,9 @@ class TestConfigDriveDataSource(MockerTestCase):
def test_find_candidates(self):
devs_with_answers = {}
- def my_devs_with(criteria):
- return devs_with_answers[criteria]
+ def my_devs_with(*args, **kwargs):
+ criteria = args[0] if len(args) else kwargs.pop('criteria', None)
+ return devs_with_answers.get(criteria, [])
def my_is_partition(dev):
return dev[-1] in "0123456789" and not dev.startswith("sr")