From 6208fe41e4e73d1f14fd4afc152565c8908684a2 Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Wed, 19 Sep 2012 18:40:20 -0700 Subject: Fix the ifup so that if a list of devices is provided then each interface is brought up individually instead of using the '--all' which isn't on rhel. The default debian behavior will be to use this still though as it overrides the new bring up interfaces function for this case. --- cloudinit/distros/__init__.py | 29 +++++++++++++++-------------- cloudinit/distros/debian.py | 6 ++++++ cloudinit/distros/fedora.py | 1 - cloudinit/distros/rhel.py | 2 ++ cloudinit/distros/ubuntu.py | 1 - 5 files changed, 23 insertions(+), 16 deletions(-) (limited to 'cloudinit/distros') diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py index 3e9d934d..442e75b4 100644 --- a/cloudinit/distros/__init__.py +++ b/cloudinit/distros/__init__.py @@ -34,12 +34,6 @@ from cloudinit import log as logging from cloudinit import ssh_util from cloudinit import util -# TODO(harlowja): Make this via config?? -IFACE_ACTIONS = { - 'up': ['ifup', '--all'], - 'down': ['ifdown', '--all'], -} - LOG = logging.getLogger(__name__) @@ -134,10 +128,10 @@ class Distro(object): def apply_network(self, settings, bring_up=True): # Write it out - self._write_network(settings) + dev_names = self._write_network(settings) # Now try to bring them up if bring_up: - return self._interface_action('up') + return self._bring_up_interfaces(dev_names) return False @abc.abstractmethod @@ -189,13 +183,11 @@ class Distro(object): util.write_file(self._paths.join(False, "/etc/hosts"), contents, mode=0644) - def _interface_action(self, action): - if action not in IFACE_ACTIONS: - raise NotImplementedError("Unknown interface action %s" % (action)) - cmd = IFACE_ACTIONS[action] + def _bring_up_interface(self, device_name): + cmd = ['ifup', device_name] + LOG.debug("Attempting to run bring up interface %s using command %s", + device_name, cmd) try: - LOG.debug("Attempting to run %s interface action using command %s", - action, cmd) (_out, err) = util.subp(cmd) if len(err): LOG.warn("Running %s resulted in stderr output: %s", cmd, err) @@ -204,6 +196,15 @@ class Distro(object): util.logexc(LOG, "Running interface command %s failed", cmd) return False + def _bring_up_interfaces(self, device_names): + am_failed = 0 + for d in device_names: + if not self._bring_up_interface(d): + am_failed += 1 + if am_failed == 0: + return True + return False + def isuser(self, name): try: if pwd.getpwnam(name): diff --git a/cloudinit/distros/debian.py b/cloudinit/distros/debian.py index 5b4aa9f8..777c8530 100644 --- a/cloudinit/distros/debian.py +++ b/cloudinit/distros/debian.py @@ -56,6 +56,12 @@ class Distro(distros.Distro): def _write_network(self, settings): net_fn = self._paths.join(False, "/etc/network/interfaces") util.write_file(net_fn, settings) + return [] + + def _bring_up_interfaces(self, device_names): + if not device_names: + device_names = ['--all'] + return distros.Distro._bring_up_interfaces(self, device_names) def set_hostname(self, hostname): out_fn = self._paths.join(False, "/etc/hostname") diff --git a/cloudinit/distros/fedora.py b/cloudinit/distros/fedora.py index 9f76a116..f65a820d 100644 --- a/cloudinit/distros/fedora.py +++ b/cloudinit/distros/fedora.py @@ -28,5 +28,4 @@ LOG = logging.getLogger(__name__) class Distro(rhel.Distro): - distro_name = 'fedora' default_user = 'ec2-user' diff --git a/cloudinit/distros/rhel.py b/cloudinit/distros/rhel.py index ec4dc2cc..0e451b02 100644 --- a/cloudinit/distros/rhel.py +++ b/cloudinit/distros/rhel.py @@ -88,6 +88,7 @@ class Distro(distros.Distro): # Make the intermediate format as the rhel format... nameservers = [] searchservers = [] + dev_names = entries.keys() for (dev, info) in entries.iteritems(): net_fn = NETWORK_FN_TPL % (dev) net_ro_fn = self._paths.join(True, net_fn) @@ -127,6 +128,7 @@ class Distro(distros.Distro): util.write_file(net_rw_fn, w_contents, 0644) if nameservers or searchservers: self._write_resolve(nameservers, searchservers) + return dev_names def set_hostname(self, hostname): out_fn = self._paths.join(False, '/etc/sysconfig/network') diff --git a/cloudinit/distros/ubuntu.py b/cloudinit/distros/ubuntu.py index 22f8c2c5..4e697f82 100644 --- a/cloudinit/distros/ubuntu.py +++ b/cloudinit/distros/ubuntu.py @@ -29,7 +29,6 @@ LOG = logging.getLogger(__name__) class Distro(debian.Distro): - distro_name = 'ubuntu' default_user = 'ubuntu' default_user_groups = ("adm,audio,cdrom,dialout,floppy,video," "plugdev,dip,netdev,sudo") -- cgit v1.2.3 From 355b0e372aec58360d4fb728088edefec27f86a1 Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Wed, 19 Sep 2012 20:57:30 -0700 Subject: Rework the rhel sysconfig writing/updating so that it goes through a single function which helps ensure correctness. Also write to /etc/sysconfig/network when we have written out devices to ensure that networking is on. --- cloudinit/distros/rhel.py | 123 ++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 59 deletions(-) (limited to 'cloudinit/distros') diff --git a/cloudinit/distros/rhel.py b/cloudinit/distros/rhel.py index ec4dc2cc..c00627c6 100644 --- a/cloudinit/distros/rhel.py +++ b/cloudinit/distros/rhel.py @@ -26,6 +26,7 @@ from cloudinit import distros from cloudinit import helpers from cloudinit import log as logging from cloudinit import util +from cloudinit import version from cloudinit.settings import PER_INSTANCE @@ -55,6 +56,12 @@ D_QUOTE_CHARS = { '`': '\`', } +def _make_sysconfig_bool(val): + if val: + return 'yes' + else: + return 'no' + class Distro(distros.Distro): @@ -76,9 +83,8 @@ class Distro(distros.Distro): if search_servers: contents.append("search %s" % (" ".join(search_servers))) if contents: - resolve_rw_fn = self._paths.join(False, "/etc/resolv.conf") contents.insert(0, '# Created by cloud-init') - util.write_file(resolve_rw_fn, "\n".join(contents), 0644) + util.write_file("/etc/resolv.conf", "\n".join(contents), 0644) def _write_network(self, settings): # TODO(harlowja) fix this... since this is the ubuntu format @@ -88,81 +94,82 @@ class Distro(distros.Distro): # Make the intermediate format as the rhel format... nameservers = [] searchservers = [] + dev_names = entries.keys() for (dev, info) in entries.iteritems(): net_fn = NETWORK_FN_TPL % (dev) - net_ro_fn = self._paths.join(True, net_fn) - (prev_exist, net_cfg) = self._read_conf(net_ro_fn) - net_cfg['DEVICE'] = dev - boot_proto = info.get('bootproto') - if boot_proto: - net_cfg['BOOTPROTO'] = boot_proto - net_mask = info.get('netmask') - if net_mask: - net_cfg["NETMASK"] = net_mask - addr = info.get('address') - if addr: - net_cfg["IPADDR"] = addr - if info.get('auto'): - net_cfg['ONBOOT'] = 'yes' - else: - net_cfg['ONBOOT'] = 'no' - gtway = info.get('gateway') - if gtway: - net_cfg["GATEWAY"] = gtway - bcast = info.get('broadcast') - if bcast: - net_cfg["BROADCAST"] = bcast - mac_addr = info.get('hwaddress') - if mac_addr: - net_cfg["MACADDR"] = mac_addr - lines = net_cfg.write() + net_cfg = { + 'DEVICE': dev, + 'NETMASK': info.get('netmask'), + 'IPADDR': info.get('address'), + 'BOOTPROTO': info.get('bootproto'), + 'GATEWAY': info.get('gateway'), + 'BROADCAST': info.get('broadcast'), + 'MACADDR': info.get('hwaddress'), + 'ONBOOT': _make_sysconfig_bool(info.get('auto')), + } + self._update_sysconfig_file(net_fn, net_cfg) if 'dns-nameservers' in info: nameservers.extend(info['dns-nameservers']) if 'dns-search' in info: searchservers.extend(info['dns-search']) - if not prev_exist: - lines.insert(0, '# Created by cloud-init') - w_contents = "\n".join(lines) - net_rw_fn = self._paths.join(False, net_fn) - util.write_file(net_rw_fn, w_contents, 0644) if nameservers or searchservers: self._write_resolve(nameservers, searchservers) + if dev_names: + net_cfg = { + 'NETWORKING': _make_sysconfig_bool(True), + } + self._update_sysconfig_file("/etc/sysconfig/network", net_cfg) + return dev_names + + def _update_sysconfig_file(self, fn, adjustments, allow_empty=False): + if not adjustments: + return + (exists, contents) = self._read_conf(fn) + updated_am = 0 + for (k, v) in adjustments.items(): + if v is None: + continue + v = str(v) + if len(v) == 0 and not allow_empty: + continue + contents[k] = v + updated_am += 1 + if updated_am: + lines = contents.write() + if not exists: + ci_ver = version.version_string() + lines.insert(0, '# Created by cloud-init v. %s' % (ci_ver)) + util.write_file(fn, "\n".join(lines), 0644) def set_hostname(self, hostname): - out_fn = self._paths.join(False, '/etc/sysconfig/network') - self._write_hostname(hostname, out_fn) - if out_fn == '/etc/sysconfig/network': - # Only do this if we are running in non-adjusted root mode - LOG.debug("Setting hostname to %s", hostname) - util.subp(['hostname', hostname]) + self._write_hostname(hostname, '/etc/sysconfig/network') + LOG.debug("Setting hostname to %s", hostname) + util.subp(['hostname', hostname]) def apply_locale(self, locale, out_fn=None): if not out_fn: - out_fn = self._paths.join(False, '/etc/sysconfig/i18n') - ro_fn = self._paths.join(True, '/etc/sysconfig/i18n') - (_exists, contents) = self._read_conf(ro_fn) - contents['LANG'] = locale - w_contents = "\n".join(contents.write()) - util.write_file(out_fn, w_contents, 0644) + out_fn = '/etc/sysconfig/i18n' + locale_cfg = { + 'LANG': locale, + } + self._update_sysconfig_file(out_fn, locale_cfg) def _write_hostname(self, hostname, out_fn): - (_exists, contents) = self._read_conf(out_fn) - contents['HOSTNAME'] = hostname - w_contents = "\n".join(contents.write()) - util.write_file(out_fn, w_contents, 0644) + host_cfg = { + 'HOSTNAME': hostname, + } + self._update_sysconfig_file(out_fn, host_cfg) def update_hostname(self, hostname, prev_file): hostname_prev = self._read_hostname(prev_file) - read_fn = self._paths.join(True, "/etc/sysconfig/network") - hostname_in_sys = self._read_hostname(read_fn) + hostname_in_sys = self._read_hostname("/etc/sysconfig/network") update_files = [] if not hostname_prev or hostname_prev != hostname: update_files.append(prev_file) if (not hostname_in_sys or (hostname_in_sys == hostname_prev and hostname_in_sys != hostname)): - write_fn = self._paths.join(False, "/etc/sysconfig/network") - update_files.append(write_fn) + update_files.append("/etc/sysconfig/network") for fn in update_files: try: self._write_hostname(hostname, fn) @@ -200,12 +207,10 @@ class Distro(distros.Distro): raise RuntimeError(("Invalid timezone %s," " no file found at %s") % (tz, tz_file)) # Adjust the sysconfig clock zone setting - read_fn = self._paths.join(True, "/etc/sysconfig/clock") - (_exists, contents) = self._read_conf(read_fn) - contents['ZONE'] = tz - tz_contents = "\n".join(contents.write()) - write_fn = self._paths.join(False, "/etc/sysconfig/clock") - util.write_file(write_fn, tz_contents) + clock_cfg = { + 'ZONE': tz, + } + self._update_sysconfig_file("/etc/sysconfig/clock", clock_cfg) # This ensures that the correct tz will be used for the system util.copy(tz_file, self._paths.join(False, "/etc/localtime")) -- cgit v1.2.3 From f59369d1bb0eac874dcd2fa91abfad9186b22810 Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Wed, 19 Sep 2012 21:13:48 -0700 Subject: Use a common header creation function to avoid duplicating the same code in this file. --- cloudinit/distros/rhel.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'cloudinit/distros') diff --git a/cloudinit/distros/rhel.py b/cloudinit/distros/rhel.py index c00627c6..1ea7952b 100644 --- a/cloudinit/distros/rhel.py +++ b/cloudinit/distros/rhel.py @@ -63,6 +63,11 @@ def _make_sysconfig_bool(val): return 'no' +def _make_header(): + ci_ver = version.version_string() + return '# Created by cloud-init v. %s' % (ci_ver) + + class Distro(distros.Distro): def __init__(self, name, cfg, paths): @@ -83,7 +88,7 @@ class Distro(distros.Distro): if search_servers: contents.append("search %s" % (" ".join(search_servers))) if contents: - contents.insert(0, '# Created by cloud-init') + contents.insert(0, _make_header()) util.write_file("/etc/resolv.conf", "\n".join(contents), 0644) def _write_network(self, settings): @@ -137,8 +142,7 @@ class Distro(distros.Distro): if updated_am: lines = contents.write() if not exists: - ci_ver = version.version_string() - lines.insert(0, '# Created by cloud-init v. %s' % (ci_ver)) + lines.insert(0, _make_header()) util.write_file(fn, "\n".join(lines), 0644) def set_hostname(self, hostname): @@ -212,7 +216,7 @@ class Distro(distros.Distro): } self._update_sysconfig_file("/etc/sysconfig/clock", clock_cfg) # This ensures that the correct tz will be used for the system - util.copy(tz_file, self._paths.join(False, "/etc/localtime")) + util.copy(tz_file, "/etc/localtime") def package_command(self, command, args=None): cmd = ['yum'] -- cgit v1.2.3 From e055c795581c2846aa6ae128de8cfd0b2c5d3f32 Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Thu, 20 Sep 2012 15:55:52 -0700 Subject: Instead of special casing the empty list we are going to check for the 'all' entry and if that exists then only fire off one call (since debian supports this). --- cloudinit/distros/debian.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'cloudinit/distros') diff --git a/cloudinit/distros/debian.py b/cloudinit/distros/debian.py index 777c8530..88f4e978 100644 --- a/cloudinit/distros/debian.py +++ b/cloudinit/distros/debian.py @@ -56,12 +56,17 @@ class Distro(distros.Distro): def _write_network(self, settings): net_fn = self._paths.join(False, "/etc/network/interfaces") util.write_file(net_fn, settings) - return [] + return ['all'] def _bring_up_interfaces(self, device_names): - if not device_names: - device_names = ['--all'] - return distros.Distro._bring_up_interfaces(self, device_names) + use_all = False + for d in device_names: + if d == 'all': + use_all = True + if use_all: + return distros.Distro._bring_up_interface(self, '--all') + else: + return distros.Distro._bring_up_interfaces(self, device_names) def set_hostname(self, hostname): out_fn = self._paths.join(False, "/etc/hostname") -- cgit v1.2.3 From d852495da6ae8eefee0ff7d2de14c398c0a87a51 Mon Sep 17 00:00:00 2001 From: Garrett Holmstrom Date: Sat, 22 Sep 2012 19:35:07 -0700 Subject: Use 0440 permissions on sudoers, not 0644 --- cloudinit/distros/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cloudinit/distros') diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py index 3e9d934d..612d44af 100644 --- a/cloudinit/distros/__init__.py +++ b/cloudinit/distros/__init__.py @@ -339,7 +339,7 @@ class Distro(object): content += "\n" if not os.path.exists(sudo_file): - util.write_file(sudo_file, content, 0644) + util.write_file(sudo_file, content, 0440) else: try: -- cgit v1.2.3 From cde52cc8449d82d5bdce2fbb73516bee144e293c Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Mon, 24 Sep 2012 16:54:51 -0400 Subject: fix make pep8 --- cloudinit/distros/fedora.py | 2 +- cloudinit/patcher.py | 1 + cloudinit/sources/__init__.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'cloudinit/distros') diff --git a/cloudinit/distros/fedora.py b/cloudinit/distros/fedora.py index 9f76a116..e7092dd8 100644 --- a/cloudinit/distros/fedora.py +++ b/cloudinit/distros/fedora.py @@ -28,5 +28,5 @@ LOG = logging.getLogger(__name__) class Distro(rhel.Distro): - distro_name = 'fedora' + distro_name = 'fedora' default_user = 'ec2-user' diff --git a/cloudinit/patcher.py b/cloudinit/patcher.py index 8921a79a..fa140f04 100644 --- a/cloudinit/patcher.py +++ b/cloudinit/patcher.py @@ -39,6 +39,7 @@ def _patch_logging(): # sys.stderr using a fallback logger fallback_handler = QuietStreamHandler(sys.stderr) fallback_handler.setFormatter(logging.Formatter(FALL_FORMAT)) + def handleError(self, record): try: fallback_handler.handle(record) diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py index 6f126091..04083d0c 100644 --- a/cloudinit/sources/__init__.py +++ b/cloudinit/sources/__init__.py @@ -173,7 +173,7 @@ class DataSource(object): # make up a hostname (LP: #475354) in format ip-xx.xx.xx.xx lhost = self.metadata['local-hostname'] if util.is_ipv4(lhost): - toks = [ "ip-%s" % lhost.replace(".", "-") ] + toks = ["ip-%s" % lhost.replace(".", "-")] else: toks = lhost.split(".") -- cgit v1.2.3 From c780ad5898f54741037ad66c28c3423aa0495fba Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Mon, 24 Sep 2012 17:56:42 -0700 Subject: Oopies, missed u. --- cloudinit/distros/rhel.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'cloudinit/distros') diff --git a/cloudinit/distros/rhel.py b/cloudinit/distros/rhel.py index 67d80bf4..1ea7952b 100644 --- a/cloudinit/distros/rhel.py +++ b/cloudinit/distros/rhel.py @@ -144,8 +144,6 @@ class Distro(distros.Distro): if not exists: lines.insert(0, _make_header()) util.write_file(fn, "\n".join(lines), 0644) -======= ->>>>>>> MERGE-SOURCE def set_hostname(self, hostname): self._write_hostname(hostname, '/etc/sysconfig/network') -- cgit v1.2.3 From 58be2ec4a3a3213700905f6bd3e6752775369471 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Mon, 24 Sep 2012 20:58:05 -0400 Subject: fix pep8 --- cloudinit/distros/rhel.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'cloudinit/distros') diff --git a/cloudinit/distros/rhel.py b/cloudinit/distros/rhel.py index 1ea7952b..1a47fc33 100644 --- a/cloudinit/distros/rhel.py +++ b/cloudinit/distros/rhel.py @@ -1,4 +1,4 @@ -# vi: ts=4 expandtab + # vi: ts=4 expandtab # # Copyright (C) 2012 Canonical Ltd. # Copyright (C) 2012 Hewlett-Packard Development Company, L.P. @@ -56,6 +56,7 @@ D_QUOTE_CHARS = { '`': '\`', } + def _make_sysconfig_bool(val): if val: return 'yes' @@ -160,7 +161,7 @@ class Distro(distros.Distro): def _write_hostname(self, hostname, out_fn): host_cfg = { - 'HOSTNAME': hostname, + 'HOSTNAME': hostname, } self._update_sysconfig_file(out_fn, host_cfg) -- cgit v1.2.3