Merge lp:~gpadgett/cloud-init/ovirt into lp:~cloud-init-dev/cloud-init/trunk

Proposed by Greg Padgett
Status: Merged
Merged at revision: 809
Proposed branch: lp:~gpadgett/cloud-init/ovirt
Merge into: lp:~cloud-init-dev/cloud-init/trunk
Diff against target: 173 lines (+63/-22)
5 files modified
cloudinit/distros/rhel.py (+53/-20)
cloudinit/sources/DataSourceConfigDrive.py (+3/-0)
cloudinit/sources/DataSourceNoCloud.py (+3/-0)
cloudinit/util.py (+1/-0)
tests/unittests/test_datasource/test_configdrive.py (+3/-2)
To merge this branch: bzr merge lp:~gpadgett/cloud-init/ovirt
Reviewer Review Type Date Requested Status
cloud-init Commiters Pending
Review via email: mp+155634@code.launchpad.net

Description of the change

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

To post a comment you must log in.
Revision history for this message
Scott Moser (smoser) wrote :

this looks fine to me, the only question i have is over 'blkid' usage and /dev/sr0.
I have one concern. At one point I was just trying 'mount /dev/sr0' and expecting that to time out quickly, but it turned out that that was taking 18 seconds to time out in a VM with an empty cd-rom. (see revision 350).
   I just want to make sure that we're not going todo something similar here. I suspect not, but would like to make sure that you've verified that boot speed is not affected significantly by this.

Reguarding the systemd changes, I largely have to blindly trust you.
Maybe Josh can sanity check?

Revision history for this message
Greg Padgett (gpadgett) wrote :

Thanks Scott. I tested the blkid calls to existing-but-empty and non-existing /dev/srX devices and didn't see any delays. Not as methodically, but I also did plenty of reboots with and without attached media and speed seemed fine. This was all on Fedora 18, RHEL 6.4, and Ubuntu 12.04 LTS--if you can think of other versions or tests to run I'd be more than happy to try it out.

I'd welcome a systemd sanity check as well. So far it seems good based on my testing and the "Changes for System Administrators" section of the F18 manual. You/others may notice that the code manually manipulates the /etc/localtime symlink instead of using timedatectl--this was done to avoid a timeout (dbus-related?) and errors that happen if timedatectl is called during startup.

Revision history for this message
Joshua Harlow (harlowja) wrote :

Since I don't have access to RHEL7 yet I am hoping it works there.

Otherwise seems fine to me.

Revision history for this message
Greg Padgett (gpadgett) wrote :

> Since I don't have access to RHEL7 yet I am hoping it works there.

I'm hoping the same, I don't see a reason why it wouldn't.

> Otherwise seems fine to me.

Great, thanks.

