summaryrefslogtreecommitdiff
path: root/cloudinit/distros/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/distros/__init__.py')
-rw-r--r--cloudinit/distros/__init__.py89
1 files changed, 68 insertions, 21 deletions
diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py
index a5d41bdb..07f03159 100644
--- a/cloudinit/distros/__init__.py
+++ b/cloudinit/distros/__init__.py
@@ -33,7 +33,7 @@ from cloudinit import log as logging
from cloudinit import ssh_util
from cloudinit import util
-from cloudinit.distros import helpers
+from cloudinit.distros.parsers import hosts
LOG = logging.getLogger(__name__)
@@ -43,6 +43,8 @@ class Distro(object):
__metaclass__ = abc.ABCMeta
default_user = None
default_user_groups = None
+ hosts_fn = "/etc/hosts"
+ ci_sudoers_fn = "/etc/sudoers.d/90-cloud-init-users"
def __init__(self, name, cfg, paths):
self._paths = paths
@@ -67,10 +69,6 @@ class Distro(object):
raise NotImplementedError()
@abc.abstractmethod
- def update_hostname(self, hostname, prev_hostname_fn):
- raise NotImplementedError()
-
- @abc.abstractmethod
def package_command(self, cmd, args=None):
raise NotImplementedError()
@@ -117,14 +115,62 @@ class Distro(object):
def _get_localhost_ip(self):
return "127.0.0.1"
+ @abc.abstractmethod
+ def _read_hostname(self, filename, default=None):
+ raise NotImplementedError()
+
+ @abc.abstractmethod
+ def _write_hostname(self, hostname, filename):
+ raise NotImplementedError()
+
+ @abc.abstractmethod
+ def _read_system_hostname(self):
+ raise NotImplementedError()
+
+ def _apply_hostname(self, hostname):
+ LOG.debug("Setting system hostname to %s", hostname)
+ util.subp(['hostname', hostname])
+
+ def update_hostname(self, hostname, prev_hostname_fn):
+ if not hostname:
+ return
+
+ prev_hostname = self._read_hostname(prev_hostname_fn)
+ (sys_fn, sys_hostname) = self._read_system_hostname()
+ update_files = []
+ if not prev_hostname or prev_hostname != hostname:
+ update_files.append(prev_hostname_fn)
+
+ if (not sys_hostname) or (sys_hostname == prev_hostname
+ and sys_hostname != hostname):
+ update_files.append(sys_fn)
+
+ update_files = set([f for f in update_files if f])
+ LOG.debug("Attempting to update hostname to %s in %s files",
+ hostname, len(update_files))
+
+ for fn in update_files:
+ try:
+ self._write_hostname(hostname, fn)
+ except IOError:
+ util.logexc(LOG, "Failed to write hostname %s to %s",
+ hostname, fn)
+
+ if (sys_hostname and prev_hostname and
+ sys_hostname != prev_hostname):
+ LOG.debug("%s differs from %s, assuming user maintained hostname.",
+ prev_hostname_fn, sys_fn)
+
+ if sys_fn in update_files:
+ self._apply_hostname(hostname)
+
def update_etc_hosts(self, hostname, fqdn):
header = ''
- if os.path.exists('/etc/hosts'):
- eh = helpers.HostsConf(util.load_file("/etc/hosts"))
+ if os.path.exists(self.hosts_fn):
+ eh = hosts.HostsConf(util.load_file(self.hosts_fn))
else:
- eh = helpers.HostsConf('')
- header = "# Added by cloud-init"
- header = "%s on %s" % (header, util.time_rfc2822())
+ eh = hosts.HostsConf('')
+ header = util.make_header(base="added")
local_ip = self._get_localhost_ip()
prev_info = eh.get_entry(local_ip)
need_change = False
@@ -154,7 +200,7 @@ class Distro(object):
if header:
contents.write("%s\n" % (header))
contents.write("%s\n" % (eh))
- util.write_file("/etc/hosts", contents.getvalue(), mode=0644)
+ util.write_file(self.hosts_fn, contents.getvalue(), mode=0644)
def _bring_up_interface(self, device_name):
cmd = ['ifup', device_name]
@@ -302,30 +348,31 @@ class Distro(object):
return True
- def write_sudo_rules(self,
- user,
- rules,
- sudo_file="/etc/sudoers.d/90-cloud-init-users",
- ):
+ def write_sudo_rules(self, user, rules, sudo_file=None):
+ if not sudo_file:
+ sudo_file = self.ci_sudoers_fn
- content_header = "# user rules for %s" % user
+ content_header = "# User rules for %s" % user
content = "%s\n%s %s\n\n" % (content_header, user, rules)
- if isinstance(rules, list):
+ if isinstance(rules, (list, tuple, set)):
content = "%s\n" % content_header
for rule in rules:
content += "%s %s\n" % (user, rule)
content += "\n"
if not os.path.exists(sudo_file):
- util.write_file(sudo_file, content, 0440)
-
+ contents = [
+ util.make_header(),
+ content,
+ ]
+ util.write_file(sudo_file, "\n".join(contents), 0440)
else:
try:
with open(sudo_file, 'a') as f:
f.write(content)
except IOError as e:
- util.logexc(LOG, "Failed to write %s" % sudo_file, e)
+ util.logexc(LOG, "Failed to write sudoers file %s", sudo_file)
raise e
def create_group(self, name, members):