Understanding the Loader
The Loader system is at the heart of how Salt works. In a nutshell, Salt is a collection of modules, tied together with the Loader. Even the transport mechanisms, which enable communication between and define the Master, Minion, and Syndic hierarchies make use of modules that are managed by the Loader.
Dynamic modules
Salt's Loader system is a bit unconventional. Traditionally, most software has been designed to require all components that are supported to be installed. This is not the case with every package, of course. The Apache Web Server is an example of one project that supports a number of components that need not all be installed. Debian-based operating systems manage Apache modules by providing their modules-available/
and modules-enabled/
directories. RedHat-based systems take a different approach: all components that are supported by Apache's httpd
package are required to be installed with it.
Making such a demand with Salt is beyond unrealistic. So many packages are supported with the default installation of Salt, many of which compete with each other (and some of which compete, in some ways, with Salt itself) that it could be said that to build such a dependency tree into Salt would effectively turn Salt into its own operating system.
However, even this is not entirely accurate. Because Salt supports a number of different Linux distributions, in addition to several Unix flavors and even Windows, it would be more accurate to say that installing every package that is supported by Salt would effectively turn Salt into several mutually-exclusive operating systems. Obviously, this is just not possible.
Salt is able to handle this using multiple approaches. First, Grains (covered in Chapter 1, Reviewing a Few Essentials) provide critical information to Salt to help identify the platform on which it is running. Grains such as os
and os_flavor
are used often enough to help Salt know whether to use yum
or apt
to manage packages, or systemd
or upstart
to manage services.
Each module is also able to check other dependencies on the system. The bulk of Salt's apache module makes use of the apachectl
command (or apache2ctl
as appropriate), so its availability is dependent upon whether or not that command exists on the system.
This set of techniques enables Salt to appropriately detect, as the Minion process starts, which modules to make available to the user.
A relatively new feature of Salt's Loader system is the ability to load modules on demand. Modules that support the Lazy Loader functionality will not actually load until requested by the user. This streamlines the start process for the Minion, and makes more effective use of the available resources.
Execution modules
It has often been said that most of the heavy lifting in Salt is performed by the execution modules. This is because Salt was designed originally as a remote execution system, and most module types that have been added to the loader have been designed to extend the functionality of remote execution.
For instance, State modules are designed with one purpose in mind: to enforce the State of a certain aspect of a system. This could be to ensure that a package is installed, or that a service is running. The State module itself doesn't install the package or start the service; it calls out to the execution module to do so. A State module's only job is to add idempotency
to an execution module.
One could say that an important differentiator between runner modules and execution modules is that runners are designed to be used from the Master, while execution modules are designed to execute remotely on the Minion. However, runners were actually designed with something more specific in mind. System administrators have been using shell scripts for decades. From csh
in Unix to bash
in Linux, and even batch files in DOS and Windows, this has been the long-running standard.
Runner modules were designed to allow Salt users to apply a scripting language to remote executions. Because so many early Salt users were also Python users, it was not generally difficult for them to use Python as their scripting language. As the Salt user base grew, so too did the number of users who were not fluent in Python, but the number of other options available for them also grew.
Reactor modules (covered in detail in Chapter 4, Managing Tasks Asynchronously) are a type of module that can pull together execution modules and runner modules, and make them available to users with no programming experience. And because Salt States are actually applied using the State
execution module, even States are available through Reactors.
Cloud modules
Cloud modules are not typically thought of by many people as Salt modules, perhaps because Salt Cloud (covered extensively in Chapter 5, Taking Salt Cloud to the Next Level) started as a project separate from Salt, but in fact they have always used the Loader system. However, they do work a little differently.
Unlike many other modules in Salt, Cloud modules do not make use of execution modules (although there is an execution module that makes use of the Salt Cloud). This is in part because Salt Cloud was designed to run on the Salt Master. However, it does not make use of runner modules either (though again, there is a runner module that can make use of the Salt Cloud).
Salt Cloud's initial purpose was to create new VMs on various public cloud providers, and automatically accept their keys on the Salt Master. However, it quickly grew apparent that users wanted to control as many aspects of their cloud providers as possible; not just VM creation.
Now Salt Cloud is able to perform any action that is available against a cloud provider. Some providers support more functionality than others. In some cases, this is because demand has not been presented, and in other cases because the appropriate developer has not yet had the resources to make the addition. But often it is because the features available on the provider itself may be limited. Whatever the situation, if a feature is available, then it can be added and made available via the Loader system.