예제 #1
0
    def setUp(self):
        super(TestCloudStackPasswordFetching, self).setUp()
        self.patches = ExitStack()
        self.addCleanup(self.patches.close)
        mod_name = MOD_PATH
        self.patches.enter_context(mock.patch("{0}.ec2".format(mod_name)))
        self.patches.enter_context(mock.patch("{0}.uhelp".format(mod_name)))
        default_gw = "192.201.20.0"
        get_latest_lease = mock.MagicMock(return_value=None)
        self.patches.enter_context(
            mock.patch(mod_name + ".get_latest_lease", get_latest_lease))

        get_default_gw = mock.MagicMock(return_value=default_gw)
        self.patches.enter_context(
            mock.patch(mod_name + ".get_default_gateway", get_default_gw))

        get_networkd_server_address = mock.MagicMock(return_value=None)
        self.patches.enter_context(
            mock.patch(
                mod_name + ".dhcp.networkd_get_option_from_leases",
                get_networkd_server_address,
            ))
        get_data_server = mock.MagicMock(return_value=None)
        self.patches.enter_context(
            mock.patch(mod_name + ".get_data_server", get_data_server))

        self.tmp = self.tmp_dir()
예제 #2
0
 def test_valid_filesystem_returns_true(self):
     self.enumerate_disk.return_value = (mock.MagicMock() for _ in range(1))
     self.check_fs.return_value = (
         mock.MagicMock(),
         "ext4",
         mock.MagicMock(),
     )
     self.assertTrue(cc_disk_setup.is_disk_used(mock.MagicMock()))
 def test_handle_no_drivers_does_nothing(self, m_install_drivers):
     """If no 'drivers' key in the config, nothing should be done."""
     myCloud = mock.MagicMock()
     myLog = mock.MagicMock()
     drivers.handle("ubuntu_drivers", {"foo": "bzr"}, myCloud, myLog, None)
     self.assertIn("Skipping module named",
                   myLog.debug.call_args_list[0][0][0])
     self.assertEqual(0, m_install_drivers.call_count)
예제 #4
0
 def test_handle_no_drivers_does_nothing(
     self, m_install_drivers, m_debconf, cfg_accepted, install_gpgpu
 ):
     """If no 'drivers' key in the config, nothing should be done."""
     myCloud = mock.MagicMock()
     myLog = mock.MagicMock()
     drivers.handle("ubuntu_drivers", {"foo": "bzr"}, myCloud, myLog, None)
     assert "Skipping module named" in myLog.debug.call_args_list[0][0][0]
     assert 0 == m_install_drivers.call_count
예제 #5
0
 def test_maybe_install_ua_tools_noop_when_ua_tools_present(self, m_which):
     """Do nothing if ubuntu-advantage-tools already exists."""
     m_which.return_value = '/usr/bin/ua'  # already installed
     distro = mock.MagicMock()
     distro.update_package_sources.side_effect = RuntimeError(
         'Some apt error')
     maybe_install_ua_tools(cloud=FakeCloud(distro))  # No RuntimeError
예제 #6
0
 def test_handler_skips_empty_landscape_cloudconfig(self):
     """Empty landscape cloud-config section does no work."""
     mycloud = get_cloud("ubuntu")
     mycloud.distro = mock.MagicMock()
     cfg = {"landscape": {}}
     cc_landscape.handle("notimportant", cfg, mycloud, LOG, None)
     self.assertFalse(mycloud.distro.install_packages.called)
