def setUp(self): super(TestConfig, self).setUp() self.name = "growpart" self.paths = None self.cloud = cloud.Cloud(None, self.paths, None, None, None) self.log = logging.getLogger("TestConfig") self.args = [] self.cloud_init = None self.handle = cc_growpart.handle
def cloudify(self): # Form the needed options to cloudify our members return cloud.Cloud( self.datasource, self.paths, self.cfg, self.distro, helpers.Runners(self.paths), reporter=self.reporter, )
def setUp(self): super(TestConfig, self).setUp() self.new_root = self.tmp_dir() self.new_root = self.reRoot(root=self.new_root) for dirname in ['tmp', 'etc/apk']: util.ensure_dir(os.path.join(self.new_root, dirname)) self.paths = helpers.Paths({'templates_dir': self.new_root}) self.name = "apk-configure" self.cloud = cloud.Cloud(None, self.paths, None, None, None) self.log = logging.getLogger("TestNoConfig") self.args = []
def test_write_hostname_rhel(self, m_uses_systemd): cfg = {'hostname': 'blah', 'fqdn': 'blah.blah.blah.yahoo.com'} distro = self._fetch_distro('rhel') paths = helpers.Paths({'cloud_dir': self.tmp}) ds = None cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) cc_set_hostname.handle('cc_set_hostname', cfg, cc, LOG, []) contents = util.load_file("/etc/sysconfig/network", decode=False) n_cfg = ConfigObj(BytesIO(contents)) self.assertEqual({'HOSTNAME': 'blah.blah.blah.yahoo.com'}, dict(n_cfg))
def test_write_hostname_rhel(self, m_uses_systemd): cfg = {"hostname": "blah", "fqdn": "blah.blah.blah.yahoo.com"} distro = self._fetch_distro("rhel") paths = helpers.Paths({"cloud_dir": self.tmp}) ds = None cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) cc_set_hostname.handle("cc_set_hostname", cfg, cc, LOG, []) contents = util.load_file("/etc/sysconfig/network", decode=False) n_cfg = ConfigObj(BytesIO(contents)) self.assertEqual({"HOSTNAME": "blah.blah.blah.yahoo.com"}, dict(n_cfg))
def _get_cloud(self, distro): self.patchUtils(self.new_root) self.patchOS(self.new_root) paths = helpers.Paths({}) cls = distros.fetch(distro) d = cls(distro, {}, paths) ds = DataSourceNoCloud.DataSourceNoCloud({}, d, paths) cc = cloud.Cloud(ds, paths, {}, d, None) return cc
def test_write_hostname_sles(self, m_uses_systemd): cfg = { 'hostname': 'blah.blah.blah.suse.com', } distro = self._fetch_distro('sles') paths = helpers.Paths({'cloud_dir': self.tmp}) ds = None cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) cc_set_hostname.handle('cc_set_hostname', cfg, cc, LOG, []) contents = util.load_file(distro.hostname_conf_fn) self.assertEqual('blah', contents.strip())
def test_write_hostname_sles(self, m_uses_systemd): cfg = { "hostname": "blah.blah.blah.suse.com", } distro = self._fetch_distro("sles") paths = helpers.Paths({"cloud_dir": self.tmp}) ds = None cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) cc_set_hostname.handle("cc_set_hostname", cfg, cc, LOG, []) contents = util.load_file(distro.hostname_conf_fn) self.assertEqual("blah", contents.strip())
def test_write_hostname_debian(self): cfg = { 'hostname': 'blah.blah.blah.yahoo.com', } distro = self._fetch_distro('debian') paths = helpers.Paths({'cloud_dir': self.tmp}) ds = None cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) cc_set_hostname.handle('cc_set_hostname', cfg, cc, LOG, []) contents = util.load_file("/etc/hostname") self.assertEqual('blah', contents.strip())
def test_write_hostname_sles(self): cfg = { 'hostname': 'blah.blah.blah.suse.com', } distro = self._fetch_distro('sles') paths = helpers.Paths({}) ds = None cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) cc_set_hostname.handle('cc_set_hostname', cfg, cc, LOG, []) contents = util.load_file("/etc/HOSTNAME") self.assertEqual('blah', contents.strip())
def test_write_hostname_debian(self): cfg = { "hostname": "blah", "fqdn": "blah.blah.blah.yahoo.com", } distro = self._fetch_distro("debian") paths = helpers.Paths({"cloud_dir": self.tmp}) ds = None cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) cc_set_hostname.handle("cc_set_hostname", cfg, cc, LOG, []) contents = util.load_file("/etc/hostname") self.assertEqual("blah", contents.strip())
def setUp(self): super(TestConfig, self).setUp() self.name = "growpart" self.paths = None self.cloud = cloud.Cloud(None, self.paths, None, None, None) self.log = logging.getLogger("TestConfig") self.args = [] self.cloud_init = None self.handle = cc_growpart.handle self.tmppath = '/tmp/cloudinit-test-file' self.tmpdir = os.scandir('/tmp') self.tmpfile = open(self.tmppath, 'w')
def test_write_hostname_rhel(self): cfg = { 'hostname': 'blah.blah.blah.yahoo.com', } distro = self._fetch_distro('rhel') paths = helpers.Paths({}) ds = None cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) cc_set_hostname.handle('cc_set_hostname', cfg, cc, LOG, []) contents = util.load_file("/etc/sysconfig/network") n_cfg = ConfigObj(StringIO(contents)) self.assertEquals({'HOSTNAME': 'blah.blah.blah.yahoo.com'}, dict(n_cfg))
def setUp(self): super(TestConfig, self).setUp() self.name = "growpart" self.paths = None self.cloud = cloud.Cloud(None, self.paths, None, None, None) self.log = logging.getLogger("TestConfig") self.args = [] os.environ = {} self.cloud_init = None self.handle = cc_growpart.handle # Order must be correct self.mocker.order()
def test_resolv_conf_invalid_resolve_conf_fn(self, m_render_to_file): ds = None distro = self._fetch_distro('rhel', self.cfg) paths = helpers.Paths({'cloud_dir': self.tmp}) cc = cloud.Cloud(ds, paths, {}, distro, None) cc.distro.resolve_conf_fn = 'bla' self.logs.truncate(0) self.call_resolv_conf_handler('rhel', self.cfg, cc) self.assertIn('No template found, not rendering resolve configs', self.logs.getvalue()) assert [mock.call(mock.ANY, '/etc/resolv.conf', mock.ANY)] not in m_render_to_file.call_args_list
def test_localhost_default_hostname(self, get_hostname): """ No hostname set. Default value returned is localhost, but we shouldn't write it in /etc/hostname """ distro = self._fetch_distro("debian") paths = helpers.Paths({"cloud_dir": self.tmp}) ds = DataSourceNone.DataSourceNone({}, None, paths) cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) util.write_file("/etc/hostname", "") cc_set_hostname.handle("cc_set_hostname", {}, cc, LOG, []) contents = util.load_file("/etc/hostname") self.assertEqual("", contents.strip())
def test_localhost_user_given_hostname(self, get_hostname): """ User set hostname is localhost. We should write it in /etc/hostname """ distro = self._fetch_distro("debian") paths = helpers.Paths({"cloud_dir": self.tmp}) ds = DataSourceNone.DataSourceNone({}, None, paths) cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) # user-provided localhost should not be ignored util.write_file("/etc/hostname", "") cc_set_hostname.handle("cc_set_hostname", {"hostname": "localhost"}, cc, LOG, []) contents = util.load_file("/etc/hostname") self.assertEqual("localhost", contents.strip())
def test_photon_hostname(self, m_subp): cfg1 = { "hostname": "photon", "prefer_fqdn_over_hostname": True, "fqdn": "test1.vmware.com", } cfg2 = { "hostname": "photon", "prefer_fqdn_over_hostname": False, "fqdn": "test2.vmware.com", } ds = None m_subp.return_value = (None, None) distro = self._fetch_distro("photon", cfg1) paths = helpers.Paths({"cloud_dir": self.tmp}) cc = cloud.Cloud(ds, paths, {}, distro, None) for c in [cfg1, cfg2]: cc_set_hostname.handle("cc_set_hostname", c, cc, LOG, []) print("\n", m_subp.call_args_list) if c["prefer_fqdn_over_hostname"]: assert [ mock.call( ["hostnamectl", "set-hostname", c["fqdn"]], capture=True, ) ] in m_subp.call_args_list assert [ mock.call( ["hostnamectl", "set-hostname", c["hostname"]], capture=True, ) ] not in m_subp.call_args_list else: assert [ mock.call( ["hostnamectl", "set-hostname", c["hostname"]], capture=True, ) ] in m_subp.call_args_list assert [ mock.call( ["hostnamectl", "set-hostname", c["fqdn"]], capture=True, ) ] not in m_subp.call_args_list
def setUp(self): super(TestConfig, self).setUp() self.name = "ca-certs" self.paths = None self.cloud = cloud.Cloud(None, self.paths, None, None, None) self.log = logging.getLogger("TestNoConfig") self.args = [] self.mocks = ExitStack() self.addCleanup(self.mocks.close) # Mock out the functions that actually modify the system self.mock_add = self.mocks.enter_context( mock.patch.object(cc_ca_certs, 'add_ca_certs')) self.mock_update = self.mocks.enter_context( mock.patch.object(cc_ca_certs, 'update_ca_certs')) self.mock_remove = self.mocks.enter_context( mock.patch.object(cc_ca_certs, 'remove_default_ca_certs'))
def test_write_etc_hosts_suse_template(self): cfg = { 'manage_etc_hosts': 'template', 'hostname': 'cloud-init.test.us' } shutil.copytree('templates', '%s/etc/cloud/templates' % self.tmp) distro = self._fetch_distro('sles') paths = helpers.Paths({}) paths.template_tpl = '%s' % self.tmp + '/etc/cloud/templates/%s.tmpl' ds = None cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) cc_update_etc_hosts.handle('test', cfg, cc, LOG, []) contents = util.load_file('%s/etc/hosts' % self.tmp) if '127.0.1.1 cloud-init.test.us cloud-init' not in contents: self.assertIsNone('No entry for 127.0.1.1 in etc/hosts') if '::1 cloud-init.test.us cloud-init' not in contents: self.assertIsNone('No entry for 127.0.0.1 in etc/hosts')
def setUp(self): super(TestConfig, self).setUp() self.name = "ca-certs" self.paths = None self.cloud = cloud.Cloud(None, self.paths, None, None, None) self.log = logging.getLogger("TestNoConfig") self.args = [] # Mock out the functions that actually modify the system self.mock_add = self.mocker.replace(cc_ca_certs.add_ca_certs, passthrough=False) self.mock_update = self.mocker.replace(cc_ca_certs.update_ca_certs, passthrough=False) self.mock_remove = self.mocker.replace( cc_ca_certs.remove_default_ca_certs, passthrough=False) # Order must be correct self.mocker.order()
def test_error_on_distro_set_hostname_errors(self): """Raise SetHostnameError on exceptions from distro.set_hostname.""" distro = self._fetch_distro('debian') def set_hostname_error(hostname, fqdn): raise Exception("OOPS on: %s" % fqdn) distro.set_hostname = set_hostname_error paths = helpers.Paths({'cloud_dir': self.tmp}) ds = None cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) with self.assertRaises(cc_set_hostname.SetHostnameError) as ctx_mgr: cc_set_hostname.handle( 'somename', {'hostname': 'hostname1.me.com'}, cc, LOG, []) self.assertEqual( 'Failed to set the hostname to hostname1.me.com (hostname1):' ' OOPS on: hostname1.me.com', str(ctx_mgr.exception))
def get_cloud(distro=None, paths=None, sys_cfg=None, metadata=None): """Obtain a "cloud" that can be used for testing. Modules take a 'cloud' parameter to call into things that are datasource/distro specific. In most cases, the specifics of this cloud implementation aren't needed to test the module, so provide a fake datasource/distro with stubbed calls to methods that may attempt to read/write files or shell out. If a specific distro is needed, it can be passed in as the distro parameter. """ paths = paths or helpers.Paths({}) sys_cfg = sys_cfg or {} cls = distros.fetch(distro) if distro else MockDistro mydist = cls(distro, sys_cfg, paths) myds = DataSourceTesting(sys_cfg, mydist, paths) if metadata: myds.metadata.update(metadata) if paths: paths.datasource = myds return cloud.Cloud(myds, paths, sys_cfg, mydist, None)
def test_write_etc_hosts_suse_template(self): cfg = { "manage_etc_hosts": "template", "hostname": "cloud-init.test.us", } shutil.copytree( t_help.cloud_init_project_dir("templates"), "%s/etc/cloud/templates" % self.tmp, ) distro = self._fetch_distro("sles") paths = helpers.Paths({}) paths.template_tpl = "%s" % self.tmp + "/etc/cloud/templates/%s.tmpl" ds = None cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) cc_update_etc_hosts.handle("test", cfg, cc, LOG, []) contents = util.load_file("%s/etc/hosts" % self.tmp) if "127.0.1.1 cloud-init.test.us cloud-init" not in contents: self.assertIsNone("No entry for 127.0.1.1 in etc/hosts") if "::1 cloud-init.test.us cloud-init" not in contents: self.assertIsNone("No entry for 127.0.0.1 in etc/hosts")
def tmp_cloud(self, distro, sys_cfg=None, metadata=None): """Create a cloud with tmp working directory paths. @param distro: Name of the distro to attach to the cloud. @param metadata: Optional metadata to set on the datasource. @return: The built cloud instance. """ self.new_root = self.tmp_dir() if not sys_cfg: sys_cfg = {} tmp_paths = {} for var in ['templates_dir', 'run_dir', 'cloud_dir']: tmp_paths[var] = self.tmp_path(var, dir=self.new_root) util.ensure_dir(tmp_paths[var]) self.paths = ch.Paths(tmp_paths) cls = distros.fetch(distro) mydist = cls(distro, sys_cfg, self.paths) myds = DataSourceNone.DataSourceNone(sys_cfg, mydist, self.paths) if metadata: myds.metadata.update(metadata) return cloud.Cloud(myds, self.paths, sys_cfg, mydist, None)
def test_write_etc_hosts_suse_localhost(self): cfg = { "manage_etc_hosts": "localhost", "hostname": "cloud-init.test.us", } os.makedirs("%s/etc/" % self.tmp) hosts_content = "192.168.1.1 blah.blah.us blah\n" fout = open("%s/etc/hosts" % self.tmp, "w") fout.write(hosts_content) fout.close() distro = self._fetch_distro("sles") distro.hosts_fn = "%s/etc/hosts" % self.tmp paths = helpers.Paths({}) ds = None cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) cc_update_etc_hosts.handle("test", cfg, cc, LOG, []) contents = util.load_file("%s/etc/hosts" % self.tmp) if "127.0.1.1\tcloud-init.test.us\tcloud-init" not in contents: self.assertIsNone("No entry for 127.0.1.1 in etc/hosts") if "192.168.1.1\tblah.blah.us\tblah" not in contents: self.assertIsNone("Default etc/hosts content modified")
def test_write_etc_hosts_suse_localhost(self): cfg = { 'manage_etc_hosts': 'localhost', 'hostname': 'cloud-init.test.us' } os.makedirs('%s/etc/' % self.tmp) hosts_content = '192.168.1.1 blah.blah.us blah\n' fout = open('%s/etc/hosts' % self.tmp, 'w') fout.write(hosts_content) fout.close() distro = self._fetch_distro('sles') distro.hosts_fn = '%s/etc/hosts' % self.tmp paths = helpers.Paths({}) ds = None cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) cc_update_etc_hosts.handle('test', cfg, cc, LOG, []) contents = util.load_file('%s/etc/hosts' % self.tmp) if '127.0.1.1\tcloud-init.test.us\tcloud-init' not in contents: self.assertIsNone('No entry for 127.0.1.1 in etc/hosts') if '192.168.1.1\tblah.blah.us\tblah' not in contents: self.assertIsNone('Default etc/hosts content modified')
def test_multiple_calls_skips_unchanged_hostname(self): """Only new hostname or fqdn values will generate a hostname call.""" distro = self._fetch_distro('debian') paths = helpers.Paths({'cloud_dir': self.tmp}) ds = None cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) cc_set_hostname.handle('cc_set_hostname', {'hostname': 'hostname1.me.com'}, cc, LOG, []) contents = util.load_file("/etc/hostname") self.assertEqual('hostname1', contents.strip()) cc_set_hostname.handle('cc_set_hostname', {'hostname': 'hostname1.me.com'}, cc, LOG, []) self.assertIn('DEBUG: No hostname changes. Skipping set-hostname\n', self.logs.getvalue()) cc_set_hostname.handle('cc_set_hostname', {'hostname': 'hostname2.me.com'}, cc, LOG, []) contents = util.load_file("/etc/hostname") self.assertEqual('hostname2', contents.strip()) self.assertIn( 'Non-persistently setting the system hostname to hostname2', self.logs.getvalue())
def test_photon_hostname(self, m_subp): cfg1 = { 'hostname': 'photon', 'prefer_fqdn_over_hostname': True, 'fqdn': 'test1.vmware.com', } cfg2 = { 'hostname': 'photon', 'prefer_fqdn_over_hostname': False, 'fqdn': 'test2.vmware.com', } ds = None m_subp.return_value = (None, None) distro = self._fetch_distro('photon', cfg1) paths = helpers.Paths({'cloud_dir': self.tmp}) cc = cloud.Cloud(ds, paths, {}, distro, None) for c in [cfg1, cfg2]: cc_set_hostname.handle('cc_set_hostname', c, cc, LOG, []) print("\n", m_subp.call_args_list) if c['prefer_fqdn_over_hostname']: assert [ mock.call(['hostnamectl', 'set-hostname', c['fqdn']], capture=True) ] in m_subp.call_args_list assert [ mock.call(['hostnamectl', 'set-hostname', c['hostname']], capture=True) ] not in m_subp.call_args_list else: assert [ mock.call(['hostnamectl', 'set-hostname', c['hostname']], capture=True) ] in m_subp.call_args_list assert [ mock.call(['hostnamectl', 'set-hostname', c['fqdn']], capture=True) ] not in m_subp.call_args_list
def test_photon_hostname(self, m_uses_systemd): cfg1 = { 'hostname': 'photon', 'prefer_fqdn_over_hostname': True, 'fqdn': 'test1.vmware.com', } cfg2 = { 'hostname': 'photon', 'prefer_fqdn_over_hostname': False, 'fqdn': 'test2.vmware.com', } ds = None distro = self._fetch_distro('photon', cfg1) paths = helpers.Paths({'cloud_dir': self.tmp}) cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) for c in [cfg1, cfg2]: cc_set_hostname.handle('cc_set_hostname', c, cc, LOG, []) contents = util.load_file(distro.hostname_conf_fn, decode=True) if c['prefer_fqdn_over_hostname']: self.assertEqual(contents.strip(), c['fqdn']) else: self.assertEqual(contents.strip(), c['hostname'])