Tutorial: read an easyconfig the way EasyBuild does¶
The model this page is teaching, in order: evaluate the file, format the templates, pick the easyblock, walk the toolchain, ask the robot. Commands are props. The model is the sequence. Work down the page. Every live sample is type-along: edit the island. Recordings later in the book are labelled as recordings; do not type those. Check that the island matches the expected output under it. Twenty minutes, nothing to install, nothing to put back. Who this is for. You can read code. You have met an easyconfig, or you are about to. You do not need EasyBuild, a cluster, an account, or Python, and you will not need them here.
Questions
Why does
SYSTEMhave no quotes?What does
%(version)sbecome, and when?How does EasyBuild pick an easyblock when the file never names one?
What you will be able to do
Say what an easyconfig means, as against what it says.
Predict which file EasyBuild will download from a version number.
Name the easyblock EasyBuild will look for, for any software name.
Say which dependencies a toolchain lets a package see.
Before you start¶
Ensure the browser has JavaScript enabled. Each sample below executes in this page on your machine. You can distinguish a live sample from a printed one. A live sample displays editable, runs as you type above it and presents an answer below before any interaction. If a sample reports that the engine is not loaded, JavaScript is disabled or still loading; wait briefly, then reload.
Step 1: what the file says, and what it means¶
A real easyconfig is provided. It installs a browser-based VS Code on a supercomputer. Read it first. Then read the answer underneath it.
Expected output. An evaluated model includes three items that are absent from the file above.
toolchain reads ({name: system, version: system}) instead of the word SYSTEM.
EasyBuild places that name in scope prior to evaluating the file, using the constant {'name': 'system', 'version': 'system'}.
It is a variable, and moduleclass adjacent to it is a string.
source_urls returns 4.130.0.
After the file runs, EasyBuild performs a second pass that formats the %(version)s strings.
The file itself stored the literal value.
File order is irrelevant; sources may appear before version.
The final line reports an easyblock that the file never mentions.
Step 2: change the version, and watch what follows¶
In the sample above, change 4.130.0 to 4.131.0.
Expected output. both the URL and the source filename follow, without your touching either.
That is what the templating is for: one number, stated once.
Now change name from code-server to codeserver.
Expected output. the derived easyblock change too, from EB_code_minus_server to EB_codeserver.
It is computed from the name you typed, which is the subject of step 4.
Put both back before moving on, or do not; nothing here is saved.
Step 3: break it on purpose¶
Delete the whole version line.
Expected output. the model names the missing field and stops.
It does not guess, and it does not carry on with a blank.
Now put version back and delete the sources line instead.
Expected output. the model come back without sources, and no complaint.
A missing version stops everything.
A missing sources is a file that downloads nothing, which is a legal easyconfig and a useless one.
One more.
Add this line at the bottom:
checksums = [
Expected output. checksums are shown as not modelled.
The page’s reader processes only single-line assignments and lists the items it omits instead of fabricating them.
A multi-line construct requires the actual parser, which is implemented in Python.
the complete engine is a full program rather than the short snippet displayed here.
Step 4: which easyblock will EasyBuild look for¶
An easyconfig that does not specify an easyblock asserts that a software-specific one exists.
EasyBuild determines the name by transforming the software’s name one character at a time.
Enter several names into this field.
Include your own software if available.
Expected output. punctuation spelled out as words: the hyphen in code-server becomes minus, and c++ becomes EB_c_plus__plus_.
Look at the doubled separator in the middle.
The substitution runs per character and collapses nothing, and that is what keeps it reversible.
Now type a name with an underscore in it, say my_tool.
Expected output. _underscore_.
That character is encoded too, and it has to be.
Left alone, _minus_ could mean either an encoded hyphen or a name that really contained the letters minus.
Two things follow.
Given a name, you know which file EasyBuild will try to import.
And given a class name in a traceback, you can read it backwards to the software.
Step 5: what a toolchain lets you see¶
A dependency qualifies as a candidate only when built with a toolchain present in the package’s hierarchy. Determine what a hierarchy contains:
Expected output. Provide a chain from system up to foss-2025a, with the most minimal first, and include a note about two of the members.
A package on foss-2025a may depend on any component built with any member of that list.
A package on GCCcore cannot depend on a foss build.
The rule is not a matter of politeness; the dependency is not a candidate, causing the robot to report that it cannot locate something visible on disk.
Change 2025a to 2024a, then to 1999z.
Expected output. Provide a different chain, followed by a refusal indicating which generations the page knows.
A hierarchy reflects what is installed rather than the string. The site’s answer to differ from any of these.
What you now know¶
Five items are described, with the first four corresponding to the previous actions.
An easyconfig is Python code evaluated in a prepared namespace.
Unquoted names represent variables supplied by EasyBuild.
= %(…)s = is Python’s own formatting applied to a dictionary assembled by EasyBuild. A value to resolve to content not explicitly stated in the file.
The easyblock is derived by transforming the name.
A file lacking an easyblock line implicitly refers to an existing easyblock.
A toolchain defines the top of a hierarchy, and the hierarchy determines permissible dependencies.
The fifth point, observed twice, states that when resolution fails, the tool reports the failure instead of guessing.
A blank version, an unknown generation, or a structure the reader cannot follow each constitute unresolved cases.
Each case is reported.
Many costly errors arise from providing guesses that the tool declined to make.
Where to go next¶
Pick by what you are doing.
working out why a build failed – see An easyconfig is Python, then the parameter chapters 5 to 9.
moving a recipe to a newer stack – see A pin is for one generation, on why the version beside a dependency is not a minimum.
told a module exists but cannot load it – see The robot, on the three lists, and What “installed” means.
installing something with no admin rights – see Build your own, without asking anyone.
doing that on a machine with no stack – see EESSI, somebody else’s stack, on EESSI.
deciding whether to use EasyBuild at all – see the afterword.
If you would rather read straight through, An easyconfig is Python is next, and it starts with the sample from step 1.