예제 #7
0
    def test_readurl_timeout(self, readurl_timeout, request_timeout):
        url = "http://hostname/path"
        m_response = mock.MagicMock()

        class FakeSession(requests.Session):
            @classmethod
            def request(cls, **kwargs):
                expected_kwargs = {
                    "url": url,
                    "allow_redirects": True,
                    "method": "GET",
                    "headers": {
                        "User-Agent": "Cloud-Init/%s"
                        % (version.version_string())
                    },
                    "timeout": request_timeout,
                }
                if request_timeout is None:
                    expected_kwargs.pop("timeout")

                assert kwargs == expected_kwargs
                return m_response

        with mock.patch(
            M_PATH + "requests.Session", side_effect=[FakeSession()]
        ):
            response = read_file_or_url(url, timeout=readurl_timeout)

        assert response._response == m_response
    def test_install_drivers_handles_old_ubuntu_drivers_gracefully(
            self, m_which, m_subp, m_tmp):
        """Older ubuntu-drivers versions should emit message and raise error"""
        tdir = self.tmp_dir()
        debconf_file = os.path.join(tdir, "nvidia.template")
        m_tmp.return_value = tdir
        myCloud = mock.MagicMock()

        def fake_subp(cmd):
            if cmd[0].startswith(tdir):
                return
            raise ProcessExecutionError(stderr=OLD_UBUNTU_DRIVERS_ERROR_STDERR,
                                        exit_code=2)

        m_subp.side_effect = fake_subp

        with self.assertRaises(Exception):
            drivers.handle("ubuntu_drivers", self.cfg_accepted, myCloud, None,
                           None)
        self.assertEqual(
            [mock.call(["ubuntu-drivers-common"])],
            myCloud.distro.install_packages.call_args_list,
        )
        self.assertEqual(
            [
                mock.call(AnyTempScriptAndDebconfFile(tdir, debconf_file)),
                mock.call(self.install_gpgpu),
            ],
            m_subp.call_args_list,
        )
        self.assertIn(
            "WARNING: the available version of ubuntu-drivers is"
            " too old to perform requested driver installation",
            self.logs.getvalue(),
        )
예제 #9
0
    def test_handle_raises_error_if_no_drivers_found(
        self,
        m_which,
        m_subp,
        m_tmp,
        m_debconf,
        caplog,
        tmpdir,
        cfg_accepted,
        install_gpgpu,
    ):
        """If ubuntu-drivers doesn't install any drivers, raise an error."""
        tdir = tmpdir
        debconf_file = os.path.join(tdir, "nvidia.template")
        m_tmp.return_value = tdir
        myCloud = mock.MagicMock()

        m_subp.side_effect = ProcessExecutionError(
            stdout="No drivers found for installation.\n", exit_code=1
        )

        with pytest.raises(Exception):
            drivers.handle("ubuntu_drivers", cfg_accepted, myCloud, None, None)
        assert [
            mock.call(drivers.X_LOADTEMPLATEFILE, debconf_file)
        ] == m_debconf.DebconfCommunicator().__enter__().command.call_args_list
        assert [
            mock.call(["ubuntu-drivers-common"])
        ] == myCloud.distro.install_packages.call_args_list
        assert [mock.call(install_gpgpu)] == m_subp.call_args_list
        assert (
            "ubuntu-drivers found no drivers for installation" in caplog.text
        )
예제 #10
0
    def test_happy_path_taken(
        self,
        m_which,
        m_subp,
        m_tmp,
        m_debconf,
        tmpdir,
        cfg_accepted,
        install_gpgpu,
        true_value,
    ):
        """Positive path test through handle. Package should be installed."""
        new_config: dict = copy.deepcopy(cfg_accepted)
        new_config["drivers"]["nvidia"]["license-accepted"] = true_value

        tdir = tmpdir
        debconf_file = tdir.join("nvidia.template")
        m_tmp.return_value = tdir
        myCloud = mock.MagicMock()
        drivers.handle("ubuntu_drivers", new_config, myCloud, None, None)
        assert [
            mock.call(drivers.X_LOADTEMPLATEFILE, debconf_file)
        ] == m_debconf.DebconfCommunicator().__enter__().command.call_args_list
        assert [
            mock.call(["ubuntu-drivers-common"])
        ] == myCloud.distro.install_packages.call_args_list
        assert [mock.call(install_gpgpu)] == m_subp.call_args_list
    def test_handle_raises_error_if_no_drivers_found(self, m_which, m_subp,
                                                     m_tmp):
        """If ubuntu-drivers doesn't install any drivers, raise an error."""
        tdir = self.tmp_dir()
        debconf_file = os.path.join(tdir, "nvidia.template")
        m_tmp.return_value = tdir
        myCloud = mock.MagicMock()

        def fake_subp(cmd):
            if cmd[0].startswith(tdir):
                return
            raise ProcessExecutionError(
                stdout="No drivers found for installation.\n", exit_code=1)

        m_subp.side_effect = fake_subp

        with self.assertRaises(Exception):
            drivers.handle("ubuntu_drivers", self.cfg_accepted, myCloud, None,
                           None)
        self.assertEqual(
            [mock.call(["ubuntu-drivers-common"])],
            myCloud.distro.install_packages.call_args_list,
        )
        self.assertEqual(
            [
                mock.call(AnyTempScriptAndDebconfFile(tdir, debconf_file)),
                mock.call(self.install_gpgpu),
            ],
            m_subp.call_args_list,
        )
        self.assertIn(
            "ubuntu-drivers found no drivers for installation",
            self.logs.getvalue(),
        )
