summaryrefslogtreecommitdiff
path: root/cloudinit/distros
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/distros')
-rw-r--r--cloudinit/distros/__init__.py258
1 files changed, 124 insertions, 134 deletions
diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py
index 3de5be36..b43d662e 100644
--- a/cloudinit/distros/__init__.py
+++ b/cloudinit/distros/__init__.py
@@ -180,13 +180,7 @@ class Distro(object):
def get_default_user_groups(self):
if not self.default_user_groups:
return []
- def_groups = []
- if isinstance(self.default_user_groups, (str, basestring)):
- def_groups = self.default_user_groups.split(",")
- else:
- def_groups = list(self.default_user_groups)
- def_groups = list(sorted(set(def_groups)))
- return def_groups
+ return _uniq_merge_sorted(self.default_user_groups)
def create_user(self, name, **kwargs):
"""
@@ -294,133 +288,6 @@ class Distro(object):
return True
- def _normalize_groups(self, grp_cfg):
- groups = {}
- if isinstance(grp_cfg, (str, basestring)):
- grp_cfg = grp_cfg.strip().split(",")
-
- if isinstance(grp_cfg, (list)):
- for g in grp_cfg:
- g = g.strip()
- if g:
- groups[g] = []
- elif isinstance(grp_cfg, (dict)):
- for grp_name, grp_members in grp_cfg.items():
- if isinstance(grp_members, (str, basestring)):
- r_grp_members = []
- for gc in grp_members.strip().split(','):
- gc = gc.strip()
- if gc and gc not in r_grp_members:
- r_grp_members.append(gc)
- grp_members = r_grp_members
- elif not isinstance(grp_members, (list)):
- raise TypeError(("Group member config must be list "
- " or string types only and not %s") %
- util.obj_name(grp_members))
- groups[grp_name] = grp_members
- else:
- raise TypeError(("Group config must be list, dict "
- " or string types only and not %s") %
- util.obj_name(grp_cfg))
- return groups
-
- def _normalize_users(self, u_cfg):
- if isinstance(u_cfg, (dict)):
- ad_ucfg = []
- for (k, v) in u_cfg.items():
- if isinstance(v, (bool, int, basestring, str)):
- if util.is_true(v):
- ad_ucfg.append(str(k))
- elif isinstance(v, (dict)):
- v['name'] = k
- ad_ucfg.append(v)
- else:
- raise TypeError(("Unmappable user value type %s"
- " for key %s") % (util.obj_name(v), k))
- u_cfg = ad_ucfg
- elif isinstance(u_cfg, (str, basestring)):
- u_cfg = u_cfg.strip().split(",")
-
- users = {}
- for user_config in u_cfg:
- if isinstance(user_config, (str, basestring)):
- for u in user_config.strip().split(","):
- u = u.strip()
- if u and u not in users:
- users[u] = {}
- elif isinstance(user_config, (dict)):
- if 'name' in user_config:
- n = user_config.pop('name')
- prev_config = users.get(n) or {}
- users[n] = util.mergemanydict([prev_config,
- user_config])
- else:
- # Assume the default user then
- prev_config = users.get('default') or {}
- users['default'] = util.mergemanydict([prev_config,
- user_config])
- elif isinstance(user_config, (bool, int)):
- pass
- else:
- raise TypeError(("User config must be dictionary "
- " or string types only and not %s") %
- util.obj_name(user_config))
-
- # Ensure user options are in the right python friendly format
- if users:
- c_users = {}
- for (uname, uconfig) in users.items():
- c_uconfig = {}
- for (k, v) in uconfig.items():
- k = k.replace('-', '_').strip()
- if k:
- c_uconfig[k] = v
- c_users[uname] = c_uconfig
- users = c_users
-
- # Fixup the default user into the real
- # default user name and extract it
- default_user = {}
- if users and 'default' in users:
- try:
- def_config = users.pop('default')
- def_user = self.get_default_user()
- def_groups = self.get_default_user_groups()
- if def_user:
- u_config = users.pop(def_user, None) or {}
- u_groups = u_config.get('groups') or []
- if isinstance(u_groups, (str, basestring)):
- u_groups = u_groups.strip().split(",")
- u_groups.extend(def_groups)
- u_groups = set([x.strip() for x in u_groups if x.strip()])
- u_config['groups'] = ",".join(sorted(u_groups))
- default_user = {
- 'name': def_user,
- 'config': util.mergemanydict([def_config, u_config]),
- }
- else:
- LOG.warn(("Distro has not provided a default user "
- "for creation. No default user will be "
- "normalized."))
- users.pop('default', None)
- except NotImplementedError:
- LOG.warn(("Distro has not implemented default user "
- "creation. No default user will be normalized."))
- users.pop('default', None)
-
- return (default_user, users)
-
- def normalize_users_groups(self, ug_cfg):
- users = {}
- groups = {}
- default_user = {}
- if 'groups' in ug_cfg:
- groups = self._normalize_groups(ug_cfg['groups'])
-
- if 'users' in ug_cfg:
- default_user, users = self._normalize_users(ug_cfg['users'])
- return ((users, default_user), groups)
-
def write_sudo_rules(self,
user,
rules,
@@ -521,6 +388,129 @@ def _get_arch_package_mirror_info(package_mirrors, arch):
return default
+def _uniq_merge_sorted(*lists):
+ return sorted(_uniq_merge(*lists))
+
+
+def _uniq_merge(*lists):
+ combined_list = []
+ for a_list in lists:
+ if isinstance(a_list, (str, basestring)):
+ a_list = a_list.strip().split(",")
+ else:
+ a_list = [str(a) for a in a_list]
+ a_list = [a.strip() for a in a_list if a.strip()]
+ combined_list.extend(a_list)
+ uniq_list = []
+ for a in combined_list:
+ if a in uniq_list:
+ continue
+ else:
+ uniq_list.append(a)
+ return uniq_list
+
+
+def _normalize_groups(grp_cfg):
+ if isinstance(grp_cfg, (str, basestring, list)):
+ c_grp_cfg = {}
+ for i in _uniq_merge(grp_cfg):
+ c_grp_cfg[i] = []
+ grp_cfg = c_grp_cfg
+
+ groups = {}
+ if isinstance(grp_cfg, (dict)):
+ for (grp_name, grp_members) in grp_cfg.items():
+ groups[grp_name] = _uniq_merge_sorted(grp_members)
+ else:
+ raise TypeError(("Group config must be list, dict "
+ " or string types only and not %s") %
+ util.obj_name(grp_cfg))
+ return groups
+
+
+def _normalize_users(u_cfg, def_user=None, def_user_groups=None):
+ if isinstance(u_cfg, (dict)):
+ ad_ucfg = []
+ for (k, v) in u_cfg.items():
+ if isinstance(v, (bool, int, basestring, str, float)):
+ if util.is_true(v):
+ ad_ucfg.append(str(k))
+ elif isinstance(v, (dict)):
+ v['name'] = k
+ ad_ucfg.append(v)
+ else:
+ raise TypeError(("Unmappable user value type %s"
+ " for key %s") % (util.obj_name(v), k))
+ u_cfg = ad_ucfg
+ elif isinstance(u_cfg, (str, basestring)):
+ u_cfg = _uniq_merge_sorted(u_cfg)
+
+ users = {}
+ for user_config in u_cfg:
+ if isinstance(user_config, (str, basestring, list)):
+ for u in _uniq_merge(user_config):
+ if u and u not in users:
+ users[u] = {}
+ elif isinstance(user_config, (dict)):
+ if 'name' in user_config:
+ n = user_config.pop('name')
+ prev_config = users.get(n) or {}
+ users[n] = util.mergemanydict([prev_config,
+ user_config])
+ else:
+ # Assume the default user then
+ prev_config = users.get('default') or {}
+ users['default'] = util.mergemanydict([prev_config,
+ user_config])
+ else:
+ raise TypeError(("User config must be dictionary/list "
+ " or string types only and not %s") %
+ util.obj_name(user_config))
+
+ # Ensure user options are in the right python friendly format
+ if users:
+ c_users = {}
+ for (uname, uconfig) in users.items():
+ c_uconfig = {}
+ for (k, v) in uconfig.items():
+ k = k.replace('-', '_').strip()
+ if k:
+ c_uconfig[k] = v
+ c_users[uname] = c_uconfig
+ users = c_users
+
+ # Fixup the default user into the real
+ # default user name and extract it
+ default_user = {}
+ if users and 'default' in users:
+ def_config = users.pop('default')
+ def_groups = def_user_groups or []
+ if def_user:
+ u_config = users.pop(def_user, None) or {}
+ u_groups = u_config.get('groups') or []
+ u_groups = _uniq_merge_sorted(u_groups, def_groups)
+ u_config['groups'] = ",".join(u_groups)
+ default_user = {
+ 'name': def_user,
+ 'config': util.mergemanydict([def_config, u_config]),
+ }
+
+ return (default_user, users)
+
+
+def normalize_users_groups(cfg, def_user=None, def_user_groups=None):
+ users = {}
+ groups = {}
+ default_user = {}
+ if 'groups' in cfg:
+ groups = _normalize_groups(cfg['groups'])
+ if 'users' in cfg:
+ (default_user, users) = _normalize_users(cfg['users'],
+ def_user,
+ def_user_groups)
+ return ((users, default_user), groups)
+
+
def fetch(name):
locs = importer.find_module(name,
['', __name__],