[cloud-init] Fix hostname persistence

gholms gholms at fedoraproject.org
Sun Sep 23 02:53:56 UTC 2012


commit dcf5001c0a92862f023c79cdc0039eaeaffaa40a
Author: Garrett Holmstrom <gholms at fedoraproject.org>
Date:   Sat Sep 22 17:47:59 2012 -0700

    Fix hostname persistence

 cloud-init-0.7.0-hostname-refactor.patch |  223 ++++++++++++++++++++++++++++++
 cloud-init.spec                          |    5 +
 2 files changed, 228 insertions(+), 0 deletions(-)
---
diff --git a/cloud-init-0.7.0-hostname-refactor.patch b/cloud-init-0.7.0-hostname-refactor.patch
new file mode 100644
index 0000000..f8789e1
--- /dev/null
+++ b/cloud-init-0.7.0-hostname-refactor.patch
@@ -0,0 +1,223 @@
+Index: trunk/cloudinit/distros/__init__.py
+===================================================================
+--- trunk.orig/cloudinit/distros/__init__.py
++++ trunk/cloudinit/distros/__init__.py
+@@ -48,6 +48,7 @@ class Distro(object):
+     __metaclass__ = abc.ABCMeta
+     default_user = None
+     default_user_groups = None
++    default_hostname_conf_file = '/etc/hostname'
+ 
+     def __init__(self, name, cfg, paths):
+         self._paths = paths
+@@ -95,14 +96,69 @@ class Distro(object):
+     def get_option(self, opt_name, default=None):
+         return self._cfg.get(opt_name, default)
+ 
+-    @abc.abstractmethod
+     def set_hostname(self, hostname):
++        conf_file = self.get_option('hostname_conf_file',
++                                    default=self.default_hostname_conf_file)
++        out_fn = self._paths.join(False, conf_file)
++        self._write_hostname(hostname, out_fn)
++        if out_fn == conf_file:
++            # We only do this if we are running in non-adjusted root mode
++            LOG.debug("Setting hostname to %s", hostname)
++            util.subp(['hostname', hostname])
++
++    def update_hostname(self, hostname, prev_hostname_fn):
++        conf_file = self.get_option('hostname_conf_file',
++                                    default=self.default_hostname_conf_file)
++        hostname_prev = self._read_hostname(prev_hostname_fn)
++        read_fn = self._paths.join(True, conf_file)
++        hostname_in_conf = self._read_hostname(read_fn)
++        update_files = []
++        if not hostname_prev or hostname_prev != hostname:
++            update_files.append(prev_hostname_fn)
++        if (not hostname_in_conf or
++            (hostname_in_conf == hostname_prev
++             and hostname_in_conf != hostname)):
++            write_fn = self._paths.join(False, conf_file)
++            update_files.append(write_fn)
++        for fn in update_files:
++            try:
++                self._write_hostname(hostname, fn)
++            except:
++                util.logexc(LOG, "Failed to write hostname %s to %s",
++                            hostname, fn)
++        if (hostname_in_conf and hostname_prev and
++            hostname_in_conf != hostname_prev):
++            LOG.debug(("Hostname in %s differs from that in %s; assuming "
++                       "hostname is user-maintained"), prev_hostname_fn, conf_file)
++        if conf_file in update_files:
++            # We only do this if we are running in non-adjusted root mode
++            LOG.debug("Setting hostname to %s", hostname)
++            util.subp(["hostname", hostname])
++
++    @abc.abstractmethod
++    def _write_hostname(self, hostname, filename):
+         raise NotImplementedError()
+ 
++    def _write_bare_hostname(self, hostname, out_fn):
++        # "" gives trailing newline.
++        util.write_file(out_fn, "%s\n" % str(hostname), 0644)
++
+     @abc.abstractmethod
+-    def update_hostname(self, hostname, prev_hostname_fn):
++    def _read_hostname(self, filename, default=None):
+         raise NotImplementedError()
+ 
++    def _read_bare_hostname(self, filename, default=None):
++        contents = util.load_file(filename, quiet=True)
++        for line in contents.splitlines():
++            c_pos = line.find("#")
++            # Handle inline comments
++            if c_pos != -1:
++                line = line[0:c_pos]
++            line_c = line.strip()
++            if line_c:
++                return line_c
++        return default
++
+     @abc.abstractmethod
+     def package_command(self, cmd, args=None):
+         raise NotImplementedError()
+Index: trunk/cloudinit/distros/debian.py
+===================================================================
+--- trunk.orig/cloudinit/distros/debian.py
++++ trunk/cloudinit/distros/debian.py
+@@ -57,56 +57,11 @@ class Distro(distros.Distro):
+         net_fn = self._paths.join(False, "/etc/network/interfaces")
+         util.write_file(net_fn, settings)
+ 
+-    def set_hostname(self, hostname):
+-        out_fn = self._paths.join(False, "/etc/hostname")
+-        self._write_hostname(hostname, out_fn)
+-        if out_fn == '/etc/hostname':
+-            # Only do this if we are running in non-adjusted root mode
+-            LOG.debug("Setting hostname to %s", hostname)
+-            util.subp(['hostname', hostname])
+-
+     def _write_hostname(self, hostname, out_fn):
+-        # "" gives trailing newline.
+-        util.write_file(out_fn, "%s\n" % str(hostname), 0644)
+-
+-    def update_hostname(self, hostname, prev_fn):
+-        hostname_prev = self._read_hostname(prev_fn)
+-        read_fn = self._paths.join(True, "/etc/hostname")
+-        hostname_in_etc = self._read_hostname(read_fn)
+-        update_files = []
+-        if not hostname_prev or hostname_prev != hostname:
+-            update_files.append(prev_fn)
+-        if (not hostname_in_etc or
+-            (hostname_in_etc == hostname_prev and
+-             hostname_in_etc != hostname)):
+-            write_fn = self._paths.join(False, "/etc/hostname")
+-            update_files.append(write_fn)
+-        for fn in update_files:
+-            try:
+-                self._write_hostname(hostname, fn)
+-            except:
+-                util.logexc(LOG, "Failed to write hostname %s to %s",
+-                            hostname, fn)
+-        if (hostname_in_etc and hostname_prev and
+-            hostname_in_etc != hostname_prev):
+-            LOG.debug(("%s differs from /etc/hostname."
+-                        " Assuming user maintained hostname."), prev_fn)
+-        if "/etc/hostname" in update_files:
+-            # Only do this if we are running in non-adjusted root mode
+-            LOG.debug("Setting hostname to %s", hostname)
+-            util.subp(['hostname', hostname])
++        return self._write_bare_hostname(hostname, out_fn)
+ 
+     def _read_hostname(self, filename, default=None):
+-        contents = util.load_file(filename, quiet=True)
+-        for line in contents.splitlines():
+-            c_pos = line.find("#")
+-            # Handle inline comments
+-            if c_pos != -1:
+-                line = line[0:c_pos]
+-            line_c = line.strip()
+-            if line_c:
+-                return line_c
+-        return default
++        return self._read_bare_hostname(filename, default=default)
+ 
+     def _get_localhost_ip(self):
+         # Note: http://www.leonardoborda.com/blog/127-0-1-1-ubuntu-debian/
+Index: trunk/cloudinit/distros/fedora.py
+===================================================================
+--- trunk.orig/cloudinit/distros/fedora.py
++++ trunk/cloudinit/distros/fedora.py
+@@ -30,3 +30,10 @@ LOG = logging.getLogger(__name__)
+ class Distro(rhel.Distro):
+     distro_name  = 'fedora'
+     default_user = 'ec2-user'
++    default_hostname_conf_file = '/etc/hostname'
++
++    def _write_hostname(self, hostname, out_fn):
++        return self._write_bare_hostname(hostname, out_fn)
++
++    def _read_hostname(self, filename, default=None):
++        return self._read_bare_hostname(filename, default=default)
+Index: trunk/cloudinit/distros/rhel.py
+===================================================================
+--- trunk.orig/cloudinit/distros/rhel.py
++++ trunk/cloudinit/distros/rhel.py
+@@ -57,6 +57,7 @@ D_QUOTE_CHARS = {
+ 
+ 
+ class Distro(distros.Distro):
++    default_hostname_conf_file = '/etc/sysconfig/network'
+ 
+     def __init__(self, name, cfg, paths):
+         distros.Distro.__init__(self, name, cfg, paths)
+@@ -128,14 +129,6 @@ class Distro(distros.Distro):
+         if nameservers or searchservers:
+             self._write_resolve(nameservers, searchservers)
+ 
+-    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])
+-
+     def apply_locale(self, locale, out_fn=None):
+         if not out_fn:
+             out_fn = self._paths.join(False, '/etc/sysconfig/i18n')
+@@ -151,33 +144,6 @@ class Distro(distros.Distro):
+         w_contents = "\n".join(contents.write())
+         util.write_file(out_fn, w_contents, 0644)
+ 
+-    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)
+-        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)
+-        for fn in update_files:
+-            try:
+-                self._write_hostname(hostname, fn)
+-            except:
+-                util.logexc(LOG, "Failed to write hostname %s to %s",
+-                            hostname, fn)
+-        if (hostname_in_sys and hostname_prev and
+-            hostname_in_sys != hostname_prev):
+-            LOG.debug(("%s differs from /etc/sysconfig/network."
+-                        " Assuming user maintained hostname."), prev_file)
+-        if "/etc/sysconfig/network" in update_files:
+-            # Only do this if we are running in non-adjusted root mode
+-            LOG.debug("Setting hostname to %s", hostname)
+-            util.subp(['hostname', hostname])
+-
+     def _read_hostname(self, filename, default=None):
+         (_exists, contents) = self._read_conf(filename)
+         if 'HOSTNAME' in contents:
diff --git a/cloud-init.spec b/cloud-init.spec
index 688710e..b7db61a 100644
--- a/cloud-init.spec
+++ b/cloud-init.spec
@@ -13,6 +13,9 @@ Source0:        %{name}-%{version}-bzr659.tar.gz
 Source1:        cloud-init-fedora.cfg
 Source2:        cloud-init-README.fedora
 Patch0:         cloud-init-0.7.0-fedora.patch
+# Make Fedora use the same hostname-updating code as Debian (/etc/hostname)
+# https://code.launchpad.net/~gholms/cloud-init/hostname-refactor/+merge/125869
+Patch1:         cloud-init-0.7.0-hostname-refactor.patch
 
 BuildArch:      noarch
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -48,6 +51,7 @@ ssh keys and to let the user run various scripts.
 %prep
 %setup -q -n %{name}-%{version}-bzr659
 %patch0 -p1
+%patch1 -p1
 
 cp -p %{SOURCE2} README.fedora
 
@@ -127,6 +131,7 @@ fi
 %changelog
 * Sat Sep 22 2012 Garrett Holmstrom <gholms at fedoraproject.org> - 0.7.0-0.2.bzr659
 - Rebased against upstream rev 659
+- Fixed hostname persistence
 
 * Mon Sep 17 2012 Garrett Holmstrom <gholms at fedoraproject.org> - 0.7.0-0.1.bzr650
 - Rebased against upstream rev 650


More information about the scm-commits mailing list