def test_get_locale_ubuntu(self, m_locale): """Test ubuntu distro returns locale set to C.UTF-8""" m_locale.return_value = 'C.UTF-8' cls = distros.fetch("ubuntu") d = cls("ubuntu", {}, None) locale = d.get_locale() self.assertEqual('C.UTF-8', locale)
def _get_cloud(self, distro): paths = helpers.Paths({}) cls = distros.fetch(distro) mydist = cls(distro, {}, paths) myds = DataSourceNone.DataSourceNone({}, mydist, paths) paths.datasource = myds return cloud.Cloud(myds, paths, {}, mydist, None)
def test_systemd_in_use(self): cls = distros.fetch("ubuntu") d = cls("ubuntu", {}, None) self.patchOS(self.tmp) self.patchUtils(self.tmp) os.makedirs('/run/systemd/system') self.assertTrue(d.uses_systemd())
def _get_cloud(self, distro): cls = distros.fetch(distro) paths = helpers.Paths({}) d = cls(distro, {}, paths) ds = DataSourceNoCloud.DataSourceNoCloud({}, d, paths) cc = cloud.Cloud(ds, paths, {}, d, None) return cc
def _get_cloud(self, distro): self.patchUtils(self.new_root) paths = helpers.Paths({'templates_dir': self.new_root}) cls = distros.fetch(distro) mydist = cls(distro, {}, paths) myds = DataSourceNone.DataSourceNone({}, mydist, paths) return cloud.Cloud(myds, paths, {}, mydist, None)
def _get_cloud(self, distro): self.patchUtils(self.new_root) paths = helpers.Paths({'scripts': self.new_root}) cls = distros.fetch(distro) mydist = cls(distro, {}, paths) myds = DataSourceNone.DataSourceNone({}, mydist, paths) paths.datasource = myds return cloud.Cloud(myds, paths, {}, mydist, None)
def _get_distro(self, dname, renderers=None): cls = distros.fetch(dname) cfg = settings.CFG_BUILTIN cfg['system_info']['distro'] = dname if renderers: cfg['system_info']['network'] = {'renderers': renderers} paths = helpers.Paths({}) return cls(dname, cfg.get('system_info'), paths)
def _get_cloud(self, distro, metadata=None): paths = helpers.Paths({}) cls = distros.fetch(distro) ubuntu_distro = cls(distro, {}, paths) ds = DataSourceNone.DataSourceNone({}, ubuntu_distro, paths) if metadata: ds.metadata = metadata return cloud.Cloud(ds, paths, {}, ubuntu_distro, None)
def test_systemd_symlink(self): cls = distros.fetch("ubuntu") d = cls("ubuntu", {}, None) self.patchOS(self.tmp) self.patchUtils(self.tmp) os.makedirs('/run/systemd') os.symlink('/', '/run/systemd/system') self.assertFalse(d.uses_systemd())
def _get_cloud(self, distro, metadata=None): self.patchUtils(self.new_root) paths = helpers.Paths({}) cls = distros.fetch(distro) mydist = cls(distro, {}, paths) myds = DataSourceNone.DataSourceNone({}, mydist, paths) if metadata: myds.metadata.update(metadata) return cloud.Cloud(myds, paths, {}, mydist, None)
def _get_cloud(self, distro): self.patchUtils(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 _make_distro(self, dtype, def_user=None): cfg = dict(settings.CFG_BUILTIN) cfg['system_info']['distro'] = dtype paths = helpers.Paths(cfg['system_info']['paths']) distro_cls = distros.fetch(dtype) if def_user: cfg['system_info']['default_user'] = def_user.copy() distro = distro_cls(dtype, cfg['system_info'], paths) return distro
def test_sudoers_ensure_new(self): cls = distros.fetch("ubuntu") d = cls("ubuntu", {}, None) self.patchOS(self.tmp) self.patchUtils(self.tmp) d.ensure_sudo_dir("/b") contents = util.load_file("/etc/sudoers") self.assertIn("includedir /b", contents) self.assertTrue(os.path.isdir("/b"))
def test_expire_passwd_freebsd_uses_pw_command(self): """Test FreeBSD.expire_passwd uses the pw command.""" cls = distros.fetch("freebsd") d = cls("freebsd", {}, None) with mock.patch("cloudinit.subp.subp") as m_subp: d.expire_passwd("myuser") m_subp.assert_called_once_with( ["pw", "usermod", "myuser", "-p", "01-Jan-1970"] )
def _make_distro(self, dtype, def_user=None): cfg = dict(settings.CFG_BUILTIN) cfg["system_info"]["distro"] = dtype paths = helpers.Paths(cfg["system_info"]["paths"]) distro_cls = distros.fetch(dtype) if def_user: cfg["system_info"]["default_user"] = def_user.copy() distro = distro_cls(dtype, cfg["system_info"], paths) return distro
def _get_cloud(self, distro, sys_cfg=None): self.new_root = self.reRoot(root=self.new_root) paths = helpers.Paths({'templates_dir': self.new_root}) cls = distros.fetch(distro) if not sys_cfg: sys_cfg = {} mydist = cls(distro, sys_cfg, paths) myds = DataSourceNone.DataSourceNone(sys_cfg, mydist, paths) return cloud.Cloud(myds, paths, sys_cfg, mydist, None)
def _write_load_sudoers(self, _user, rules): cls = distros.fetch("ubuntu") d = cls("ubuntu", {}, None) os.makedirs(os.path.join(self.tmp, "etc")) os.makedirs(os.path.join(self.tmp, "etc", 'sudoers.d')) self.patchOS(self.tmp) self.patchUtils(self.tmp) d.write_sudo_rules("harlowja", rules) contents = util.load_file(d.ci_sudoers_fn) return contents
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_alpine_delay(self): # alpine takes delay in seconds. cls = distros.fetch('alpine') paths = helpers.Paths({}) alpine = cls('alpine', {}, paths) cfg = {'power_state': {'mode': 'poweroff', 'delay': ''}} for delay, value in (('now', 0), ("+1", 60), ("+30", 1800)): cfg['power_state']['delay'] = delay ret = psc.load_power_state(cfg, alpine) self.assertEqual('-d', ret[0][1]) self.assertEqual(str(value), ret[0][2])
def setUp(self): super(DataSourceCloudSigmaTest, self).setUp() self.paths = helpers.Paths({'run_dir': self.tmp_dir()}) self.add_patch(DS_PATH + '.is_running_in_cloudsigma', "m_is_container", return_value=True) distro_cls = distros.fetch("ubuntu") distro = distro_cls("ubuntu", cfg={}, paths=self.paths) self.datasource = DataSourceCloudSigma.DataSourceCloudSigma( sys_cfg={}, distro=distro, paths=self.paths) self.datasource.cepko = CepkoMock(SERVER_CONTEXT)
def test_alpine_delay(self): # alpine takes delay in seconds. cls = distros.fetch("alpine") paths = helpers.Paths({}) alpine = cls("alpine", {}, paths) cfg = {"power_state": {"mode": "poweroff", "delay": ""}} for delay, value in (("now", 0), ("+1", 60), ("+30", 1800)): cfg["power_state"]["delay"] = delay ret = psc.load_power_state(cfg, alpine) self.assertEqual("-d", ret[0][1]) self.assertEqual(str(value), ret[0][2])
def test_sudoers_ensure_append(self): cls = distros.fetch("ubuntu") d = cls("ubuntu", {}, None) self.patchOS(self.tmp) self.patchUtils(self.tmp) util.write_file("/etc/sudoers", "josh, josh\n") d.ensure_sudo_dir("/b") contents = util.load_file("/etc/sudoers") self.assertIn("includedir /b", contents) self.assertTrue(os.path.isdir("/b")) self.assertIn("josh", contents) self.assertEqual(2, contents.count("josh"))
def test_sudoers_ensure_only_one_includedir(self): cls = distros.fetch("ubuntu") d = cls("ubuntu", {}, None) self.patchOS(self.tmp) self.patchUtils(self.tmp) for char in ["#", "@"]: util.write_file("/etc/sudoers", "{}includedir /b".format(char)) d.ensure_sudo_dir("/b") contents = util.load_file("/etc/sudoers") self.assertIn("includedir /b", contents) self.assertTrue(os.path.isdir("/b")) self.assertEqual(1, contents.count("includedir /b"))
def test_sudoers_ensure_append(self): cls = distros.fetch("ubuntu") d = cls("ubuntu", {}, None) self.patchOS(self.tmp) self.patchUtils(self.tmp) util.write_file("/etc/sudoers", "josh, josh\n") d.ensure_sudo_dir("/b") contents = util.load_file("/etc/sudoers") self.assertIn("includedir /b", contents) self.assertTrue(os.path.isdir("/b")) self.assertIn("josh", contents) self.assertEquals(2, contents.count("josh"))
def _get_distro(dtype, system_info=None): """Return a Distro class of distro 'dtype'. cfg is format of CFG_BUILTIN['system_info']. example: _get_distro("debian") """ if system_info is None: system_info = copy.deepcopy(settings.CFG_BUILTIN["system_info"]) system_info["distro"] = dtype paths = helpers.Paths(system_info["paths"]) distro_cls = distros.fetch(dtype) return distro_cls(dtype, system_info, paths)
def distro(self): if not self._distro: # Try to find the right class to use system_config = self._extract_cfg('system') distro_name = system_config.pop('distro', 'ubuntu') distro_cls = distros.fetch(distro_name) LOG.debug("Using distro class %s", distro_cls) self._distro = distro_cls(distro_name, system_config, self.paths) # If we have an active datasource we need to adjust # said datasource and move its distro/system config # from whatever it was to a new set... if self.datasource is not NULL_DATA_SOURCE: self.datasource.distro = self._distro self.datasource.sys_cfg = system_config return self._distro
def distro(self): if not self._distro: # Try to find the right class to use system_config = self._extract_cfg("system") distro_name = system_config.pop("distro", "ubuntu") distro_cls = distros.fetch(distro_name) LOG.debug("Using distro class %s", distro_cls) self._distro = distro_cls(distro_name, system_config, self.paths) # If we have an active datasource we need to adjust # said datasource and move its distro/system config # from whatever it was to a new set... if self.datasource is not NULL_DATA_SOURCE: self.datasource.distro = self._distro self.datasource.sys_cfg = self.cfg return self._distro
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 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 _get_distro(self, dname): cls = distros.fetch(dname) cfg = settings.CFG_BUILTIN cfg['system_info']['distro'] = dname paths = helpers.Paths({}) return cls(dname, cfg, paths)
def _fetch_distro(self, kind, conf=None): cls = distros.fetch(kind) paths = helpers.Paths({"cloud_dir": self.tmp}) conf = {} if conf is None else conf return cls(kind, conf, paths)
def fetch_cloud(self, distro_kind): cls = distros.fetch(distro_kind) paths = helpers.Paths({}) distro = cls(distro_kind, {}, paths) ds = DataSourceNone.DataSourceNone({}, distro, paths, None) return cloud.Cloud(ds, paths, {}, distro, None)
def test_systemd_not_in_use(self): cls = distros.fetch("ubuntu") d = cls("ubuntu", {}, None) self.patchOS(self.tmp) self.patchUtils(self.tmp) self.assertFalse(d.uses_systemd())
def _fetch_distro(self, kind): cls = distros.fetch(kind) paths = helpers.Paths({'cloud_dir': self.tmp}) return cls(kind, {}, paths)
def test_get_locale_rhel(self): """Test rhel distro returns NotImplementedError exception""" cls = distros.fetch("rhel") d = cls("rhel", {}, None) with self.assertRaises(NotImplementedError): d.get_locale()
def handle_args(name, args): if not args.directory.endswith("/"): args.directory += "/" if not os.path.isdir(args.directory): os.makedirs(args.directory) if args.debug: log.setupBasicLogging(level=log.DEBUG) else: log.setupBasicLogging(level=log.WARN) if args.mac: known_macs = {} for item in args.mac: iface_name, iface_mac = item.split(",", 1) known_macs[iface_mac] = iface_name else: known_macs = None net_data = args.network_data.read() if args.kind == "eni": pre_ns = eni.convert_eni_data(net_data) elif args.kind == "yaml": pre_ns = yaml.load(net_data) if 'network' in pre_ns: pre_ns = pre_ns.get('network') if args.debug: sys.stderr.write('\n'.join( ["Input YAML", yaml.dump(pre_ns, default_flow_style=False, indent=4), ""])) elif args.kind == 'network_data.json': pre_ns = openstack.convert_net_json( json.loads(net_data), known_macs=known_macs) elif args.kind == 'azure-imds': pre_ns = azure.parse_network_config(json.loads(net_data)) elif args.kind == 'vmware-imc': config = ovf.Config(ovf.ConfigFile(args.network_data.name)) pre_ns = ovf.get_network_config_from_conf(config, False) ns = network_state.parse_net_config_data(pre_ns) if not ns: raise RuntimeError("No valid network_state object created from" "input data") if args.debug: sys.stderr.write('\n'.join([ "", "Internal State", yaml.dump(ns, default_flow_style=False, indent=4), ""])) distro_cls = distros.fetch(args.distro) distro = distro_cls(args.distro, {}, None) config = {} if args.output_kind == "eni": r_cls = eni.Renderer config = distro.renderer_configs.get('eni') elif args.output_kind == "netplan": r_cls = netplan.Renderer config = distro.renderer_configs.get('netplan') # don't run netplan generate/apply config['postcmds'] = False # trim leading slash config['netplan_path'] = config['netplan_path'][1:] else: r_cls = sysconfig.Renderer config = distro.renderer_configs.get('sysconfig') r = r_cls(config=config) sys.stderr.write(''.join([ "Read input format '%s' from '%s'.\n" % ( args.kind, args.network_data.name), "Wrote output format '%s' to '%s'\n" % ( args.output_kind, args.directory)]) + "\n") r.render_network_state(network_state=ns, target=args.directory)
def _fetch_distro(self, kind): cls = distros.fetch(kind) paths = helpers.Paths({}) return cls(kind, {}, paths)
class TestPackageCommand: distro = distros.fetch("debian")("debian", {}, None) @mock.patch("cloudinit.distros.debian.Distro._apt_lock_available", return_value=True) def test_simple_command(self, m_apt_avail, m_subp, m_which): self.distro.package_command('update') apt_args = [APT_GET_WRAPPER['command']] apt_args.extend(APT_GET_COMMAND) apt_args.append('update') expected_call = { 'args': apt_args, 'capture': False, 'env': {'DEBIAN_FRONTEND': 'noninteractive'}, } assert m_subp.call_args == mock.call(**expected_call) @mock.patch("cloudinit.distros.debian.Distro._apt_lock_available", side_effect=[False, False, True]) @mock.patch("cloudinit.distros.debian.time.sleep") def test_wait_for_lock(self, m_sleep, m_apt_avail, m_subp, m_which): self.distro._wait_for_apt_command("stub", {"args": "stub2"}) assert m_sleep.call_args_list == [mock.call(1), mock.call(1)] assert m_subp.call_args_list == [mock.call(args='stub2')] @mock.patch("cloudinit.distros.debian.Distro._apt_lock_available", return_value=False) @mock.patch("cloudinit.distros.debian.time.sleep") @mock.patch("cloudinit.distros.debian.time.time", side_effect=count()) def test_lock_wait_timeout( self, m_time, m_sleep, m_apt_avail, m_subp, m_which ): with pytest.raises(TimeoutError): self.distro._wait_for_apt_command("stub", "stub2", timeout=5) assert m_subp.call_args_list == [] @mock.patch("cloudinit.distros.debian.Distro._apt_lock_available", side_effect=cycle([True, False])) @mock.patch("cloudinit.distros.debian.time.sleep") def test_lock_exception_wait(self, m_sleep, m_apt_avail, m_subp, m_which): exception = subp.ProcessExecutionError( exit_code=100, stderr="Could not get apt lock" ) m_subp.side_effect = [exception, exception, "return_thing"] ret = self.distro._wait_for_apt_command("stub", {"args": "stub2"}) assert ret == "return_thing" @mock.patch("cloudinit.distros.debian.Distro._apt_lock_available", side_effect=cycle([True, False])) @mock.patch("cloudinit.distros.debian.time.sleep") @mock.patch("cloudinit.distros.debian.time.time", side_effect=count()) def test_lock_exception_timeout( self, m_time, m_sleep, m_apt_avail, m_subp, m_which ): m_subp.side_effect = subp.ProcessExecutionError( exit_code=100, stderr="Could not get apt lock" ) with pytest.raises(TimeoutError): self.distro._wait_for_apt_command( "stub", {"args": "stub2"}, timeout=5 )
def handle_args(name, args): if not args.directory.endswith("/"): args.directory += "/" if not os.path.isdir(args.directory): os.makedirs(args.directory) if args.debug: log.setupBasicLogging(level=log.DEBUG) else: log.setupBasicLogging(level=log.WARN) if args.mac: known_macs = {} for item in args.mac: iface_name, iface_mac = item.split(",", 1) known_macs[iface_mac] = iface_name else: known_macs = None net_data = args.network_data.read() if args.kind == "eni": pre_ns = eni.convert_eni_data(net_data) elif args.kind == "yaml": pre_ns = safeyaml.load(net_data) if 'network' in pre_ns: pre_ns = pre_ns.get('network') if args.debug: sys.stderr.write('\n'.join( ["Input YAML", safeyaml.dumps(pre_ns), ""])) elif args.kind == 'network_data.json': pre_ns = openstack.convert_net_json( json.loads(net_data), known_macs=known_macs) elif args.kind == 'azure-imds': pre_ns = azure.parse_network_config(json.loads(net_data)) elif args.kind == 'vmware-imc': config = ovf.Config(ovf.ConfigFile(args.network_data.name)) pre_ns = ovf.get_network_config_from_conf(config, False) ns = network_state.parse_net_config_data(pre_ns) if args.debug: sys.stderr.write('\n'.join( ["", "Internal State", safeyaml.dumps(ns), ""])) distro_cls = distros.fetch(args.distro) distro = distro_cls(args.distro, {}, None) config = {} if args.output_kind == "eni": r_cls = eni.Renderer config = distro.renderer_configs.get('eni') elif args.output_kind == "netplan": r_cls = netplan.Renderer config = distro.renderer_configs.get('netplan') # don't run netplan generate/apply config['postcmds'] = False # trim leading slash config['netplan_path'] = config['netplan_path'][1:] # enable some netplan features config['features'] = ['dhcp-use-domains', 'ipv6-mtu'] elif args.output_kind == "networkd": r_cls = networkd.Renderer config = distro.renderer_configs.get('networkd') elif args.output_kind == "sysconfig": r_cls = sysconfig.Renderer config = distro.renderer_configs.get('sysconfig') else: raise RuntimeError("Invalid output_kind") r = r_cls(config=config) sys.stderr.write(''.join([ "Read input format '%s' from '%s'.\n" % ( args.kind, args.network_data.name), "Wrote output format '%s' to '%s'\n" % ( args.output_kind, args.directory)]) + "\n") r.render_network_state(network_state=ns, target=args.directory)
def setUp(self): super(TestLoadPowerState, self).setUp() cls = distros.fetch("ubuntu") paths = helpers.Paths({}) self.dist = cls("ubuntu", {}, paths)
def handle_args(name, args): if not args.directory.endswith("/"): args.directory += "/" if not os.path.isdir(args.directory): os.makedirs(args.directory) if args.debug: log.setupBasicLogging(level=log.DEBUG) else: log.setupBasicLogging(level=log.WARN) if args.mac: known_macs = {} for item in args.mac: iface_name, iface_mac = item.split(",", 1) known_macs[iface_mac] = iface_name else: known_macs = None net_data = args.network_data.read() if args.kind == "eni": pre_ns = eni.convert_eni_data(net_data) ns = network_state.parse_net_config_data(pre_ns) elif args.kind == "yaml": pre_ns = yaml.load(net_data) if 'network' in pre_ns: pre_ns = pre_ns.get('network') if args.debug: sys.stderr.write('\n'.join( ["Input YAML", yaml.dump(pre_ns, default_flow_style=False, indent=4), ""])) ns = network_state.parse_net_config_data(pre_ns) elif args.kind == 'network_data.json': pre_ns = openstack.convert_net_json( json.loads(net_data), known_macs=known_macs) ns = network_state.parse_net_config_data(pre_ns) elif args.kind == 'azure-imds': pre_ns = azure.parse_network_config(json.loads(net_data)) ns = network_state.parse_net_config_data(pre_ns) if not ns: raise RuntimeError("No valid network_state object created from" "input data") if args.debug: sys.stderr.write('\n'.join([ "", "Internal State", yaml.dump(ns, default_flow_style=False, indent=4), ""])) distro_cls = distros.fetch(args.distro) distro = distro_cls(args.distro, {}, None) config = {} if args.output_kind == "eni": r_cls = eni.Renderer config = distro.renderer_configs.get('eni') elif args.output_kind == "netplan": r_cls = netplan.Renderer config = distro.renderer_configs.get('netplan') else: r_cls = sysconfig.Renderer config = distro.renderer_configs.get('sysconfig') r = r_cls(config=config) sys.stderr.write(''.join([ "Read input format '%s' from '%s'.\n" % ( args.kind, args.network_data.name), "Wrote output format '%s' to '%s'\n" % ( args.output_kind, args.directory)]) + "\n") r.render_network_state(network_state=ns, target=args.directory)
def _get_cloud(self, distro): paths = helpers.Paths({'templates_dir': self.new_root}) cls = distros.fetch(distro) mydist = cls(distro, {}, paths) myds = DataSourceNone.DataSourceNone({}, mydist, paths) return cloud.Cloud(myds, paths, {}, mydist, None)