summaryrefslogtreecommitdiff
path: root/cloudinit/distros
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/distros')
-rw-r--r--cloudinit/distros/__init__.py18
-rw-r--r--cloudinit/distros/arch.py2
-rw-r--r--cloudinit/distros/debian.py2
-rw-r--r--cloudinit/distros/freebsd.py81
-rw-r--r--cloudinit/distros/gentoo.py2
-rw-r--r--cloudinit/distros/rhel.py12
6 files changed, 88 insertions, 29 deletions
diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py
index 9c9211fe..83c2eebf 100644
--- a/cloudinit/distros/__init__.py
+++ b/cloudinit/distros/__init__.py
@@ -387,8 +387,20 @@ class Distro(object):
# Import SSH keys
if 'ssh_authorized_keys' in kwargs:
- keys = set(kwargs['ssh_authorized_keys']) or []
- ssh_util.setup_user_keys(keys, name, options=None)
+ # Try to handle this in a smart manner.
+ keys = kwargs['ssh_authorized_keys']
+ if isinstance(keys, (basestring, str)):
+ keys = [keys]
+ if isinstance(keys, dict):
+ keys = list(keys.values())
+ if keys is not None:
+ if not isinstance(keys, (tuple, list, set)):
+ LOG.warn("Invalid type '%s' detected for"
+ " 'ssh_authorized_keys', expected list,"
+ " string, dict, or set.", type(keys))
+ else:
+ keys = set(keys) or []
+ ssh_util.setup_user_keys(keys, name, options=None)
return True
@@ -861,5 +873,5 @@ def set_etc_timezone(tz, tz_file=None, tz_conf="/etc/timezone",
util.write_file(tz_conf, str(tz).rstrip() + "\n")
# This ensures that the correct tz will be used for the system
if tz_local and tz_file:
- util.copy(tz_file, self.tz_local_fn)
+ util.copy(tz_file, tz_local)
return
diff --git a/cloudinit/distros/arch.py b/cloudinit/distros/arch.py
index 9f11b89c..005a0dd4 100644
--- a/cloudinit/distros/arch.py
+++ b/cloudinit/distros/arch.py
@@ -159,7 +159,7 @@ class Distro(distros.Distro):
return hostname
def set_timezone(self, tz):
- set_etc_timezone(tz=tz, tz_file=self._find_tz_file(tz))
+ distros.set_etc_timezone(tz=tz, tz_file=self._find_tz_file(tz))
def package_command(self, command, args=None, pkgs=None):
if pkgs is None:
diff --git a/cloudinit/distros/debian.py b/cloudinit/distros/debian.py
index 7cf4a9ef..010be67d 100644
--- a/cloudinit/distros/debian.py
+++ b/cloudinit/distros/debian.py
@@ -131,7 +131,7 @@ class Distro(distros.Distro):
return "127.0.1.1"
def set_timezone(self, tz):
- set_etc_timezone(tz=tz, tz_file=self._find_tz_file(tz))
+ distros.set_etc_timezone(tz=tz, tz_file=self._find_tz_file(tz))
def package_command(self, command, args=None, pkgs=None):
if pkgs is None:
diff --git a/cloudinit/distros/freebsd.py b/cloudinit/distros/freebsd.py
index 849834eb..ee23fd20 100644
--- a/cloudinit/distros/freebsd.py
+++ b/cloudinit/distros/freebsd.py
@@ -106,6 +106,35 @@ class Distro(distros.Distro):
val = None
return val
+ # NOVA will inject something like eth0, rewrite that to use the FreeBSD
+ # adapter. Since this adapter is based on the used driver, we need to
+ # figure out which interfaces are available. On KVM platforms this is
+ # vtnet0, where Xen would use xn0.
+ def getnetifname(self, dev):
+ LOG.debug("Translating network interface %s", dev)
+ if dev.startswith('lo'):
+ return dev
+
+ n = re.search('\d+$', dev)
+ index = n.group(0)
+
+ (out, err) = util.subp(['ifconfig', '-a'])
+ ifconfigoutput = [x for x in (out.strip()).splitlines() if len(x.split()) > 0]
+ for line in ifconfigoutput:
+ m = re.match('^\w+', line)
+ if m:
+ if m.group(0).startswith('lo'):
+ continue
+ # Just settle with the first non-lo adapter we find, since it's
+ # rather unlikely there will be multiple nicdrivers involved.
+ bsddev = m.group(0)
+ break
+
+ # Replace the index with the one we're after.
+ bsddev = re.sub('\d+$', index, bsddev)
+ LOG.debug("Using network interface %s", bsddev)
+ return bsddev
+
def _read_system_hostname(self):
sys_hostname = self._read_hostname(filename=None)
return ('rc.conf', sys_hostname)
@@ -162,18 +191,18 @@ class Distro(distros.Distro):
log_adduser_cmd = ['pw', 'useradd', '-n', name]
adduser_opts = {
- "homedir": '-d',
- "gecos": '-c',
- "primary_group": '-g',
- "groups": '-G',
- "passwd": '-h',
- "shell": '-s',
- "inactive": '-E',
+ "homedir": '-d',
+ "gecos": '-c',
+ "primary_group": '-g',
+ "groups": '-G',
+ "passwd": '-h',
+ "shell": '-s',
+ "inactive": '-E',
}
adduser_flags = {
- "no_user_group": '--no-user-group',
- "system": '--system',
- "no_log_init": '--no-log-init',
+ "no_user_group": '--no-user-group',
+ "system": '--system',
+ "no_log_init": '--no-log-init',
}
redact_opts = ['passwd']
@@ -246,17 +275,21 @@ class Distro(distros.Distro):
nameservers = []
searchdomains = []
dev_names = entries.keys()
- for (dev, info) in entries.iteritems():
+ for (device, info) in entries.iteritems():
# Skip the loopback interface.
- if dev.startswith('lo'):
+ if device.startswith('lo'):
continue
+ dev = self.getnetifname(device)
+
LOG.info('Configuring interface %s', dev)
if info.get('bootproto') == 'static':
- LOG.debug('Configuring dev %s with %s / %s', dev, info.get('address'), info.get('netmask'))
+ LOG.debug('Configuring dev %s with %s / %s', dev,
+ info.get('address'), info.get('netmask'))
# Configure an ipv4 address.
- ifconfig = info.get('address') + ' netmask ' + info.get('netmask')
+ ifconfig = (info.get('address') + ' netmask ' +
+ info.get('netmask'))
# Configure the gateway.
self.updatercconf('defaultrouter', info.get('gateway'))
@@ -264,10 +297,10 @@ class Distro(distros.Distro):
if 'dns-nameservers' in info:
nameservers.extend(info['dns-nameservers'])
if 'dns-search' in info:
- searchservers.extend(info['dns-search'])
+ searchdomains.extend(info['dns-search'])
else:
ifconfig = 'DHCP'
-
+
self.updatercconf('ifconfig_' + dev, ifconfig)
# Try to read the /etc/resolv.conf or just start from scratch if that
@@ -276,7 +309,8 @@ class Distro(distros.Distro):
resolvconf = ResolvConf(util.load_file(self.resolv_conf_fn))
resolvconf.parse()
except IOError:
- util.logexc(LOG, "Failed to parse %s, use new empty file", self.resolv_conf_fn)
+ util.logexc(LOG, "Failed to parse %s, use new empty file",
+ self.resolv_conf_fn)
resolvconf = ResolvConf('')
resolvconf.parse()
@@ -323,6 +357,19 @@ class Distro(distros.Distro):
util.logexc(LOG, "Failed to restore %s backup",
self.login_conf_fn)
+ def _bring_up_interface(self, device_name):
+ if device_name.startswith('lo'):
+ return
+ dev = self.getnetifname(device_name)
+ cmd = ['/etc/rc.d/netif', 'start', dev]
+ LOG.debug("Attempting to bring up interface %s using command %s",
+ dev, cmd)
+ # This could return 1 when the interface has already been put UP by the
+ # OS. This is just fine.
+ (_out, err) = util.subp(cmd, rcs=[0, 1])
+ if len(err):
+ LOG.warn("Error running %s: %s", cmd, err)
+
def install_packages(self, pkglist):
return
diff --git a/cloudinit/distros/gentoo.py b/cloudinit/distros/gentoo.py
index c4b02de1..45c2e658 100644
--- a/cloudinit/distros/gentoo.py
+++ b/cloudinit/distros/gentoo.py
@@ -138,7 +138,7 @@ class Distro(distros.Distro):
return hostname
def set_timezone(self, tz):
- set_etc_timezone(tz=tz, tz_file=self._find_tz_file(tz))
+ distros.set_etc_timezone(tz=tz, tz_file=self._find_tz_file(tz))
def package_command(self, command, args=None, pkgs=None):
if pkgs is None:
diff --git a/cloudinit/distros/rhel.py b/cloudinit/distros/rhel.py
index e8abf111..1a269e08 100644
--- a/cloudinit/distros/rhel.py
+++ b/cloudinit/distros/rhel.py
@@ -98,7 +98,7 @@ class Distro(distros.Distro):
rhel_util.update_sysconfig_file(self.network_conf_fn, net_cfg)
return dev_names
- def _dist_uses_systemd(self):
+ def 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])
@@ -106,7 +106,7 @@ class Distro(distros.Distro):
or (dist.startswith('Fedora') and major >= 18))
def apply_locale(self, locale, out_fn=None):
- if self._dist_uses_systemd():
+ if self.uses_systemd():
if not out_fn:
out_fn = self.systemd_locale_conf_fn
out_fn = self.systemd_locale_conf_fn
@@ -119,7 +119,7 @@ class Distro(distros.Distro):
rhel_util.update_sysconfig_file(out_fn, locale_cfg)
def _write_hostname(self, hostname, out_fn):
- if self._dist_uses_systemd():
+ if self.uses_systemd():
util.subp(['hostnamectl', 'set-hostname', str(hostname)])
else:
host_cfg = {
@@ -135,14 +135,14 @@ class Distro(distros.Distro):
return hostname
def _read_system_hostname(self):
- if self._dist_uses_systemd():
+ if self.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):
- if self._dist_uses_systemd():
+ if self.uses_systemd():
(out, _err) = util.subp(['hostname'])
if len(out):
return out
@@ -163,7 +163,7 @@ class Distro(distros.Distro):
def set_timezone(self, tz):
tz_file = self._find_tz_file(tz)
- if self._dist_uses_systemd():
+ if self.uses_systemd():
# Currently, timedatectl complains if invoked during startup
# so for compatibility, create the link manually.
util.del_file(self.tz_local_fn)