Giter Site home page Giter Site logo

straw's Introduction

๐Ÿฅค Straw for your Slurm beverage!

Straw is a simple and minimalistic one-shot cli tool that fetches the Slurm config files from a Slurm server running the slurmctld. It can greatly simplify the deployment of (containerised) environments that interact as clients with Slurm clusters by removing the need for maintaining munge keys, Slurm config files, as well as slurmd, and munge daemons.

Why Straw?

In order to create tools and clients that interact with a Slurm cluster, an environment/container usually needs at least the following:

  • The Slurm config file(s).
  • The Munge authentication tokens.

Most of the time, this involves:

  • Either maintaining a copy of your Slurm config file(s), or running slurmd with configless mode.
  • The munged daemon configured with a munge key for authentication

When containerising tools or clients that interact with the Slurm cluster, it is undesirable having to run and setup these extra services on each container, and managing the munge.key that is shared in the cluster requires utmost care.

In fact, when building Slurm client environments (such as containers), due to how Slurm tools have been designed, you must choose between either a configless setup, or a munge secretless setup.

Configless setup refers to an environment which is agnostic to Slurm config files (no need update and put these files in your environment).

Secretless setup refers to not needing to share the secret munge key with your environment.

For instance, you may want to connect some notebook service that is exposed to the internet to your Slurm cluster. In this situation, you might prefer not to keep the Slurm munge key in the public notebook service that's exposed to the wider Internet.

   D M Z       firewall
                  โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚            โ”‚    โ”‚    โ”‚           โ”‚
โ”‚  Public    โ”‚    โ”‚    โ”‚  Private  โ”‚
โ”‚  notebook  โ”‚    โ”‚    โ”‚  Slurm    โ”‚
โ”‚  service   โ”‚    โ”‚    โ”‚  cluster  โ”‚
โ”‚            โ”‚    โ”‚    โ”‚           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

One way to go munge-secretless is to rely on JWT tokens (which arguably are a secret, but where the risk implications are much lower than the munge key). However, Slurm tools can not use JWT tokens and configless mode simultaneously. And while it is possible to use JWT in combination with a minimalistic slurm.conf with just the SlurmctldHost and Clustername, some commands such as srun refuse to run without more information in the slurm.conf, limiting the usefulness of this approach.

Straw is a one-shot cli tool that aims to greatly simplify these use cases, and provide increased security for these environments.

Straw fetches the Slurm config files, optionally using JWT authentication, removing the burden of setting up and running both slurmd and munged, and allowing configless and munge-secretless environments to interact with Slurm clusters.

How does it work?

Straw talks just enough of the Slurm protocol to be able to retrieve the config files, and perform either munge or jwt authentication, in a way that regular Slurm tools don't.

Therefore you can create containers that do not contain neither the slurm.conf files, nor munge secrets, nor run additional daemons (such as munge or slurmd). Just add straw to your container and call it early on during initialisation, ensuring your environment starts after having fetched all Slurm config files.

Requirements

Running this tool requires python 3.

If you're using munge to authenticate, you must run this tool as either the Slurm user, or root. The slurmctld needs to have configless mode enabled as well.
Optionally, for JWT authentication you'll need to enable JWT support in your slurmctld.

Building

With munge support

pip install "straw[munge] @ git+https://github.com/pllopis/straw"

Without munge support

pip install "straw @ git+https://github.com/pllopis/straw"

Usage

usage: straw.py [-h] [--auth {munge,jwt}] [-o OUTPUT_DIR] [-v] [-V] [-l] server [server ...] version

positional arguments:
  server                slurmctld server in server[:port] notation
  version               Slurm major version that corresponds to that of the slurmctld server (e.g. 22.05)

options:
  -h, --help            show this help message and exit
  --auth {munge,jwt}    Authentication method (default: jwt)
  -o OUTPUT_DIR, --output-dir OUTPUT_DIR
                        Existing output directory where config files will be saved (default: ./)
  -v, --verbose         Increase output verbosity. Rrepetitions allowed. (default: None)
  -V, --version         show program's version number and exit
  -l, --list            List available protocol versions (default: False)

Where auth_method is either munge or jwt. The pymunge import is conditional on using munge as authentication method, so if yo do not need munge, the library requirement is also not needed. When using jwt authentication, the token will be grabbed from the SLURM_JWT environment variable.

The Slurm version should include the major release (first two parts), e.g. 22.05. It should also match that of the slurmctld server, as this will determine the Slurm protocol version that straw will use to communicate with the slurmctld.

straw's People

Contributors

frukto avatar pllopis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

frukto pforai

straw's Issues

Unpack error

I'm trying this on our Slurm 21.08.8 cluster with python 3.10 and I get:

$ python3.10 straw.py --auth munge -v master02.hydra.os 21.08
Using authentication method: munge
Trying master02.hydra.os:6817...
Traceback (most recent call last):
  File "/vscmnt/brussel_pixiu_data/_data_brussel/100/vsc10042/straw/straw.py", line 425, in <module>
    main()
  File "/vscmnt/brussel_pixiu_data/_data_brussel/100/vsc10042/straw/straw.py", line 422, in main
    fetch_config(args.server, args.auth, args.output_dir)
  File "/vscmnt/brussel_pixiu_data/_data_brussel/100/vsc10042/straw/straw.py", line 350, in fetch_config
    response_msg = send_recv(server, payload)
  File "/vscmnt/brussel_pixiu_data/_data_brussel/100/vsc10042/straw/straw.py", line 324, in send_recv
    resp_len = int(unpack('!I', recv_len)[0])
struct.error: unpack requires a buffer of 4 bytes

Any clue?

Use default_factory to create default Header instances for SlurmMessage fields

SlurmMessage.header and SlurmMessage.auth fields need to use default_factory to initialize Header instances.

Using Python 3.11.3, simply importing the straw module shows the problem:

Python 3.11.3 (main, Apr  5 2023, 22:33:13) [GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import straw
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.11/site-packages/straw.py", line 82, in <module>
    @dataclass
     ^^^^^^^^^
  File "/usr/local/lib/python3.11/dataclasses.py", line 1223, in dataclass
    return wrap(cls)
           ^^^^^^^^^
  File "/usr/local/lib/python3.11/dataclasses.py", line 1213, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dataclasses.py", line 958, in _process_class
    cls_fields.append(_get_field(cls, name, type, kw_only))
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dataclasses.py", line 815, in _get_field
    raise ValueError(f'mutable default {type(f.default)} for field '
ValueError: mutable default <class 'straw.Header'> for field header is not allowed: use default_factory

Following the guidance in the ValueError, using default_factory appears to resolve the issue:

diff --git a/straw.py b/straw.py
index ebfe6fb..31c39cb 100644
--- a/straw.py
+++ b/straw.py
@@ -90,8 +90,8 @@ class SlurmMessage:
     """
     data: bytes = None
 
-    header: Header = Header()
-    auth: Auth = Header()
+    header: Header = field(default_factory=Header)
+    auth: Auth = field(default_factory=Header)
     body: Body = None
 
     _unpack_offset: int = 0

With the fix, the import succeeds:

Python 3.11.3 (main, Apr  5 2023, 22:33:13) [GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import straw
>>> 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.