-
Notifications
You must be signed in to change notification settings - Fork 52
WIP: modprobe: efficient and extensible flux startup and shutdown #6774
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Problem: We'd like to use the TopologicalSorter from Python 3.9 graphlib, but Flux still needs to support Python < 3.9. Grab a backport from https://github.com/mariushelf/graphlib_backport and vendor in flux.utils.
df1c909
to
72a0172
Compare
A really dumb initial comment. Seeing a file called |
it was originally |
Yeah, I think that would be better. |
Problem: Flux startup and shutdown currently use scripts that load modules and run other tasks serially, but there is potential to do some of this work in parallel which would greatly speed up instance startup. Introduce flux-modprobe, which can manage loading and removal of modules and the execution of tasks based on precedence relationships. Modules are defined in TOML configuration files, and startup/shutdown tasks defined in python using a modprobe `@task` decorator. The rc1 and rc3 scripts can then be replaced by `flux modprobe rc1` and `flux modprobe rc3` which load modules and execute tasks in the most efficient manner possible.
Problem: flux-modprobe requires that modules be configured in a modprobe.toml file, but no such file currently exists. Add modprobe.toml containing configuration for the current set of flux-core modules.
Problem: Flux startup/shutdown does not use flux-modprobe. Add etc/rc1.py and etc/rc3.py files to define startup and shutdown tasks. Replace most of rc1/rc3 with calls to `flux modprobe rc1` and `flux modprobe rc3`.
Problem: `FLUX_MODPROBE_PATH` set in the calling environment could affect tests in the testsuite. Unset `FLUX_MODPROBE_PATH` for tests.
Problem: The rc-* "personality" files used by `test_under_flux` in the testsuite do not use flux-modprobe. This not only makes them less efficient, but also we lose out on testing the modprobe tool. Convert the rc personality files to flux-modprobe.
Problem: Several tests in t1200-stats-basic.t are racy with the new rc1, which runs faster than before. Use `dmesg-grep.py` to find matching dmesg lines before exiting the instance instead of assuming the output will occur in time when /bin/true is used as the initial program. In one case, load the heartbeat module with period=0.2s to ensure content module stats are emitted within `sleep 1`.
Problem: flake8 identifies several problems with the helper script `etc/gen-cmdhelp.py`. Address the issues so that Python linting run clean on this script.
Problem: There's trailing whitespace in `etc/.gitignore`. Remove it.
Problem: New Python files in etc and t/rc are not run under black, flake8 and mypy since these paths do not appear in the pre-commit `files` pattern. Add these paths to `.pre-commit-config.yaml` so the new `.py` files are formatted and checked in CI.
Problem: There are no tests of flux-modprobe. Add t0100-modprobe.t for this purpose.
Problem: None of the tests in the testsuite test starting an instance with content.restore=auto but no RESTORE link, but this is the case when first starting a system instance, and exercises key login in etc/rc1.py. Add -Scontent.restore=auto to the first instance run in t2810-kvs-garbage-collect.t so that this case is exercised in the testsuite.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #6774 +/- ##
==========================================
+ Coverage 83.83% 83.90% +0.06%
==========================================
Files 535 537 +2
Lines 89323 89925 +602
==========================================
+ Hits 74888 75449 +561
- Misses 14435 14476 +41
🚀 New features to boost your workflow:
|
This experimental PR is a prototype of a replacement for the Flux rc startup/shutdown system.
It started with a few goals:
sched
andfeasiblity
I'm somewhat satisfied with the interface in this prototype, so I'm posting it early for feedback on that aspect of the design, before going on to do documentation and tests. I'm looking for feedback on the overall scheme here, and if it would an acceptable path forward.
I apologize, the description below is lengthy:
The proposed design here consists of 3 components: A TOML configuration specification for expressing modules and their relationships and requirements:
modules.toml
andetc/modules.d/*.toml
, a new Python interface to define tasks that run duringrc1
andrc3
, and finally aflux modprobe
command that processes the previous two files and runs the tasks defined for the runlevel as efficiently as possible. Each of these components is described in more detail below:modules.toml
The
modules.toml
file defines modules in Flux, whether they require other modules, any broker attrs/config they need, and the ranks on which they should be loaded. The flux-core modules are all defined in/etc/flux/modules.toml
, and extra modules can be defined inmodules.d/*.toml
. The file currently contains one[[modules]]
array, each entry of which defines a module and supports the following keys (this is taken from the top of the existingmodules.toml
)Here's an example module:
This entry defines the
cron
module, only loaded on rank 0. The cron module requires theheartbeat
mdoule, and it should be loaded by default with the argssync=heartbeat.pulse
.One caveat: the
provides
documentation claims to support a way to override the default alternative, but that is not yet implemented.modprobe
rcX.py
filesflux modprobe
replaces thercX
scripts with a Python file that defines a set of tasks to run and the relationships between those tasks so that interdependent tasks are run in the correct order. Non-module tasks are defined in an Python file via the@task
decorator:The
context
here is aflux.modprobe.Context
object which is shared between all tasks, it contains some convenience attributes and methods to get a shared Flux handle, send an rpc, or run something underbash
, as well as offering a way to get broker attributes, config, and share arbitrary data between tasks. Here's an example of a task fromrc1.py
:This task runs only on ranks != 0, only if the
config.path
broker attribute is set and runs before all other tasks. It sends theconfig.reload
rpc and waits for the result.When modprobe loads a
*.py
file, it will always first run any definedsetup (context)
method. This is where the rc file can define modules to load or remove, setup context data, etc. This is currently how anrc.d/*.py
could set an alternative or extend module args, or a replacementrc1.py
could load a subset of modules (though a more light weight method could be implemented later).Check out the
modules.toml
andrc1.py
andrc3.py
in this PR for full examples.Transition
For now, the majority of
rc1
andrc3
are replaced withflux modprobe rcX
. The run through ofFLUX_RC_EXTRA
is still maintained for backwards compatibility, but some kind of transition plan forflux-sched
will need to be implemented. If the overall design here is acceptable, we can work on that next.Timing
This implementation reduces the rc1 runtime in Flux from ~2.3s to ~.4s for a single rank
flux start
. To evaluate the prototype, the current version supports a--timing
option which dumps the start/end times of all tasks into the KVS. Here's the results for a system instance startup as an example: