- Converted user list to user dict to allow exclusion of the default user

on Ubuntu systems via cloud-config (LP: #1041384).

- Fixed bug with user creation on Ubuntu where the default user groups are
    not set properly (LP: #1044044).

- Fixed documentation for user creation (LP: #1044508).
This commit is contained in:
Ben Howard 2012-08-31 12:45:40 -06:00
parent 7d2c506bae
commit dbc030b2ab
7 changed files with 76 additions and 37 deletions

View File

@ -107,7 +107,7 @@ def handle(_name, cfg, cloud, log, _args):
user = cloud.distro.get_default_user()
if 'users' in cfg:
user_zero = cfg['users'].keys()[0]
user_zero = cfg['users'][0]
if user_zero != "default":
user = user_zero

View File

@ -40,18 +40,31 @@ def handle(_name, cfg, cloud, log, args):
# import for cloudinit created users
elist = []
for user in cfg['users'].keys():
if user == "default":
for user_cfg in cfg['users']:
user = None
import_ids = []
if isinstance(user_cfg, str) and user_cfg == "default":
user = cloud.distro.get_default_user()
if not user:
continue
import_ids = util.get_cfg_option_list(cfg, "ssh_import_id", [])
else:
if not isinstance(cfg['users'][user], dict):
log.debug("cfg['users'][%s] not a dict, skipping ssh_import",
user)
import_ids = util.get_cfg_option_list(cfg['users'][user],
"ssh_import_id", [])
elif isinstance(user_cfg, dict):
user = None
import_ids = []
try:
user = user_cfg['name']
import_ids = user_cfg['ssh_import_id']
if import_ids and isinstance(import_ids, str):
import_ids = import_ids.split(',')
except:
log.debug("user %s is not configured for ssh_import" % user)
continue
if not len(import_ids):
continue
@ -59,8 +72,8 @@ def handle(_name, cfg, cloud, log, args):
try:
import_ssh_ids(import_ids, user, log)
except Exception as exc:
util.logexc(exc, "ssh-import-id failed for: %s %s" %
(user, import_ids))
util.logexc(log, "ssh-import-id failed for: %s %s" %
(user, import_ids), exc)
elist.append(exc)
if len(elist):
@ -68,6 +81,7 @@ def handle(_name, cfg, cloud, log, args):
def import_ssh_ids(ids, user, log):
if not (user and ids):
log.debug("empty user(%s) or ids(%s). not importing", user, ids)
return

View File

@ -38,19 +38,17 @@ def handle(name, cfg, cloud, log, _args):
if 'users' in cfg:
user_zero = None
for name, user_config in cfg['users'].iteritems():
if not user_zero:
user_zero = name
for user_config in cfg['users']:
# Handle the default user creation
if name == "default" and user_config:
if 'default' in user_config:
log.info("Creating default user")
# Create the default user if so defined
try:
cloud.distro.add_default_user()
if user_zero == name:
if not user_zero:
user_zero = cloud.distro.get_default_user()
except NotImplementedError:
@ -60,11 +58,21 @@ def handle(name, cfg, cloud, log, _args):
log.warn("Distro has not implemented default user "
"creation. No default user will be created")
else:
elif isinstance(user_config, dict) and 'name' in user_config:
name = user_config['name']
if not user_zero:
user_zero = name
# Make options friendly for distro.create_user
new_opts = {}
if isinstance(user_config, dict):
for opt in user_config:
new_opts[opt.replace('-', '')] = user_config[opt]
new_opts[opt.replace('-', '_')] = user_config[opt]
cloud.distro.create_user(name, **new_opts)
cloud.distro.create_user(**new_opts)
else:
# create user with no configuration
cloud.distro.create_user(user_config)

View File

@ -47,6 +47,7 @@ class Distro(object):
__metaclass__ = abc.ABCMeta
default_user = None
default_user_groups = None
def __init__(self, name, cfg, paths):
self._paths = paths
@ -59,16 +60,25 @@ class Distro(object):
# - nopasswd sudo access
user = self.get_default_user()
groups = self.get_default_user_groups()
if not user:
raise NotImplementedError("No Default user")
self.create_user(user,
plain_text_passwd=user,
home="/home/%s" % user,
shell="/bin/bash",
lockpasswd=True,
gecos="%s%s" % (user[0:1].upper(), user[1:]),
sudo="ALL=(ALL) NOPASSWD:ALL")
user_dict = {
'name': user,
'plain_text_passwd': user,
'home': "/home/%s" % user,
'shell': "/bin/bash",
'lock_passwd': True,
'gecos': "%s%s" % (user[0:1].upper(), user[1:]),
'sudo': "ALL=(ALL) NOPASSWD:ALL",
}
if groups:
user_dict['groups'] = groups
self.create_user(**user_dict)
LOG.info("Added default '%s' user with passwordless sudo", user)
@ -204,6 +214,9 @@ class Distro(object):
def get_default_user(self):
return self.default_user
def get_default_user_groups(self):
return self.default_user_groups
def create_user(self, name, **kwargs):
"""
Creates users for the system using the GNU passwd tools. This
@ -220,7 +233,7 @@ class Distro(object):
adduser_opts = {
"gecos": '--comment',
"homedir": '--home',
"primarygroup": '--gid',
"primary_group": '--gid',
"groups": '--groups',
"passwd": '--password',
"shell": '--shell',
@ -229,10 +242,10 @@ class Distro(object):
}
adduser_opts_flags = {
"nousergroup": '--no-user-group',
"no_user_group": '--no-user-group',
"system": '--system',
"nologinit": '--no-log-init',
"nocreatehome": "-M",
"no_log_init": '--no-log-init',
"no_create_home": "-M",
}
# Now check the value and create the command
@ -254,7 +267,7 @@ class Distro(object):
# Default to creating home directory unless otherwise directed
# Also, we do not create home directories for system users.
if "nocreatehome" not in kwargs and "system" not in kwargs:
if "no_create_home" not in kwargs and "system" not in kwargs:
adduser_cmd.append('-m')
# Create the user
@ -273,8 +286,8 @@ class Distro(object):
self.set_passwd(name, kwargs['plain_text_passwd'])
# Default locking down the account.
if ('lockpasswd' not in kwargs and
('lockpasswd' in kwargs and kwargs['lockpasswd']) or
if ('lock_passwd' not in kwargs and
('lock_passwd' in kwargs and kwargs['lock_passwd']) or
'system' not in kwargs):
try:
util.subp(['passwd', '--lock', name])
@ -288,8 +301,8 @@ class Distro(object):
self.write_sudo_rules(name, kwargs['sudo'])
# Import SSH keys
if 'sshauthorizedkeys' in kwargs:
keys = set(kwargs['sshauthorizedkeys']) or []
if 'ssh_authorized_keys' in kwargs:
keys = set(kwargs['ssh_authorized_keys']) or []
ssh_util.setup_user_keys(keys, name, None, self._paths)
return True

View File

@ -31,3 +31,5 @@ class Distro(debian.Distro):
distro_name = 'ubuntu'
default_user = 'ubuntu'
default_user_groups = ("adm,admin,audio,cdrom,dialout,floppy,video,"
"plugdev,dip,netdev,sudo")

View File

@ -3,7 +3,7 @@
# Implement for Ubuntu only: create the default 'ubuntu' user
users:
default: true
- default
# If this is set, 'root' will not be able to ssh in and they
# will get a message to login instead as the above $user (ubuntu)

View File

@ -7,6 +7,7 @@ groups:
# add users to the system. Users are added after groups are added.
users:
- default
- name: foobar
gecos: Foo B. Bar
primary-group: foobar
@ -24,12 +25,13 @@ users:
ssh-authorized-keys:
- <ssh pub key 1>
- <ssh pub key 2>
cloudy:
- name cloudy
gecos: Magic Cloud App Daemon User
inactive: true
system: true
# Valid Values:
# name: The user's login name
# gecos: The user name's real name, i.e. "Bob B. Smith"
# homedir: Optional. Set to the local path you want to use. Defaults to
# /home/<username>