From a510726d622b9d1768b5417d09277d5cc786e952 Mon Sep 17 00:00:00 2001 From: Dominic Schlegel Date: Thu, 29 Mar 2018 14:19:29 -0600 Subject: doc: Fix links in OpenStack datasource documentation. Fix link to external openstack resource and to internal vendor data. LP: #1721660 --- doc/rtd/topics/datasources/openstack.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/rtd/topics/datasources/openstack.rst b/doc/rtd/topics/datasources/openstack.rst index 607b70f3..43592dec 100644 --- a/doc/rtd/topics/datasources/openstack.rst +++ b/doc/rtd/topics/datasources/openstack.rst @@ -5,7 +5,7 @@ OpenStack This datasource supports reading data from the `OpenStack Metadata Service -`_. +`_. Configuration ------------- @@ -59,6 +59,6 @@ upgrade packages and install ``htop`` on all instances: {"cloud-init": "#cloud-config\npackage_upgrade: True\npackages:\n - htop"} For more general information about how cloud-init handles vendor data, -including how it can be disabled by users on instances, see `Vendor Data`_. +including how it can be disabled by users on instances, see :doc:`/topics/vendordata`. .. vi: textwidth=78 -- cgit v1.2.3 From c436e173c4162c940523a2978799193672ff9cd3 Mon Sep 17 00:00:00 2001 From: Ryan Harper Date: Mon, 2 Apr 2018 13:33:39 -0600 Subject: cc_resizefs, util: handle no /dev/zfs The zfs/zpool commands will hang for 10 seconds if /dev/zfs is not present (bug 1760173). This is a common occurence for containers using zfs as rootfs. Additionally handle missing zpool command or other errors that may occur while executing the zpool command. --- cloudinit/config/cc_resizefs.py | 2 ++ cloudinit/util.py | 10 +++++++++- tests/unittests/test_util.py | 29 +++++++++++++++++++++++++++-- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/cloudinit/config/cc_resizefs.py b/cloudinit/config/cc_resizefs.py index c8e1752f..013e69b5 100644 --- a/cloudinit/config/cc_resizefs.py +++ b/cloudinit/config/cc_resizefs.py @@ -251,6 +251,8 @@ def handle(name, cfg, _cloud, log, args): if fs_type == 'zfs': zpool = devpth.split('/')[0] devpth = util.get_device_info_from_zpool(zpool) + if not devpth: + return # could not find device from zpool resize_what = zpool info = "dev=%s mnt_point=%s path=%s" % (devpth, mount_point, resize_what) diff --git a/cloudinit/util.py b/cloudinit/util.py index 0ab2c484..acdc0d85 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -2249,7 +2249,15 @@ def get_mount_info_freebsd(path): def get_device_info_from_zpool(zpool): - (zpoolstatus, err) = subp(['zpool', 'status', zpool]) + # zpool has 10 second timeout waiting for /dev/zfs LP: #1760173 + if not os.path.exists('/dev/zfs'): + LOG.debug('Cannot get zpool info, no /dev/zfs') + return None + try: + (zpoolstatus, err) = subp(['zpool', 'status', zpool]) + except ProcessExecutionError as err: + LOG.warning("Unable to get zpool status of %s: %s", zpool, err) + return None if len(err): return None r = r'.*(ONLINE).*' diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py index 8685b8e2..50101906 100644 --- a/tests/unittests/test_util.py +++ b/tests/unittests/test_util.py @@ -366,8 +366,11 @@ class TestMountinfoParsing(helpers.ResourceUsingTestCase): expected = ('none', 'tmpfs', '/run/lock') self.assertEqual(expected, util.parse_mount_info('/run/lock', lines)) + @mock.patch('cloudinit.util.os') @mock.patch('cloudinit.util.subp') - def test_get_device_info_from_zpool(self, zpool_output): + def test_get_device_info_from_zpool(self, zpool_output, m_os): + # mock /dev/zfs exists + m_os.path.exists.return_value = True # mock subp command from util.get_mount_info_fs_on_zpool zpool_output.return_value = ( self.readResource('zpool_status_simple.txt'), '' @@ -376,9 +379,31 @@ class TestMountinfoParsing(helpers.ResourceUsingTestCase): ret = util.get_device_info_from_zpool('vmzroot') self.assertEqual('gpt/system', ret) self.assertIsNotNone(ret) + m_os.path.exists.assert_called_with('/dev/zfs') + @mock.patch('cloudinit.util.os') + def test_get_device_info_from_zpool_no_dev_zfs(self, m_os): + # mock /dev/zfs missing + m_os.path.exists.return_value = False + # save function return values and do asserts + ret = util.get_device_info_from_zpool('vmzroot') + self.assertIsNone(ret) + + @mock.patch('cloudinit.util.os') + @mock.patch('cloudinit.util.subp') + def test_get_device_info_from_zpool_handles_no_zpool(self, m_sub, m_os): + """Handle case where there is no zpool command""" + # mock /dev/zfs exists + m_os.path.exists.return_value = True + m_sub.side_effect = util.ProcessExecutionError("No zpool cmd") + ret = util.get_device_info_from_zpool('vmzroot') + self.assertIsNone(ret) + + @mock.patch('cloudinit.util.os') @mock.patch('cloudinit.util.subp') - def test_get_device_info_from_zpool_on_error(self, zpool_output): + def test_get_device_info_from_zpool_on_error(self, zpool_output, m_os): + # mock /dev/zfs exists + m_os.path.exists.return_value = True # mock subp command from util.get_mount_info_fs_on_zpool zpool_output.return_value = ( self.readResource('zpool_status_simple.txt'), 'error' -- cgit v1.2.3 From b27f713ae5b4c5b38eda63758dbaeab92be13b9d Mon Sep 17 00:00:00 2001 From: Dominic Schlegel Date: Tue, 3 Apr 2018 12:19:54 -0600 Subject: correct documentation to match correct attribute name usage. LP: #1420018 --- cloudinit/config/cc_users_groups.py | 28 +++++++++++----------- doc/examples/cloud-config-user-groups.txt | 24 +++++++++---------- .../testcases/examples/including_user_groups.yaml | 2 +- .../cloud_tests/testcases/modules/user_groups.yaml | 2 +- tests/data/merge_sources/expected7.yaml | 16 ++++++------- tests/data/merge_sources/source7-1.yaml | 10 ++++---- tests/data/merge_sources/source7-2.yaml | 6 ++--- 7 files changed, 44 insertions(+), 44 deletions(-) diff --git a/cloudinit/config/cc_users_groups.py b/cloudinit/config/cc_users_groups.py index f363000d..b215e95a 100644 --- a/cloudinit/config/cc_users_groups.py +++ b/cloudinit/config/cc_users_groups.py @@ -34,16 +34,16 @@ config keys for an entry in ``users`` are as follows: - ``homedir``: Optional. Home dir for user. Default is ``/home/`` - ``inactive``: Optional. Mark user inactive. Default: false - ``lock_passwd``: Optional. Disable password login. Default: true - - ``no-create-home``: Optional. Do not create home directory. Default: + - ``no_create_home``: Optional. Do not create home directory. Default: false - - ``no-log-init``: Optional. Do not initialize lastlog and faillog for + - ``no_log_init``: Optional. Do not initialize lastlog and faillog for user. Default: false - - ``no-user-group``: Optional. Do not create group named after user. + - ``no_user_group``: Optional. Do not create group named after user. Default: false - ``passwd``: Hash of user password - - ``primary-group``: Optional. Primary group for user. Default to new group + - ``primary_group``: Optional. Primary group for user. Default to new group named after user. - - ``selinux-user``: Optional. SELinux user for user's login. Default to + - ``selinux_user``: Optional. SELinux user for user's login. Default to default SELinux user. - ``shell``: Optional. The user's login shell. The default is to set no shell, which results in a system-specific default being used. @@ -51,9 +51,9 @@ config keys for an entry in ``users`` are as follows: a Snappy user through ``snap create-user``. If an Ubuntu SSO account is associated with the address, username and SSH keys will be requested from there. Default: none - - ``ssh-authorized-keys``: Optional. List of ssh keys to add to user's + - ``ssh_authorized_keys``: Optional. List of ssh keys to add to user's authkeys file. Default: none - - ``ssh-import-id``: Optional. SSH id to import for user. Default: none + - ``ssh_import_id``: Optional. SSH id to import for user. Default: none - ``sudo``: Optional. Sudo rule to use, or list of sudo rules to use. Default: none. - ``system``: Optional. Create user as system user with no home directory. @@ -89,18 +89,18 @@ config keys for an entry in ``users`` are as follows: homedir: inactive: lock_passwd: - no-create-home: - no-log-init: - no-user-group: + no_create_home: + no_log_init: + no_user_group: passwd: - primary-group: - selinux-user: + primary_group: + selinux_user: shell: snapuser: - ssh-authorized-keys: + ssh_authorized_keys: - - - ssh-import-id: + ssh_import_id: sudo: system: uid: diff --git a/doc/examples/cloud-config-user-groups.txt b/doc/examples/cloud-config-user-groups.txt index 0554d1f7..7bca24a3 100644 --- a/doc/examples/cloud-config-user-groups.txt +++ b/doc/examples/cloud-config-user-groups.txt @@ -10,20 +10,20 @@ users: - default - name: foobar gecos: Foo B. Bar - primary-group: foobar + primary_group: foobar groups: users - selinux-user: staff_u + selinux_user: staff_u expiredate: 2012-09-01 - ssh-import-id: foobar + ssh_import_id: foobar lock_passwd: false passwd: $6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/ - name: barfoo gecos: Bar B. Foo sudo: ALL=(ALL) NOPASSWD:ALL groups: users, admin - ssh-import-id: None + ssh_import_id: None lock_passwd: true - ssh-authorized-keys: + ssh_authorized_keys: - - - name: cloudy @@ -37,10 +37,10 @@ users: # 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/ -# primary-group: define the primary group. Defaults to a new group created +# primary_group: define the primary group. Defaults to a new group created # named after the user. # groups: Optional. Additional groups to add the user to. Defaults to none -# selinux-user: Optional. The SELinux user for the user's login, such as +# selinux_user: Optional. The SELinux user for the user's login, such as # "staff_u". When this is omitted the system will select the default # SELinux user. # lock_passwd: Defaults to true. Lock the password to disable password login @@ -66,11 +66,11 @@ users: # should use SSH authentication only. # # You have thus been warned. -# no-create-home: When set to true, do not create home directory. -# no-user-group: When set to true, do not create a group named after the user. -# no-log-init: When set to true, do not initialize lastlog and faillog database. -# ssh-import-id: Optional. Import SSH ids -# ssh-authorized-keys: Optional. [list] Add keys to user's authorized keys file +# no_create_home: When set to true, do not create home directory. +# no_user_group: When set to true, do not create a group named after the user. +# no_log_init: When set to true, do not initialize lastlog and faillog database. +# ssh_import_id: Optional. Import SSH ids +# ssh_authorized_keys: Optional. [list] Add keys to user's authorized keys file # sudo: Defaults to none. Set to the sudo string you want to use, i.e. # ALL=(ALL) NOPASSWD:ALL. To add multiple rules, use the following # format. diff --git a/tests/cloud_tests/testcases/examples/including_user_groups.yaml b/tests/cloud_tests/testcases/examples/including_user_groups.yaml index 469d03c3..77528d98 100644 --- a/tests/cloud_tests/testcases/examples/including_user_groups.yaml +++ b/tests/cloud_tests/testcases/examples/including_user_groups.yaml @@ -16,7 +16,7 @@ cloud_config: | - default - name: foobar gecos: Foo B. Bar - primary-group: foobar + primary_group: foobar groups: users expiredate: 2038-01-19 lock_passwd: false diff --git a/tests/cloud_tests/testcases/modules/user_groups.yaml b/tests/cloud_tests/testcases/modules/user_groups.yaml index 22b5d706..675dfb8c 100644 --- a/tests/cloud_tests/testcases/modules/user_groups.yaml +++ b/tests/cloud_tests/testcases/modules/user_groups.yaml @@ -15,7 +15,7 @@ cloud_config: | - default - name: foobar gecos: Foo B. Bar - primary-group: foobar + primary_group: foobar groups: users expiredate: 2038-01-19 lock_passwd: false diff --git a/tests/data/merge_sources/expected7.yaml b/tests/data/merge_sources/expected7.yaml index 25284f04..d32988e8 100644 --- a/tests/data/merge_sources/expected7.yaml +++ b/tests/data/merge_sources/expected7.yaml @@ -4,20 +4,20 @@ users: - default - name: foobar gecos: Foo B. Bar - primary-group: foobar + primary_group: foobar groups: users - selinux-user: staff_u + selinux_user: staff_u expiredate: 2012-09-01 - ssh-import-id: foobar + ssh_import_id: foobar lock-passwd: false passwd: $6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/ - name: barfoo gecos: Bar B. Foo sudo: ALL=(ALL) NOPASSWD:ALL groups: users, admin - ssh-import-id: None + ssh_import_id: None lock-passwd: true - ssh-authorized-keys: + ssh_authorized_keys: - - - name: cloudy @@ -29,10 +29,10 @@ users: - sue - name: foobar_jr gecos: Foo B. Bar Jr - primary-group: foobar + primary_group: foobar groups: users - selinux-user: staff_u + selinux_user: staff_u expiredate: 2012-09-01 - ssh-import-id: foobar + ssh_import_id: foobar lock-passwd: false passwd: $6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/ diff --git a/tests/data/merge_sources/source7-1.yaml b/tests/data/merge_sources/source7-1.yaml index 8fb9b32a..6405fc9b 100644 --- a/tests/data/merge_sources/source7-1.yaml +++ b/tests/data/merge_sources/source7-1.yaml @@ -4,20 +4,20 @@ users: - default - name: foobar gecos: Foo B. Bar - primary-group: foobar + primary_group: foobar groups: users - selinux-user: staff_u + selinux_user: staff_u expiredate: 2012-09-01 - ssh-import-id: foobar + ssh_import_id: foobar lock-passwd: false passwd: $6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/ - name: barfoo gecos: Bar B. Foo sudo: ALL=(ALL) NOPASSWD:ALL groups: users, admin - ssh-import-id: None + ssh_import_id: None lock-passwd: true - ssh-authorized-keys: + ssh_authorized_keys: - - - name: cloudy diff --git a/tests/data/merge_sources/source7-2.yaml b/tests/data/merge_sources/source7-2.yaml index 1e26201b..0cd28978 100644 --- a/tests/data/merge_sources/source7-2.yaml +++ b/tests/data/merge_sources/source7-2.yaml @@ -6,11 +6,11 @@ users: - sue - name: foobar_jr gecos: Foo B. Bar Jr - primary-group: foobar + primary_group: foobar groups: users - selinux-user: staff_u + selinux_user: staff_u expiredate: 2012-09-01 - ssh-import-id: foobar + ssh_import_id: foobar lock-passwd: false passwd: $6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/ -- cgit v1.2.3 From 05926e48eae0fa70a26da6449617e04e87c4e704 Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Tue, 3 Apr 2018 16:52:13 -0600 Subject: tests: fix integration tests to support lxd 3.0 release Integration tests previously had a logic path that was unexercised on jenkins because we were on an older version of lxc. With an upgrade to lxd version 3.0 we need to bump pylxd dependency pin and fix a typo in integration tests which checked the lxd version. --- integration-requirements.txt | 4 ++-- tests/cloud_tests/platforms/lxd/instance.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/integration-requirements.txt b/integration-requirements.txt index 45baac6a..df3a73ef 100644 --- a/integration-requirements.txt +++ b/integration-requirements.txt @@ -12,8 +12,8 @@ boto3==1.5.9 paramiko==2.4.0 # lxd backend -# 01/10/2018: enables use of lxd as snap support -git+https://github.com/lxc/pylxd.git@0722955260a6557e6d2ffde1896bfe0707bbca27 +# 04/03/2018: enables use of lxd 3.0 +git+https://github.com/lxc/pylxd.git@1a85a12a23401de6e96b1aeaf59ecbff2e88f49d # finds latest image information diff --git a/tests/cloud_tests/platforms/lxd/instance.py b/tests/cloud_tests/platforms/lxd/instance.py index 0488da57..0d957bca 100644 --- a/tests/cloud_tests/platforms/lxd/instance.py +++ b/tests/cloud_tests/platforms/lxd/instance.py @@ -210,7 +210,7 @@ def _has_proper_console_support(): reason = "LXD server does not support console api extension" else: dver = info.get('environment', {}).get('driver_version', "") - if dver.startswith("2.") or dver.startwith("1."): + if dver.startswith("2.") or dver.startswith("1."): reason = "LXD Driver version not 3.x+ (%s)" % dver else: try: -- cgit v1.2.3