Crate slurm_spank

Crate slurm_spank 

Source
Expand description

Rust bindings for writing Slurm SPANK Plugins

§Introduction

This crate allows to write Slurm SPANK plugins using Rust. To learn more about capabilities available through SPANK please refer to the official SPANK documentation.

To create a SPANK plugin using this crate, you need to define a struct for which you implement the Plugin trait and to make it available as a SPANK plugin using the SPANK_PLUGIN! macro.

The methods of the Plugin trait correspond to the callbacks defined by the SPANK API such as init_post_opt, task_post_fork etc. These methods have a default implementation which means you only need to implement the callbacks relevant for your plugin.

Each callback method is passed a SpankHandle reference which allows to interact with Slurm through the SPANK API.

When returning an Err from a callback an error message will be displayed and/or logged by default, depending on the context. This behaviour may be overridden by the report_error method. A default Subscriber is also configured to facilitate the use of the tracing crate for logging and error reporting while using SPANK log facilities, such as in the example below. This can be overridden by the setup method.

§Example: hello.so

The following example implements a simple hello world plugin. A more complete example is provided in the example directory of the repository which shows how to implement the same renice plugin that is given as an example of the C SPANK API in the Slurm SPANK documentation.

use eyre::WrapErr;
use slurm_spank::{
    spank_log_user, Context, Plugin, SpankHandle, SpankOption, SLURM_VERSION_NUMBER, SPANK_PLUGIN,
};

use std::error::Error;
use tracing::info;

// All spank plugins must define this macro for the
// Slurm plugin loader.
SPANK_PLUGIN!(b"hello", SLURM_VERSION_NUMBER, SpankHello);

#[derive(Default)]
struct SpankHello {
    greet: Option<String>,
}

unsafe impl Plugin for SpankHello {
    fn init(&mut self, spank: &mut SpankHandle) -> Result<(), Box<dyn Error>> {
        // Register the --greet=name option
        match spank.context()? {
            Context::Local | Context::Remote => {
                spank
                    .register_option(
                        SpankOption::new("greet")
                            .takes_value("name")
                            .usage("Greet [name] before running tasks"),
                    )
                    .wrap_err("Failed to register greet option")?;
            }
            _ => {}
        }
        Ok(())
    }
    fn init_post_opt(&mut self, spank: &mut SpankHandle) -> Result<(), Box<dyn Error>> {
        // Check if the option was set
        self.greet = spank
            .get_option_value("greet")
            .wrap_err("Failed to read --greet option")?
            .map(|s| s.to_string());
        if let Some(name) = &self.greet {
            info!("User opted to greet {name}");
        }
        Ok(())
    }

    fn user_init(&mut self, _spank: &mut SpankHandle) -> Result<(), Box<dyn Error>> {
        // Greet as requested
        if let Some(name) = &self.greet {
            spank_log_user!("Hello {name}!");
        }
        Ok(())
    }
}

The following Cargo.toml can be used to build this example plugin

 [package]
 name = "slurm-spank-hello"
 version = "0.1.0"
 edition = "2021"

 [lib]
 crate-type = ["cdylib"]

 [dependencies]
 eyre = "0.6.8"
 slurm-spank = "0.3"
 tracing = "0.1.37"

Macros§

SPANK_PLUGIN
Export a Plugin to make it available to the Slurm plugin loader
spank_log_debug
Log messages through SPANK at the debug level
spank_log_debug2
Log messages through SPANK at the debug2 level
spank_log_debug3
Log messages through SPANK at the debug3 level
spank_log_error
Log messages through SPANK at the error level
spank_log_info
Log messages through SPANK at the info level
spank_log_user
Log messages back to the user at the error level without prepending “error:”
spank_log_verbose
Log messages through SPANK at the verbose level

Structs§

SpankHandle
Handle to the Slurm interface exposed to SPANK plugins. It provides methods to query Slurm from a plugin.
SpankOption
SPANK plugin command-line option that can be registered with SpankHandle::register_option

Enums§

Context
Context in which a plugin is loaded during a Slurm job
LogLevel
Log level for SPANK logging functions
SpankApiError
Errors returned by the underlying SPANK API
SpankError
Main Error enum for interfaces provided by this crate

Constants§

SLURM_VERSION_NUMBER

Traits§

Plugin
Implement this trait to create a SPANK plugin

Functions§

slurm_spank_log
spank_log
Log messages through SPANK