예제 #12
0
 def test_handler_installs_client_and_creates_config_file(self):
     """Write landscape client.conf and install landscape-client."""
     mycloud = get_cloud('ubuntu')
     cfg = {'landscape': {'client': {}}}
     expected = {
         'client': {
             'log_level': 'info',
             'url': 'https://landscape.canonical.com/message-system',
             'ping_url': 'http://landscape.canonical.com/ping',
             'data_path': '/var/lib/landscape/client'
         }
     }
     mycloud.distro = mock.MagicMock()
     wrap_and_call(
         'cloudinit.config.cc_landscape', {
             'LSC_CLIENT_CFG_FILE': {
                 'new': self.conf
             },
             'LS_DEFAULT_FILE': {
                 'new': self.default_file
             }
         }, cc_landscape.handle, 'notimportant', cfg, mycloud, LOG, None)
     self.assertEqual([mock.call('landscape-client')],
                      mycloud.distro.install_packages.call_args)
     self.assertEqual(expected, dict(ConfigObj(self.conf)))
     self.assertIn('Wrote landscape config file to {0}'.format(self.conf),
                   self.logs.getvalue())
     default_content = util.load_file(self.default_file)
     self.assertEqual('RUN=1\n', default_content)
예제 #13
0
 def test_install_drivers_rejects_invalid_config(
     self, m_debconf, cfg_accepted, install_gpgpu
 ):
     """install_drivers should raise TypeError if not given a config dict"""
     pkg_install = mock.MagicMock()
     with pytest.raises(TypeError, match=".*expected dict.*"):
         drivers.install_drivers("mystring", pkg_install_func=pkg_install)
     assert 0 == pkg_install.call_count
예제 #14
0
 def test_maybe_install_ua_tools_happy_path(self, m_which):
     """maybe_install_ua_tools installs ubuntu-advantage-tools."""
     m_which.return_value = None
     distro = mock.MagicMock()  # No errors raised
     maybe_install_ua_tools(cloud=FakeCloud(distro))
     distro.update_package_sources.assert_called_once_with()
     distro.install_packages.assert_called_once_with(
         ['ubuntu-advantage-tools'])
예제 #15
0
 def test_handle_inert(
     self, m_which, m_subp, m_debconf, cfg_accepted, install_gpgpu, config
 ):
     """Helper to reduce repetition when testing negative cases"""
     myCloud = mock.MagicMock()
     drivers.handle("ubuntu_drivers", config, myCloud, None, None)
     assert 0 == myCloud.distro.install_packages.call_count
     assert 0 == m_subp.call_count
예제 #16
0
 def test_false_disables_pipelining(self, m_write_file):
     """ensure that pipelining can be disabled with correct config"""
     cc_apt_pipelining.handle("foo", {"apt_pipelining": "false"}, None,
                              mock.MagicMock(), None)
     self.assertEqual(1, m_write_file.call_count)
     args, _ = m_write_file.call_args
     self.assertEqual(cc_apt_pipelining.DEFAULT_FILE, args[0])
     self.assertIn('Pipeline-Depth "0"', args[1])
예제 #17
0
 def test_false_disables_pipelining(self, m_write_file):
     """ensure that pipelining can be disabled with correct config"""
     cc_apt_pipelining.handle("foo", {"apt_pipelining": "false"}, None,
                              mock.MagicMock(), None)
     assert 1 == m_write_file.call_count
     args, _ = m_write_file.call_args
     assert cc_apt_pipelining.DEFAULT_FILE == args[0]
     assert 'Pipeline-Depth "0"' in args[1]
예제 #18
0
    def test_puppet_config_installs_puppet_on_true(self, m_subp, _):
        """Cloud-config with 'puppet' key installs when 'install' is True."""

        self.cloud.distro = mock.MagicMock()
        cfg = {'puppet': {'install': True}}
        cc_puppet.handle('notimportant', cfg, self.cloud, LOG, None)
        self.assertEqual([mock.call(('puppet', None))],
                         self.cloud.distro.install_packages.call_args_list)
