WHAT? ----- This is a templated-based configuration utility for clusters. It allows CTDB and various services (Samba, NFS, vsftpd, ...) to be configured. It should be installed/run on each node after relevant packages are installed or after any master configuration/template change. WHY? ---- This is meant to be flexible and allow subsets of services to be configured. HOW? ---- Run like this to test template expansion into a staging subdirectory "t/": ./cluster-configure.py -vv -n -t templates/rhel -s t example.conf Or without -n but as root to test actual installation of files and reload of services. Try --help to see the options. Notes - this sounds complex, but it isn't... see the example configuration file and templates. Run the above command with the "-n" option and check out the files in the staging area... :-) * Master configuration file The master configuration file is parsed by Python's ConfigParser module. Therefore, it is subject to any restrictions of that module. For example, older versions do not allow identation of settings. * Template structure Each subdirectory of templates directory is a package name, with a 2-digit-plus-dot prefix used to order the processing of packages. If, according to the system's package manager, that package is not installed on the system then no further processing is done. A package subdirectory should have one or more version subdirectories that are matched to the version of the package reported by the package manager. A version subdirectory is named as # with a literal '#' as the separator. A missing limit implies no limit, so a version subdirectory of "#" matches all version. Comparisons with use <= and comparisons with use <. This allows simple ranges like "3.0#4.0" to work sensibly with "4.0#". The highest matching version is used, so the above could just be written "3.0#" and "4.0#". A "files" subdirectory of a version subdirectory contains a directory tree of configuration files that have template substitution done and are then installed into the root filesystem. A file is only actually installed if, after substitutions, it is different to the currently/previously installed file. An "events" subdirectory of a version subdirectory can contain "pre" and "post" files. If any configuration files are (to be) installed the "pre" is run before installation of these files and "post" is run afterwards. For example, consider the following: templates/rhel/60.nfs-utils/1.0#/files/etc/exports templates/rhel/60.nfs-utils/1.0#/files/etc/sysconfig/nfs templates/rhel/60.nfs-utils/1.0#/events/post If nfs-utils with a version >= 1.0 is installed then: 1. Template substitution is done on both files the /etc/exports and /etc/sysconfig/nfs files, and each resulting file is installed if it is different to the already installed corresponding file. 2. If a file was installed then "post" is run. This tells NFS to reload its configuration. * Template substitutions !!variable!! The template format is !!variable!!. @@variable@@ has been avoided so that you can install a configuration and templates with autocluster. !!|expr!! Apart from simple variables, templates can contain expression evaluations. !!|expr!! causes expr to be processed with Python's eval() function and the *return value* (not the output) is substituted for the template expression. !!%plugin.func(args)!! Plugin expressions are an extension to expression evaluations. If a plugin called "export.py" contains a function called "format" then a template can contain: !!%export.format(REST)!! and this will cause the return value the following to be substituted: export.format(config, self.name, ... REST ...) where: - config is the global configuration object - self.name is the name of the current package being processed - ... REST ... is usually a printf-style format string followed by a list of configuration keys who's values should be substituted into the Note that, for robustness, plugins don't actually get imported into the regular namespace so plugin expressions are quite useful... even though they might look confusing at first. An example is illustrative... Assuming that export.py contains: def format(config, package, format, items): ... In config (the master configuration file), several exports may be defined for the given package. Each will be of the form: [export:nfs-utils:data] share = data fsid = 834258092 This will inherit the directory and other options from the share "data": [share:data] directory = /srv/xyz123/data filesystem = /srv/xyz123 permissions = 0777 comment = An example share To create export defintions for NFS, something like this can be used: !!%export:format("\"%s\" *(rw,fsid=%s)\n", ["directory", "fsid"])!! This produces a line of output for each export, substituting the values for "directory" and "fsid" appropriately. In the above case, the output would be: "/srv/xyz123/data" *(rw,fsid=834258092) WHERE? ------ This is part of autocluster, so you can get it from: git://git.samba.org/autocluster.git WHO? ---- Martin Schwenke