KestrelCluster comes with an extensible template system which generates and edits the system and the nodes files. The behaviour and values of the templates can be changed with the variables, and also the template system allows to overload any template by a user customized one simply creating a new one with the same name and label (since we can have different templates editing the same file, and flags are ignored in the overload process).
The minimal node images are created using debootstrap which bootstraps a minimal debian system, this way we ensure that the OS run on the nodes is minimal. Afterwards the different configuration stages are run over this image.
KestrelCluster adds dinamically entries on the /etc/hosts file, and at the same time we parse this file to know what nodes are connected. Registered nodes are stored on /var/lib/kestrel/registered_nodes with dnsmasq's host format, this way we can map MAC to hostnames and at the same time dnsmasq gives the correct hostnames to the nodes since the start. Both files can be changed with KESTREL_CON_NODES and KESTREL_REG_NODES variables.
The node system and home directory are shared using NFS 4, although this can be extended in the future.
We tried to keep a simple design so that it would be easy to understand how everything works and know what The problem is that each time we add a new abstraction/stage, the more difficult it gets to understand how everything works and what they do.
The first approach was creating a name convention for every script, a try to provide good a descriptive name. The first name convention was :
(host|image)_service_description[_chroot]
This way we indicated if it was modifying system files or image files, for example the /etc/exports file when configuring an image, and if it was required to be run on a chroot, por example for holding a package with dpkg.
We also to splitted each script as they got too big under the lema: one script one functionality.
In the end, this approach started to be too hard to mantain.
Templates are named as they files the generate, scripts are named as the files they edit, and non editing scripts describe what they do:
Examples:
1. node/install.d/sbin/dhclient-script(edit) 2. node/install.d/etc/hostname 3. node/install.d/install/etc/init.d/kestrel_disconnect(OS=Ubuntu) 4. node/configure/etc/fstab("nfs4",edit) 5. node/configure/restart.dnsmasq
As we can see 2 and 3 are templates. 1 and 4 are editing scripts. 5 is a non editing script.
Flags are used to describe if a file is a template (by default) or an editing script, if it needs to be run under a chroot, and grouping a set of templates under a common "label". These grouped templates can be enabled/disabled globally with the option <label>_disabled=yes, or for an image with <label>_<image>_disabled=yes.
We also may want to create different templated for different OS releases, and we may also want to disable templates with variables.
system/configure.d/etc/dnsmasq.d/kestrel system/configure.d/etc/dnsmasq.d/kestrel(template)
By default a file is a template and when executed a sed script replaces the variables found by their value on the template.
share/node/system-install.d/etc/exports(edit)
share/system/configure.d/${TFTPBOOT_DIR}/kernel(run)
run.<name>, restart.<name>, check.<name>Examples:
share/system/configure.d/check.nfs share/system/configure.d/run.recreate_ssh_keys share/system/configure.d/restart.ufw share/system/configure.d/restart.dnsmasq
check scripts are executed on the stage before everything else. For example check.nfs parses the /etc/exports file to autodetect the nfs root directory and saves it on a variable.
run and restart scripts are executed on the stage after everything else.
This is an interesting function for editing files, since it makes easy to edit key-value based configuration files.
set_key_value <key> <value> <file> [<separator_re> [<separator> [<space>]]]
Examples:
set_key_value FRONTEND_IP "192.168.30.1" ${FILE} set_key_value PrintMotd no ${FILE} " "
FILE variable is an special variable the absolute path to the file being edited. Of course if the script is not executed under a chroot on an image it will point to the complete path where the image is found.
system/install.d/${KESTREL_DATA_DIR}/rpc/fifo(edit,user=kestrel,group=root,mode=660)
Allow setting the user, group an mode to generated/edited files.
node/pre-install.d/run.disable-dpkg-upstart(chroot) node/pre-install.d/run.disable-dpkg-upstart(nochroot)
os=${OS_DISTRIBUTION}-${OS_CODENAME} os=${OS_DISTRIBUTION}-${OS_RELEASE}Examples:
node/install.d/etc/init.d/kestrel_disconnect(os=Ubuntu-11.04) node/install.d/etc/init.d/kestrel_connect(os=Debian-squeeze) node/packages.d/openmpi(arch=amd64)
Templates and scripts are only applied to machines depending of the distribution or architecture.
system/configure.d/${TFTPBOOT_DIR}/reboot("pxelinux")
Variables on paths will be expanded, allowing a user to change the tftpboot dir.
system/configure.d/etc/ufw/applications.d/nfs(${secure_nfs})
We can enable or disable this script setting the variable secure_nfs_<image>=yes or secure_nfs_=yes.
Merges the user and the system configuration.
load_config, variable_list, variable_user_list, variable_values, export_config, detect_iface
Common functions.
mount_image, check_image, list_image, lock_image, ...
check_user, list_users, sshkeygen, check_root
run_script, kestrel_dialog, question_yN, msg, warn, die, msg_config, warn_config, eval_variables, check_kestrel_daemon, check_enabled
This library parses /etc/hosts (kestrel daemon adds dynamically entries for each connected node) to get the list of connected nodes, and parses a dnsmasq's dhcp config file (When a node is registered we add an entry containing the mac a unique hostname) to get the list of registered nodes.
(connected|disconnected|registered)_(nodes|images|groups), list_groups, check_(hostname|group|mac)
This library contains functions for configuring files.
create_evaluation_script, find_templates, run_template, applicable_templates
search_backup_file, get_backup_version, list_(backup_versions|original_files|edited_files), diff_files
list_stages, check_stages, run_configuration_stage
node_configure, node_install, system_configure, system_install
This library contains functions for edit scripts
copy_file, link_file, template_file, test_backup, perms_and_backup, restore_file, evaluate_template, set_key_value
Templates to be run before the installing packages stage.
For example, we hold dpkg and upstart packages, since we replace temporaly start-stop-daemon to avoid starting any service when we are installing a packages under a chroot jail.
The output of scripts in this stage are installed with apt-get.
Templates in this stage are run only once when KestrelCluster is installed/uninstalled on the system/image.
Templates in this stage are run each time you change any configuration parameter.
Templates in this stage are run only once when KestrelCluster is installed/uninstalled on the system/image.
Templates in this stage are run each time you change any configuration parameter.
Unused by now.
The output of scripts in this stage are installed with apt-get.
Unused by now, we provide the same functionality with package's dependencies
Templates in this stage are run only once when KestrelCluster is installed/uninstalled on the system/image.
Templates in this stage are run each time you change any configuration parameter.
Variables get their default value from the configuration files located at:
/usr/share/kestrel/* files should not be modified by a user because they will be overriden when a package is updated. They should modify /etc/kestrel/kestrel.conf instead.