예제 #19
0
    def test_puppet_config_installs_puppet_version(self, m_subp, _):
        """Cloud-config 'puppet' configuration can specify a version."""

        self.cloud.distro = mock.MagicMock()
        cfg = {'puppet': {'version': '3.8'}}
        cc_puppet.handle('notimportant', cfg, self.cloud, LOG, None)
        self.assertEqual([mock.call(('puppet', '3.8'))],
                         self.cloud.distro.install_packages.call_args_list)
예제 #20
0
    def test_empty_puppet_config_installs_puppet(self, m_subp, m_auto):
        """Cloud-config empty 'puppet' configuration installs latest puppet."""

        self.cloud.distro = mock.MagicMock()
        cfg = {'puppet': {}}
        cc_puppet.handle('notimportant', cfg, self.cloud, LOG, None)
        self.assertEqual([mock.call(('puppet', None))],
                         self.cloud.distro.install_packages.call_args_list)
예제 #21
0
 def test_ntp_install_no_op_with_empty_pkg_list(self, mock_subp):
     """ntp_install_client runs install_func with empty list"""
     mock_subp.which.return_value = None  # check_exe not found
     install_func = mock.MagicMock()
     cc_ntp.install_ntp_client(install_func,
                               packages=[],
                               check_exe='timesyncd')
     install_func.assert_called_once_with([])
예제 #22
0
    def test_puppet_config_installs_puppet_aio(self, m_subp, m_aio, _):
        """Cloud-config with 'puppet' key installs
        when 'install_type' is 'aio'."""

        self.cloud.distro = mock.MagicMock()
        cfg = {'puppet': {'install': True, 'install_type': 'aio'}}
        cc_puppet.handle('notimportant', cfg, self.cloud, LOG, None)
        m_aio.assert_called_with(cc_puppet.AIO_INSTALL_URL, None, None, True)
예제 #23
0
    def test_collect_logs_includes_optional_userdata(self, m_getuid):
        """collect-logs include userdata when --include-userdata is set."""
        m_getuid.return_value = 0
        log1 = self.tmp_path('cloud-init.log', self.new_root)
        write_file(log1, 'cloud-init-log')
        log2 = self.tmp_path('cloud-init-output.log', self.new_root)
        write_file(log2, 'cloud-init-output-log')
        userdata = self.tmp_path('user-data.txt', self.new_root)
        write_file(userdata, 'user-data')
        ensure_dir(self.run_dir)
        write_file(self.tmp_path('results.json', self.run_dir), 'results')
        write_file(self.tmp_path(INSTANCE_JSON_SENSITIVE_FILE, self.run_dir),
                   'sensitive')
        output_tarfile = self.tmp_path('logs.tgz')

        date = datetime.utcnow().date().strftime('%Y-%m-%d')
        date_logdir = 'cloud-init-logs-{0}'.format(date)

        version_out = '/usr/bin/cloud-init 18.2fake\n'
        expected_subp = {
            ('dpkg-query', '--show', "-f=${Version}\n", 'cloud-init'):
                '0.7fake',
            ('cloud-init', '--version'): version_out,
            ('dmesg',): 'dmesg-out\n',
            ('journalctl', '--boot=0', '-o', 'short-precise'): 'journal-out\n',
            ('tar', 'czvf', output_tarfile, date_logdir): ''
        }

        def fake_subp(cmd):
            cmd_tuple = tuple(cmd)
            if cmd_tuple not in expected_subp:
                raise AssertionError(
                    'Unexpected command provided to subp: {0}'.format(cmd))
            if cmd == ['tar', 'czvf', output_tarfile, date_logdir]:
                subp(cmd)  # Pass through tar cmd so we can check output
            return expected_subp[cmd_tuple], ''

        fake_stderr = mock.MagicMock()

        wrap_and_call(
            'cloudinit.cmd.devel.logs',
            {'subp': {'side_effect': fake_subp},
             'sys.stderr': {'new': fake_stderr},
             'CLOUDINIT_LOGS': {'new': [log1, log2]},
             'CLOUDINIT_RUN_DIR': {'new': self.run_dir},
             'USER_DATA_FILE': {'new': userdata}},
            logs.collect_logs, output_tarfile, include_userdata=True)
        # unpack the tarfile and check file contents
        subp(['tar', 'zxvf', output_tarfile, '-C', self.new_root])
        out_logdir = self.tmp_path(date_logdir, self.new_root)
        self.assertEqual(
            'user-data',
            load_file(os.path.join(out_logdir, 'user-data.txt')))
        self.assertEqual(
            'sensitive',
            load_file(os.path.join(out_logdir, 'run', 'cloud-init',
                                   INSTANCE_JSON_SENSITIVE_FILE)))
        fake_stderr.write.assert_any_call('Wrote %s\n' % output_tarfile)
