System plugins provide a way for the pavilion user to provide ways for Pavilion to find useful information about the system it's running on. Each plugin has a name and produces one or more values. The set of system plugin values are provided to several other components, including to test configurations as the 'sys' variable set.
Names
System variable plugins should have names compatible with the allowed names for test config variables. The names are case sensitive, and should match the regex `^[a-zA-Z][a-zA-Z0-9_-]+$'.
Values
The values are limited to what is acceptable in a test config variable. They can be a single string value, a list of string values, a dict of key -> str value pairs, or a list of such dicts.
Dependencies
Each system plugin receives the values of plugins that resolved before it, so they can depend on the values of other system plugins. Loops in such dependencies are detected automatically.
Expected System Plugins
A default plugin is provided for several important values. Unfortunately, some of these only work in the narrowest of cases, as noted. Also note that most of these names start with sys_*. This is solely a matter of local convention.
'sys_os'
The 'sys_os' is the vendor specific, high level name and release version major of the system os, in lowercase. Examples include 'ubuntu18', 'rhel7', 'cle6', and 'toss3'. Most os's provide a /etc/*_release file that this is gathered from, though both the actual name of the file and the content formats vary by os.
The default plugin checks for and parses several different 'release' files, as well as the SYSOS environment variable.
'sys_arch'
The underlying cpu architecture of the system. The default simply uses what is returned by uname -i.
'sys_name'
The name of overall cluster. The default simply uses the unqualified host name of the system. This is almost certainly the wrong answer..
Deferred Lookups
Some system variables have values that would be useless if looked up on the node that starts the test. To get a reasonable value, these variables need their lookups deferred until the test script actually runs. Such variables should have their system plugin module defined with 'deferred' set to True. When the test configuration is resolved, the value for deferred variables will be returned as a subshell that calls pavilion itself.
As you can see, deferring a variable simply becomes a sub-shell resolution through pavilion itself. A few notes:
Only system variables provide this functionality currently.
Deferred variables can only return a single value (though it may be a dictionary).
While we attempt to check this on the initiating host, there are no guarantees about how an arbitrary plugin will behave.
See below for how to write a system plugin that can be deferred.
Writing System Plugins
To write a system plugin, create a new python module in one of your pavilion config directories under plugins/system. In that, inherit from pavilion.system_plugins.SystemPlugin, and override the get() and __init__() methods.
# It's important that you not import SystemPlugin directly, as the plugin system has no way to tell it apart # from your plugin, and could load the wrong one.
import pavilion.system_plugins as system_plugins
class Hugepages(system_plugins.SystemPlugin):
# The init can't take any arguments, other than self.
def __init__(self):
# This is how you set the plugin variable name.
super().__init__('sys_hugepages')
def get(self, sys_vars):
# The sys_vars are in special structures that raise a unique KeyError child type. When this
# happens, the plugin is moved to the bottom of the resolution queue, to hopefully after a time
# when the variable will be available. This can happen repeatedly, until either all of the plugins are
# resolved or a loop is detected.
if sys_vars['sys_os'] == 'rhel7':
# This doesn't actually vary like this; it's just an example.
huge_pages_key = 'HugePages:'
else:
huge_pages_key = 'HugePages_Total:'
with open('/proc/meminfo') as meminfo_file:
for line in meminfo_file.read().split('\n'):
if line.startswith(huge_pages_key):
return line.split()[1]
return None
Deferred Variables
When a system plugin is defined as deferred, it should return a variables.DeferredVariable object instead of a value by default. These objects resolve into the subshell commands as shown above. They must also be aware of what subkeys are available for the user to reference.
System Plugins
System plugins provide a way for the pavilion user to provide ways for Pavilion to find useful information about the system it's running on. Each plugin has a name and produces one or more values. The set of system plugin values are provided to several other components, including to test configurations as the 'sys' variable set.
Names
System variable plugins should have names compatible with the allowed names for test config variables. The names are case sensitive, and should match the regex `^[a-zA-Z][a-zA-Z0-9_-]+$'.
Values
The values are limited to what is acceptable in a test config variable. They can be a single string value, a list of string values, a dict of key -> str value pairs, or a list of such dicts.
Dependencies
Each system plugin receives the values of plugins that resolved before it, so they can depend on the values of other system plugins. Loops in such dependencies are detected automatically.
Expected System Plugins
A default plugin is provided for several important values. Unfortunately, some of these only work in the narrowest of cases, as noted. Also note that most of these names start with
sys_*
. This is solely a matter of local convention.'sys_os'
The 'sys_os' is the vendor specific, high level name and release version major of the system os, in lowercase. Examples include 'ubuntu18', 'rhel7', 'cle6', and 'toss3'. Most os's provide a /etc/*_release file that this is gathered from, though both the actual name of the file and the content formats vary by os.
The default plugin checks for and parses several different 'release' files, as well as the SYSOS environment variable.
'sys_arch'
The underlying cpu architecture of the system. The default simply uses what is returned by
uname -i
.'sys_name'
The name of overall cluster. The default simply uses the unqualified host name of the system. This is almost certainly the wrong answer..
Deferred Lookups
Some system variables have values that would be useless if looked up on the node that starts the test. To get a reasonable value, these variables need their lookups deferred until the test script actually runs. Such variables should have their system plugin module defined with 'deferred' set to
True
. When the test configuration is resolved, the value for deferred variables will be returned as a subshell that calls pavilion itself.should yield a test script with a command like:
As you can see, deferring a variable simply becomes a sub-shell resolution through pavilion itself. A few notes:
See below for how to write a system plugin that can be deferred.
Writing System Plugins
To write a system plugin, create a new python module in one of your pavilion config directories under
plugins/system
. In that, inherit frompavilion.system_plugins.SystemPlugin
, and override theget()
and__init__()
methods.Deferred Variables
When a system plugin is defined as deferred, it should return a
variables.DeferredVariable
object instead of a value by default. These objects resolve into the subshell commands as shown above. They must also be aware of what subkeys are available for the user to reference.