Is there anything else I can do to help get this one in?

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cloudinit/distros/rhel.py'
2--- cloudinit/distros/rhel.py 2013-03-07 19:54:25 +0000
3+++ cloudinit/distros/rhel.py 2013-03-26 22:14:53 +0000
4@@ -47,8 +47,10 @@
5 # See: http://tiny.cc/6r99fw
6 clock_conf_fn = "/etc/sysconfig/clock"
7 locale_conf_fn = '/etc/sysconfig/i18n'
8+ systemd_locale_conf_fn = '/etc/locale.conf'
9 network_conf_fn = "/etc/sysconfig/network"
10 hostname_conf_fn = "/etc/sysconfig/network"
11+ systemd_hostname_conf_fn = "/etc/hostname"
12 network_script_tpl = '/etc/sysconfig/network-scripts/ifcfg-%s'
13 resolve_conf_fn = "/etc/resolv.conf"
14 tz_local_fn = "/etc/localtime"
15@@ -143,21 +145,36 @@
16 ]
17 if not exists:
18 lines.insert(0, util.make_header())
19- util.write_file(fn, "\n".join(lines), 0644)
20+ util.write_file(fn, "\n".join(lines) + "\n", 0644)
21+
22+ def _dist_uses_systemd(self):
23+ # Fedora 18 and RHEL 7 were the first adopters in their series
24+ (dist, vers) = util.system_info()['dist'][:2]
25+ major = (int)(vers.split('.')[0])
26+ return ((dist.startswith('Red Hat Enterprise Linux') and major >= 7)
27+ or (dist.startswith('Fedora') and major >= 18))
28
29 def apply_locale(self, locale, out_fn=None):
30- if not out_fn:
31- out_fn = self.locale_conf_fn
32+ if self._dist_uses_systemd():
33+ if not out_fn:
34+ out_fn = self.systemd_locale_conf_fn
35+ out_fn = self.systemd_locale_conf_fn
36+ else:
37+ if not out_fn:
38+ out_fn = self.locale_conf_fn
39 locale_cfg = {
40 'LANG': locale,
41 }
42 self._update_sysconfig_file(out_fn, locale_cfg)
43
44 def _write_hostname(self, hostname, out_fn):
45- host_cfg = {
46- 'HOSTNAME': hostname,
47- }
48- self._update_sysconfig_file(out_fn, host_cfg)
49+ if self._dist_uses_systemd():
50+ util.subp(['hostnamectl', 'set-hostname', str(hostname)])
51+ else:
52+ host_cfg = {
53+ 'HOSTNAME': hostname,
54+ }
55+ self._update_sysconfig_file(out_fn, host_cfg)
56
57 def _select_hostname(self, hostname, fqdn):
58 # See: http://bit.ly/TwitgL
59@@ -167,15 +184,25 @@
60 return hostname
61
62 def _read_system_hostname(self):
63- return (self.network_conf_fn,
64- self._read_hostname(self.network_conf_fn))
65+ if self._dist_uses_systemd():
66+ host_fn = self.systemd_hostname_conf_fn
67+ else:
68+ host_fn = self.hostname_conf_fn
69+ return (host_fn, self._read_hostname(host_fn))
70
71 def _read_hostname(self, filename, default=None):
72- (_exists, contents) = self._read_conf(filename)
73- if 'HOSTNAME' in contents:
74- return contents['HOSTNAME']
75+ if self._dist_uses_systemd():
76+ (out, _err) = util.subp(['hostname'])
77+ if len(out):
78+ return out
79+ else:
80+ return default
81 else:
82- return default
83+ (_exists, contents) = self._read_conf(filename)
84+ if 'HOSTNAME' in contents:
85+ return contents['HOSTNAME']
86+ else:
87+ return default
88
89 def _read_conf(self, fn):
90 exists = False
91@@ -200,13 +227,19 @@
92 if not os.path.isfile(tz_file):
93 raise RuntimeError(("Invalid timezone %s,"
94 " no file found at %s") % (tz, tz_file))
95- # Adjust the sysconfig clock zone setting
96- clock_cfg = {
97- 'ZONE': str(tz),
98- }
99- self._update_sysconfig_file(self.clock_conf_fn, clock_cfg)
100- # This ensures that the correct tz will be used for the system
101- util.copy(tz_file, self.tz_local_fn)
102+ if self._dist_uses_systemd():
103+ # Currently, timedatectl complains if invoked during startup
104+ # so for compatibility, create the link manually.
105+ util.del_file(self.tz_local_fn)
106+ util.sym_link(tz_file, self.tz_local_fn)
107+ else:
108+ # Adjust the sysconfig clock zone setting
109+ clock_cfg = {
110+ 'ZONE': str(tz),
111+ }
112+ self._update_sysconfig_file(self.clock_conf_fn, clock_cfg)
113+ # This ensures that the correct tz will be used for the system
114+ util.copy(tz_file, self.tz_local_fn)
115
116 def package_command(self, command, args=None, pkgs=None):
117 if pkgs is None:
118
119=== modified file 'cloudinit/sources/DataSourceConfigDrive.py'
120--- cloudinit/sources/DataSourceConfigDrive.py 2013-03-07 21:27:47 +0000
121+++ cloudinit/sources/DataSourceConfigDrive.py 2013-03-26 22:14:53 +0000
122@@ -258,6 +258,9 @@
123 * labeled with 'config-2'
124 """
125
126+ # Query optical drive to get it in blkid cache for 2.6 kernels
127+ util.find_devs_with(path="/dev/sr0")
128+
129 by_fstype = (util.find_devs_with("TYPE=vfat") +
130 util.find_devs_with("TYPE=iso9660"))
131 by_label = util.find_devs_with("LABEL=config-2")
132
133=== modified file 'cloudinit/sources/DataSourceNoCloud.py'
134--- cloudinit/sources/DataSourceNoCloud.py 2013-03-07 21:27:47 +0000
135+++ cloudinit/sources/DataSourceNoCloud.py 2013-03-26 22:14:53 +0000
136@@ -87,6 +87,9 @@
137
138 label = self.ds_cfg.get('fs_label', "cidata")
139 if label is not None:
140+ # Query optical drive to get it in blkid cache for 2.6 kernels
141+ util.find_devs_with(path="/dev/sr0")
142+
143 fslist = util.find_devs_with("TYPE=vfat")
144 fslist.extend(util.find_devs_with("TYPE=iso9660"))
145
146
147=== modified file 'cloudinit/util.py'
148--- cloudinit/util.py 2013-03-19 13:32:04 +0000
149+++ cloudinit/util.py 2013-03-26 22:14:53 +0000
150@@ -408,6 +408,7 @@
151 'release': platform.release(),
152 'python': platform.python_version(),
153 'uname': platform.uname(),
154+ 'dist': platform.linux_distribution(),
155 }
156
157
158
159=== modified file 'tests/unittests/test_datasource/test_configdrive.py'
160--- tests/unittests/test_datasource/test_configdrive.py 2013-01-17 00:46:30 +0000
161+++ tests/unittests/test_datasource/test_configdrive.py 2013-03-26 22:14:53 +0000
162@@ -259,8 +259,9 @@
163 def test_find_candidates(self):
164 devs_with_answers = {}
165
166- def my_devs_with(criteria):
167- return devs_with_answers[criteria]
168+ def my_devs_with(*args, **kwargs):
169+ criteria = args[0] if len(args) else kwargs.pop('criteria', None)
170+ return devs_with_answers.get(criteria, [])
171
172 def my_is_partition(dev):
173 return dev[-1] in "0123456789" and not dev.startswith("sr")