예제 #24
0
 def test_ntp_install_not_needed(self, mock_subp):
     """ntp_install_client doesn't install when check_exe is found."""
     client = 'chrony'
     mock_subp.which.return_value = [client]  # check_exe found.
     install_func = mock.MagicMock()
     cc_ntp.install_ntp_client(install_func,
                               packages=[client],
                               check_exe=client)
     install_func.assert_not_called()
예제 #25
0
 def test_ntp_install(self, mock_subp):
     """ntp_install_client runs install_func when check_exe is absent."""
     mock_subp.which.return_value = None  # check_exe not found.
     install_func = mock.MagicMock()
     cc_ntp.install_ntp_client(install_func,
                               packages=['ntpx'],
                               check_exe='ntpdx')
     mock_subp.which.assert_called_with('ntpdx')
     install_func.assert_called_once_with(['ntpx'])
예제 #26
0
 def test_maybe_install_squashfuse_happy_path(self, m_container):
     """maybe_install_squashfuse logs and raises package install errors."""
     m_container.return_value = True
     distro = mock.MagicMock()  # No errors raised
     maybe_install_squashfuse(cloud=FakeCloud(distro))
     self.assertEqual([mock.call()],
                      distro.update_package_sources.call_args_list)
     self.assertEqual([mock.call(['squashfuse'])],
                      distro.install_packages.call_args_list)
 def test_maybe_install_ua_tools_raises_update_errors(self, m_which):
     """maybe_install_ua_tools logs and raises apt update errors."""
     m_which.return_value = None
     distro = mock.MagicMock()
     distro.update_package_sources.side_effect = RuntimeError(
         "Some apt error")
     with self.assertRaises(RuntimeError) as context_manager:
         maybe_install_ua_tools(cloud=FakeCloud(distro))
     self.assertEqual("Some apt error", str(context_manager.exception))
     self.assertIn("Package update failed\nTraceback", self.logs.getvalue())
예제 #28
0
    def test_puppet_config_installs_puppet_version(self, m_subp, _):
        """Cloud-config 'puppet' configuration can specify a version."""

        self.cloud.distro = mock.MagicMock()
        cfg = {"puppet": {"version": "3.8"}}
        cc_puppet.handle("notimportant", cfg, self.cloud, LOG, None)
        self.assertEqual(
            [mock.call(("puppet", "3.8"))],
            self.cloud.distro.install_packages.call_args_list,
        )
예제 #29
0
 def test_maybe_install_squashfuse_raises_update_errors(self, m_container):
     """maybe_install_squashfuse logs and raises package update errors."""
     m_container.return_value = True
     distro = mock.MagicMock()
     distro.update_package_sources.side_effect = RuntimeError(
         'Some apt error')
     with self.assertRaises(RuntimeError) as context_manager:
         maybe_install_squashfuse(cloud=FakeCloud(distro))
     self.assertEqual('Some apt error', str(context_manager.exception))
     self.assertIn('Package update failed\nTraceback', self.logs.getvalue())
예제 #30
0
 def test_maybe_install_ua_raises_install_errors(self, m_which):
     """maybe_install_ua_tools logs and raises package install errors."""
     m_which.return_value = None
     distro = mock.MagicMock()
     distro.update_package_sources.return_value = None
     distro.install_packages.side_effect = RuntimeError(
         'Some install error')
     with self.assertRaises(RuntimeError) as context_manager:
         maybe_install_ua_tools(cloud=FakeCloud(distro))
     self.assertEqual('Some install error', str(context_manager.exception))
     self.assertIn('Failed to install ubuntu-advantage-tools\n',
                   self.logs.getvalue())