diff options
| -rw-r--r-- | ChangeLog | 3 | ||||
| -rw-r--r-- | cloudinit/distros/__init__.py | 24 | ||||
| -rw-r--r-- | cloudinit/util.py | 15 | ||||
| -rw-r--r-- | config/cloud.cfg | 2 | ||||
| -rwxr-xr-x | systemd/cloud-init-generator | 6 | ||||
| -rw-r--r-- | tests/unittests/test_util.py | 10 | 
6 files changed, 51 insertions, 9 deletions
| @@ -86,6 +86,9 @@   - Enable password changing via a hashed string [Alex Sirbu]   - Added BigStep datasource [Alex Sirbu]   - No longer run pollinate in seed_random (LP: #1554152) + - groups: add defalt user to 'lxd' group.  Create groups listed +   for a user if they do not exist. (LP: #1539317) + - dmi data: fix failure of reading dmi data for unset dmi values  0.7.6:   - open 0.7.6 diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py index a73acae5..e8220985 100644 --- a/cloudinit/distros/__init__.py +++ b/cloudinit/distros/__init__.py @@ -319,6 +319,11 @@ class Distro(object):              LOG.info("User %s already exists, skipping." % name)              return +        if 'create_groups' in kwargs: +            create_groups = kwargs.pop('create_groups') +        else: +            create_groups = True +          adduser_cmd = ['useradd', name]          log_adduser_cmd = ['useradd', name] @@ -346,6 +351,19 @@ class Distro(object):          redact_opts = ['passwd'] +        groups = kwargs.get('groups') +        if groups: +            if isinstance(groups, (list, tuple)): +                kwargs['groups'] = ",".join(groups) +            else: +                groups = groups.split(",") + +        if create_groups: +            for group in kwargs.get('groups').split(","): +                if not util.is_group(group): +                    self.create_group(group) +                    LOG.debug("created group %s for user %s", name, group) +          # Check the values and create the command          for key, val in kwargs.items(): @@ -534,8 +552,10 @@ class Distro(object):                  util.logexc(LOG, "Failed to append sudoers file %s", sudo_file)                  raise e -    def create_group(self, name, members): +    def create_group(self, name, members=None):          group_add_cmd = ['groupadd', name] +        if not members: +            members = []          # Check if group exists, and then add it doesn't          if util.is_group(name): @@ -545,7 +565,7 @@ class Distro(object):                  util.subp(group_add_cmd)                  LOG.info("Created new group %s" % name)              except Exception: -                util.logexc("Failed to create group %s", name) +                util.logexc(LOG, "Failed to create group %s", name)          # Add members to the group, if so defined          if len(members) > 0: diff --git a/cloudinit/util.py b/cloudinit/util.py index e7407ea4..20916e53 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -2140,13 +2140,19 @@ def _read_dmi_syspath(key):              LOG.debug("did not find %s", dmi_key_path)              return None -        key_data = load_file(dmi_key_path) +        key_data = load_file(dmi_key_path, decode=False)          if not key_data:              LOG.debug("%s did not return any data", dmi_key_path)              return None -        LOG.debug("dmi data %s returned %s", dmi_key_path, key_data) -        return key_data.strip() +        # uninitialized dmi values show as all \xff and /sys appends a '\n'. +        # in that event, return a string of '.' in the same length. +        if key_data == b'\xff' * (len(key_data) - 1) + b'\n': +            key_data = b"" + +        str_data = key_data.decode('utf8').strip() +        LOG.debug("dmi data %s returned %s", dmi_key_path, str_data) +        return str_data      except Exception:          logexc(LOG, "failed read of %s", dmi_key_path) @@ -2162,6 +2168,9 @@ def _call_dmidecode(key, dmidecode_path):          cmd = [dmidecode_path, "--string", key]          (result, _err) = subp(cmd)          LOG.debug("dmidecode returned '%s' for '%s'", result, key) +        result = result.strip() +        if result.replace(".", "") == "": +            return ""          return result      except (IOError, OSError) as _err:          LOG.debug('failed dmidecode cmd: %s\n%s', cmd, _err.message) diff --git a/config/cloud.cfg b/config/cloud.cfg index 795df19f..a6afcc83 100644 --- a/config/cloud.cfg +++ b/config/cloud.cfg @@ -89,7 +89,7 @@ system_info:       name: ubuntu       lock_passwd: True       gecos: Ubuntu -     groups: [adm, audio, cdrom, dialout, dip, floppy, netdev, plugdev, sudo, video] +     groups: [adm, audio, cdrom, dialout, dip, floppy, lxd, netdev, plugdev, sudo, video]       sudo: ["ALL=(ALL) NOPASSWD:ALL"]       shell: /bin/bash     # Other config here will be given to the distro class and/or path classes diff --git a/systemd/cloud-init-generator b/systemd/cloud-init-generator index 8156db58..2d319695 100755 --- a/systemd/cloud-init-generator +++ b/systemd/cloud-init-generator @@ -35,9 +35,9 @@ etc_file() {  read_proc_cmdline() {      # return /proc/cmdline for non-container, and /proc/1/cmdline for container      local ctname="systemd" -    if [ -n "$CONTAINER" ] && ctname=$CONTAINER || systemd-detect-virt --container --quiet; then -        local  -        if _RET=$(tr '\0' ' ' < /proc/1/cmdline) >/dev/null 2>&1; then +    if [ -n "$CONTAINER" ] && ctname=$CONTAINER || +        systemd-detect-virt --container --quiet; then +        if { _RET=$(tr '\0' ' ' < /proc/1/cmdline); } 2>/dev/null; then              _RET_MSG="container[$ctname]: pid 1 cmdline"              return          fi diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py index 95990165..37a984ac 100644 --- a/tests/unittests/test_util.py +++ b/tests/unittests/test_util.py @@ -385,6 +385,16 @@ class TestReadDMIData(helpers.FilesystemMockingTestCase):          self.patch_mapping({})          self.assertEqual(None, util.read_dmi_data('expect-fail')) +    def test_dots_returned_instead_of_foxfox(self): +        # uninitialized dmi values show as \xff, return those as . +        my_len = 32 +        dmi_value = b'\xff' * my_len + b'\n' +        expected = "" +        dmi_key = 'system-product-name' +        sysfs_key = 'product_name' +        self._create_sysfs_file(sysfs_key, dmi_value) +        self.assertEqual(expected, util.read_dmi_data(dmi_key)) +  class TestMultiLog(helpers.FilesystemMockingTestCase): | 
