def test_context(self, ucr0): with ucr0: ucr0["foo"] = "bar" ucr = ConfigRegistry() ucr.load() assert ucr['foo'] == 'bar'
def handler_info(args, opts=dict()): # type: (List[str], Dict[str, Any]) -> Iterator[str] """ Print variable info. :param args: Command line arguments. :param opts: Command line options. """ ucr = ConfigRegistry() ucr.load() # Import located here, because on module level, a circular import would be # created import univention.config_registry_info as cri # pylint: disable-msg=W0403 cri.set_language('en') info = cri.ConfigRegistryInfo(install_mode=False) for arg in args: try: yield variable_info_string(arg, ucr.get(arg, None), info.get_variable(arg), details=_SHOW_EMPTY | _SHOW_DESCRIPTION | _SHOW_CATEGORIES) except UnknownKeyException as ex: print(ex, file=sys.stderr)
def test_is_false_valid_direct(self): """Test valid is_false(value).""" ucr = ConfigRegistry() for value in ('NO', 'No', 'no', 'false', '0', 'disable', 'disabled', 'off'): self.assertTrue(ucr.is_false(value=value), 'is_false(v=%r)' % value)
def _commit_files(files, result, module): result['changed'] = len(files) > 0 if not result['changed']: result['message'] = "No files need to be unset" if module.check_mode: if len(files) > 0: result['message'] = "These files will be commited: {}".format(" ".join(files)) return if not result['changed']: return startd = datetime.datetime.now() ucr = ConfigRegistry() ucr.load() ucr_handlers = configHandlers() ucr_handlers.load() ucr_handlers.update() ucr_handlers.commit(ucr, files) endd = datetime.datetime.now() result['start'] = str(startd) result['end'] = str(endd) result['delta'] = str(endd - startd) result['meta']['commited_templates'] = files result['message'] = "These files were be commited: {}".format(" ".join(files)) result['failed'] = 0
def handler_filter(args, opts=dict()): # type: (List[str], Dict[str, Any]) -> None """Run filter on STDIN to STDOUT.""" ucr = ConfigRegistry() ucr.load() stdout = sys.stdout if six.PY2 else sys.stdout.buffer # type: IO[bytes] # type: ignore stdout.write(run_filter(sys.stdin.read(), ucr, opts=opts))
def handler_commit(args, opts=dict()): """Commit all registered templated files.""" ucr = ConfigRegistry() ucr.load() handlers = ConfigHandlers() handlers.load() handlers.commit(ucr, args)
def test_save_load(self, ucr0): """Save and re-load UCR.""" ucr0['foo'] = 'bar' ucr0.save() ucr = ConfigRegistry() ucr.load() assert ucr['foo'] == 'bar'
def handler_unregister(args, opts=dict()): """Unregister old info file.""" ucr = ConfigRegistry() ucr.load() handlers = ConfigHandlers() cur = handlers.update() # cache must be current obsolete = handlers.unregister(args[0], ucr) handlers.update_divert(cur - obsolete)
def test_context_error(self, ucr0): ex = ValueError() with pytest.raises(ValueError) as exc_info, ucr0: ucr0["foo"] = "bar" raise ex assert exc_info.value is ex ucr = ConfigRegistry() ucr.load() assert ucr['foo'] is None
def handler_register(args, opts=dict()): """Register new info file.""" ucr = ConfigRegistry() ucr.load() handlers = ConfigHandlers() handlers.update() # cache must be current # Bug #21263: by forcing an update here, the new .info file is already # incorporated. Calling register for multifiles will increment the # def_count a second time, which is not nice, but uncritical, since the # diversion is (re-)done when >= 1. handlers.register(args[0], ucr)
def handler_dump(args, opts=dict()): # type: (List[str], Dict[str, Any]) -> Iterator[str] """ Dump all variables. :param args: Command line arguments. :param opts: Command line options. """ ucr = ConfigRegistry() ucr.load() for line in str(ucr).split('\n'): yield line
def handler_commit(args, opts=dict()): # type: (List[str], Dict[str, Any]) -> None """ Commit all registered templated files. :param args: Command line arguments. :param opts: Command line options. """ ucr = ConfigRegistry() ucr.load() handlers = ConfigHandlers() handlers.load() handlers.commit(ucr, args)
def handler_unregister(args, opts=dict()): # type: (List[str], Dict[str, Any]) -> None """ Unregister old `.info` file. :param args: Command line arguments. :param opts: Command line options. """ ucr = ConfigRegistry() ucr.load() handlers = ConfigHandlers() cur = handlers.update() # cache must be current obsolete = handlers.unregister(args[0], ucr) handlers.update_divert(cur - obsolete)
def _set_keys(keys, result, module): ucr = ConfigRegistry() ucr.load() def needs_change(key): if key not in ucr: return True if isinstance(keys[key], bool): if keys[key] and not ucr.is_true(key): return True elif not keys[key] and not ucr.is_false(key): return True elif ucr[key] != keys[key]: return True return False to_set = list(filter(needs_change, keys)) result['changed'] = len(to_set) > 0 if not result['changed']: result['message'] = "No keys need to be set" if module.check_mode: if len(to_set) > 0: result['message'] = "These keys need to be set: {}".format(" ".join(to_set)) return if not result['changed']: return args = ["/usr/sbin/univention-config-registry", "set"] + ["{0}={1}".format(key, keys[key]) for key in to_set] startd = datetime.datetime.now() rc, out, err = module.run_command(args) endd = datetime.datetime.now() result['start'] = str(startd) result['end'] = str(endd) result['delta'] = str(endd - startd) result['out'] = out.rstrip("\r\n") result['err'] = err.rstrip("\r\n") result['rc'] = rc result['message'] = "These keys were set: {}".format(" ".join(to_set)) result['meta']['changed_keys'] = to_set result['failed'] = rc != 0 or len(err) > 0 if rc != 0: module.fail_json(msg='non-zero return code', **result)
def test_schedule(self): """Create SCHEDULE registry.""" _ucr = ConfigRegistry(write_registry=ConfigRegistry.SCHEDULE) fname = os.path.join(self.work_dir, ConfigRegistry.BASES[ConfigRegistry.SCHEDULE]) self.assertTrue(os.path.exists(fname))
def test_forced(self): """Create FORCED registry.""" _ucr = ConfigRegistry(write_registry=ConfigRegistry.FORCED) fname = os.path.join(self.work_dir, ConfigRegistry.BASES[ConfigRegistry.FORCED]) self.assertTrue(os.path.exists(fname))
def test_normal(self): """Create NORMAL registry.""" _ucr = ConfigRegistry() fname = os.path.join(self.work_dir, ConfigRegistry.BASES[ConfigRegistry.NORMAL]) self.assertTrue(os.path.exists(fname))
def test_custom(self, ucr0, tmpdir): """Create CUSTOM registry.""" fname = tmpdir / 'custom.conf' _ucr = ConfigRegistry(str(fname)) # noqa F841 assert fname.exists()
def test_custom(self): """Create CUSTOM registry.""" fname = os.path.join(self.work_dir, 'custom.conf') _ucr = ConfigRegistry(fname) self.assertTrue(os.path.exists(fname))
def ucr_factory(): # type: () -> ConfigRegistry """ Factory method to return private loaded UCR instance. :returns: A private UCR instance. """ return ConfigRegistry().load()
def test_ldap(self): """Create LDAP registry.""" _ucr = ConfigRegistry(write_registry=ConfigRegistry.LDAP) fname = os.path.join(self.work_dir, ConfigRegistry.BASES[ConfigRegistry.LDAP]) self.assertTrue(os.path.exists(fname))
def ucr0(tmpdir): """ Return an empty UCR instance. """ ConfigRegistry.PREFIX = str(tmpdir) ucr = ConfigRegistry() return ucr
def test_schedule(self, ucr0, tmpdir): """Create SCHEDULE registry.""" _ucr = ConfigRegistry( write_registry=ConfigRegistry.SCHEDULE) # noqa F841 assert (tmpdir / ConfigRegistry.BASES[ConfigRegistry.SCHEDULE]).exists()
def test_save_load(self): """Save and re-load UCR.""" ucr = ConfigRegistry() ucr['foo'] = 'bar' ucr.save() ucr = ConfigRegistry() ucr.load() self.assertEqual(ucr['foo'], 'bar')
def test_custom_through_env(self, monkeypatch, tmpdir): """Create CUSTOM registry through environment variable.""" fname = tmpdir / 'custom.conf' monkeypatch.setenv('UNIVENTION_BASECONF', str(fname)) _ucr = ConfigRegistry(str(fname)) # noqa F841 assert fname.exists()
def handler_info(args, opts=dict()): """Print variable info.""" reg = ConfigRegistry() reg.load() # Import located here, because on module level, a circular import would be # created import univention.config_registry_info as cri # pylint: disable-msg=W0403 cri.set_language('en') info = cri.ConfigRegistryInfo(install_mode=False) for arg in args: try: print_variable_info_string(arg, reg.get(arg, None), info.get_variable(arg), details=_SHOW_EMPTY | _SHOW_DESCRIPTION | _SHOW_CATEGORIES) except UnknownKeyException, ex: print >> sys.stderr, ex
def test_locking(self): """Test inter-process-locking.""" delay = 1.0 ucr = ConfigRegistry() read_end, write_end = os.pipe() pid1 = os.fork() if not pid1: # child 1 os.close(read_end) ucr.lock() os.write(write_end, '1') time.sleep(delay) ucr.unlock() os._exit(0) pid2 = os.fork() if not pid2: # child 2 os.close(write_end) os.read(read_end, 1) ucr.lock() time.sleep(delay) ucr.unlock() os._exit(0) os.close(read_end) os.close(write_end) timeout = time.time() + delay * 3 while time.time() < timeout: pid, status = os.waitpid(0, os.WNOHANG) if (pid, status) == (0, 0): time.sleep(0.1) elif pid == pid1: self.assertTrue(os.WIFEXITED(status)) self.assertEqual(os.WEXITSTATUS(status), 0) pid1 = None elif pid == pid2: self.assertTrue(os.WIFEXITED(status)) self.assertEqual(os.WEXITSTATUS(status), 0) self.assertEqual(pid1, None, 'child 2 exited before child 1') break else: self.fail('Unknown child status: %d, %x' % (pid, status)) else: self.fail('Timeout')
def handler_register(args, opts=dict()): # type: (List[str], Dict[str, Any]) -> None """ Register new `.info` file. :param args: Command line arguments. :param opts: Command line options. """ ucr = ConfigRegistry() ucr.load() handlers = ConfigHandlers() handlers.update() # cache must be current # Bug #21263: by forcing an update here, the new .info file is already # incorporated. Calling register for multifiles will increment the # def_count a second time, which is not nice, but uncritical, since the # diversion is (re-)done when >= 1. handlers.register(args[0], ucr)
def handler_get(args, opts=dict()): # type: (List[str], Dict[str, Any]) -> Iterator[str] """ Return config registry variable. :param args: Command line arguments. :param opts: Command line options. """ ucr = ConfigRegistry() ucr.load() key = args[0] value = ucr.get(key) if value is None: return elif OPT_FILTERS['shell'][2]: yield '%s: %s' % (key, value) else: yield value
def handler_info(args, opts=dict()): """Print variable info.""" ucr = ConfigRegistry() ucr.load() # Import located here, because on module level, a circular import would be # created import univention.config_registry_info as cri # pylint: disable-msg=W0403 cri.set_language('en') info = cri.ConfigRegistryInfo(install_mode=False) for arg in args: try: print_variable_info_string(arg, ucr.get(arg, None), info.get_variable(arg), details=_SHOW_EMPTY | _SHOW_DESCRIPTION | _SHOW_CATEGORIES) except UnknownKeyException as ex: print >> sys.stderr, ex
def test_threading(self, tmpdir): """Multiple threads accessing same registry.""" DO_LOCKING = True THREADS = 10 ITERATIONS = 1000 BASE, PRIME = 7, 23 KEY = 'x' * PRIME SKEY, SVALUE = 'always', 'there' ConfigRegistry.PREFIX = str(tmpdir) ucr = ConfigRegistry() ucr[SKEY] = SVALUE ucr.save() lock = Lock() if DO_LOCKING else DummyLock() def run(tid): for iteration in range(ITERATIONS): i = tid + iteration random = pow(BASE, i, PRIME) key = KEY[:random + 1] with lock: ucr.load() assert ucr[SKEY] == SVALUE, 'tid=%d iter=%d %r' % ( tid, iteration, ucr.items()) try: del ucr[key] except LookupError: ucr[key] = '%d %d' % (tid, iteration) if i % 10 == 0 and tid % 10 == 0: with lock: ucr.save() threads = [] for tid in range(THREADS): thread = Thread(target=run, name='%d' % tid, args=(tid, )) threads.append(thread) for thread in threads: thread.start() for thread in threads: thread.join()
def handler_get(args, opts=dict()): """Return config registry variable.""" ucr = ConfigRegistry() ucr.load() if not args[0] in ucr: return if OPT_FILTERS['shell'][2]: print '%s: %s' % (args[0], ucr.get(args[0], '')) else: print ucr.get(args[0], '')
def handler_set(args, opts=dict(), quiet=False): """ Set config registry variables in args. Args is an array of strings 'key=value' or 'key?value'. """ handlers = ConfigHandlers() handlers.load() current_scope = ConfigRegistry.NORMAL reg = None if opts.get('ldap-policy', False): current_scope = ConfigRegistry.LDAP reg = ConfigRegistry(write_registry=current_scope) elif opts.get('force', False): current_scope = ConfigRegistry.FORCED reg = ConfigRegistry(write_registry=current_scope) elif opts.get('schedule', False): current_scope = ConfigRegistry.SCHEDULE reg = ConfigRegistry(write_registry=current_scope) else: reg = ConfigRegistry() reg.lock() try: reg.load() changed = {} for arg in args: sep_set = arg.find('=') # set sep_def = arg.find('?') # set if not already set if sep_set == -1 and sep_def == -1: print >> sys.stderr, \ "W: Missing value for config registry variable '%s'" % \ (arg,) continue else: if sep_set > 0 and sep_def == -1: sep = sep_set elif sep_def > 0 and sep_set == -1: sep = sep_def else: sep = min(sep_set, sep_def) key = arg[0:sep] value = arg[sep + 1:] old = reg.get(key) if (old is None or sep == sep_set) and validate_key(key): if not quiet: if reg.has_key(key, write_registry_only=True): print 'Setting %s' % key else: print 'Create %s' % key k = reg.get(key, None, getscope=True) if k and k[0] > current_scope: print >> sys.stderr, \ 'W: %s is overridden by scope "%s"' % \ (key, SCOPE[k[0]]) reg[key] = value changed[key] = (old, value) replog('set', current_scope, reg, key, old, value) else: if not quiet: if old is not None: print 'Not updating %s' % key else: print 'Not setting %s' % key reg.save() finally: reg.unlock() handlers(changed.keys(), (reg, changed))
def handler_dump(args, opts=dict()): """Dump all variables.""" ucr = ConfigRegistry() ucr.load() for line in str(ucr).split('\n'): print line
def handler_filter(args, opts=dict()): """Run filter on STDIN to STDOUT.""" ucr = ConfigRegistry() ucr.load() sys.stdout.write(run_filter(sys.stdin.read(), ucr, opts=opts))
except re.error, ex: print >> sys.stderr, 'E: invalid regular expression: %s' % (ex,) sys.exit(1) # Import located here, because on module level, a circular import would be # created import univention.config_registry_info as cri # pylint: disable-msg=W0403 cri.set_language('en') info = cri.ConfigRegistryInfo(install_mode=False) category = opts.get('category', None) if category and not info.get_category(category): print >> sys.stderr, 'E: unknown category: "%s"' % (category,) sys.exit(1) ucr = ConfigRegistry() ucr.load() details = _SHOW_EMPTY | _SHOW_DESCRIPTION if opts.get('non-empty', False): details &= ~_SHOW_EMPTY if opts.get('brief', False) or ucr.is_true('ucr/output/brief', False): details &= ~_SHOW_DESCRIPTION if ucr.is_true('ucr/output/scope', False): details |= _SHOW_SCOPE if opts.get('verbose', False): details |= _SHOW_CATEGORIES | _SHOW_DESCRIPTION all_vars = {} # key: (value, vinfo, scope) for key, var in info.get_variables(category).items(): all_vars[key] = (None, var, None)
def handler_unset(args, opts=dict()): """ Unset config registry variables in args. """ current_scope = ConfigRegistry.NORMAL reg = None if opts.get('ldap-policy', False): current_scope = ConfigRegistry.LDAP reg = ConfigRegistry(write_registry=current_scope) elif opts.get('force', False): current_scope = ConfigRegistry.FORCED reg = ConfigRegistry(write_registry=current_scope) elif opts.get('schedule', False): current_scope = ConfigRegistry.SCHEDULE reg = ConfigRegistry(write_registry=current_scope) else: reg = ConfigRegistry() reg.lock() try: reg.load() handlers = ConfigHandlers() handlers.load() changed = {} for arg in args: if reg.has_key(arg, write_registry_only=True): oldvalue = reg[arg] print 'Unsetting %s' % arg del reg[arg] changed[arg] = (oldvalue, '') k = reg.get(arg, None, getscope=True) replog('unset', current_scope, reg, arg, oldvalue) if k and k[0] > current_scope: print >> sys.stderr, \ 'W: %s is still set in scope "%s"' % \ (arg, SCOPE[k[0]]) else: msg = "W: The config registry variable '%s' does not exist" print >> sys.stderr, msg % (arg,) reg.save() finally: reg.unlock() handlers(changed.keys(), (reg, changed))