summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--cloudinit/distros/__init__.py25
-rw-r--r--cloudinit/sources/DataSourceCloudStack.py82
3 files changed, 87 insertions, 31 deletions
diff --git a/ChangeLog b/ChangeLog
index 31a19996..544032a2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,8 +11,15 @@
- support omnibus installer for chef [Anatoliy Dobrosynets]
- fix bug where cloud-config in user-data could not modify system_info
settings (LP: #1090482)
- - fix CloudStack DataSource to use Virtual Router as found in
- /var/lib/dhcpclient rather than default gateway (LP: #1089989)
+ - fix CloudStack DataSource to use Virtual Router as described by
+ CloudStack documentation if it is available by searching through dhclient
+ lease files. If it is not available, then fall back to the default
+ gateway. (LP: #1089989)
+ - fix redaction of password field in log (LP: #1096417)
+ - fix to cloud-config user setup. Previously, lock_passwd was broken and
+ all accounts would be locked unless 'system' was given (LP: #1096423).
+ - Allow 'sr0' (or sr[0-9]) to be specified without /dev/ as a source for
+ mounts. [Vlastimil Holer]
0.7.1:
- sysvinit: fix missing dependency in cloud-init job for RHEL 5.6
- config-drive: map hostname to local-hostname (LP: #1061964)
diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py
index 6a684b89..38b2f829 100644
--- a/cloudinit/distros/__init__.py
+++ b/cloudinit/distros/__init__.py
@@ -297,22 +297,26 @@ class Distro(object):
"no_create_home": "-M",
}
+ redact_fields = ['passwd']
+
# Now check the value and create the command
for option in kwargs:
value = kwargs[option]
if option in adduser_opts and value \
and isinstance(value, str):
adduser_cmd.extend([adduser_opts[option], value])
-
- # Redact the password field from the logs
- if option != "password":
- x_adduser_cmd.extend([adduser_opts[option], value])
- else:
+ # Redact certain fields from the logs
+ if option in redact_fields:
x_adduser_cmd.extend([adduser_opts[option], 'REDACTED'])
-
+ else:
+ x_adduser_cmd.extend([adduser_opts[option], value])
elif option in adduser_opts_flags and value:
adduser_cmd.append(adduser_opts_flags[option])
- x_adduser_cmd.append(adduser_opts_flags[option])
+ # Redact certain fields from the logs
+ if option in redact_fields:
+ x_adduser_cmd.append('REDACTED')
+ else:
+ x_adduser_cmd.append(adduser_opts_flags[option])
# Default to creating home directory unless otherwise directed
# Also, we do not create home directories for system users.
@@ -334,10 +338,9 @@ class Distro(object):
if 'plain_text_passwd' in kwargs and kwargs['plain_text_passwd']:
self.set_passwd(name, kwargs['plain_text_passwd'])
- # Default locking down the account.
- if ('lock_passwd' not in kwargs and
- ('lock_passwd' in kwargs and kwargs['lock_passwd']) or
- 'system' not in kwargs):
+ # Default locking down the account. 'lock_passwd' defaults to True.
+ # lock account unless lock_password is False.
+ if kwargs.get('lock_passwd', True):
try:
util.subp(['passwd', '--lock', name])
except Exception as e:
diff --git a/cloudinit/sources/DataSourceCloudStack.py b/cloudinit/sources/DataSourceCloudStack.py
index 82e1e130..275caf0d 100644
--- a/cloudinit/sources/DataSourceCloudStack.py
+++ b/cloudinit/sources/DataSourceCloudStack.py
@@ -30,6 +30,8 @@ from cloudinit import log as logging
from cloudinit import sources
from cloudinit import url_helper as uhelp
from cloudinit import util
+from socket import inet_ntoa
+from struct import pack
LOG = logging.getLogger(__name__)
@@ -122,26 +124,70 @@ class DataSourceCloudStack(sources.DataSource):
return self.metadata['availability-zone']
+def get_default_gateway():
+ # Returns the default gateway ip address in the dotted format.
+ lines = util.load_file("/proc/net/route").splitlines()
+ for line in lines:
+ items = line.split("\t")
+ if items[1] == "00000000":
+ # Found the default route, get the gateway
+ gw = inet_ntoa(pack("<L", int(items[2], 16)))
+ LOG.debug("Found default route, gateway is %s", gw)
+ return gw
+ return None
+
+
+def get_dhclient_d():
+ # find lease files directory
+ supported_dirs = ["/var/lib/dhclient", "/var/lib/dhcp"]
+ for d in supported_dirs:
+ if os.path.exists(d):
+ LOG.debug("Using %s lease directory", d)
+ return d
+ return None
+
+
+def get_latest_lease():
+ # find latest lease file
+ lease_d = get_dhclient_d()
+ if not lease_d:
+ return None
+ lease_files = os.listdir(lease_d)
+ latest_mtime = -1
+ latest_file = None
+ for file_name in lease_files:
+ if file_name.endswith(".lease") or file_name.endswith(".leases"):
+ abs_path = os.path.join(lease_d, file_name)
+ mtime = os.path.getmtime(abs_path)
+ if mtime > latest_mtime:
+ latest_mtime = mtime
+ latest_file = abs_path
+ return latest_file
+
+
def get_vr_address():
- # get the address of the virtual router via dhcp responses
+ # Get the address of the virtual router via dhcp leases
# see http://bit.ly/T76eKC for documentation on the virtual router.
- dhclient_d = "/var/lib/dhclient"
- addresses = set()
- dhclient_files = os.listdir(dhclient_d)
- for file_name in dhclient_files:
- if file_name.endswith(".lease") or file_name.endswith(".leases"):
- with open(os.path.join(dhclient_d, file_name), "r") as fd:
- for line in fd:
- if "dhcp-server-identifier" in line:
- words = line.strip(" ;\r\n").split(" ")
- if len(words) > 2:
- dhcp = words[2]
- LOG.debug("Found DHCP identifier %s", dhcp)
- addresses.add(dhcp)
- if len(addresses) != 1:
- # No unique virtual router found
- return None
- return addresses.pop()
+ # If no virtual router is detected, fallback on default gateway.
+ lease_file = get_latest_lease()
+ if not lease_file:
+ LOG.debug("No lease file found, using default gateway")
+ return get_default_gateway()
+
+ latest_address = None
+ with open(lease_file, "r") as fd:
+ for line in fd:
+ if "dhcp-server-identifier" in line:
+ words = line.strip(" ;\r\n").split(" ")
+ if len(words) > 2:
+ dhcp = words[2]
+ LOG.debug("Found DHCP identifier %s", dhcp)
+ latest_address = dhcp
+ if not latest_address:
+ # No virtual router found, fallback on default gateway
+ LOG.debug("No DHCP found, using default gateway")
+ return get_default_gateway()
+ return latest_address
# Used to match classes to dependencies