Cette page a été traduite automatiquement de l’anglais et peut contenir des erreurs. Original en anglais

Installation du logiciel de simulation

Le paquet axqua.install installe TELEMAC, OpenFOAM, ParaView et VisIt en exécutant les scripts d’installation publiés. Il détecte le système d’exploitation, compose un plan qui peut être lu avant que tout ne tourne, exécute le plan comme un processus détaché, et entre le résultat dans le profil de l’ordinateur. La commande axqua install et les assistants d’installation de l’extension QGIS sont les deux extrémités de ce paquet.

Système d’exploitation

What kind of computer this is, as far as an installation is concerned.

The installer scripts exist per operating system release, so the first thing an installation needs to know is which release it runs on. The answer is the base of the system, the release whose packages it uses: debian12, ubuntu22 or ubuntu24. Linux Mint reports its Ubuntu base in UBUNTU_CODENAME and is mapped through it. A derivative that is not recognized has no base, and a user who knows the base of their system can name it (--base).

ID_LIKE is deliberately not enough to assign a base: Ubuntu itself says it is like Debian, and its packages are not Debian’s. The rule and the three bases are the ones of the installer scripts, so that aXqua never offers an installation the scripts refuse.

The Windows Subsystem for Linux is Linux here: the simulation programs are built and run inside the distribution. It is reported separately because an installation must stay in the Linux file system; a folder below /mnt/c is slow by an order of magnitude and the OpenFOAM installer refuses it.

Standard library only.

axqua.install.host.BASES = {'debian12': 'Debian 12', 'ubuntu22': 'Ubuntu 22.04', 'ubuntu24': 'Ubuntu 24.04'}

The releases the installer scripts support, with the name a person reads.

class axqua.install.host.Host(system, distro='', version='', codename='', base='', wsl=False, machine='', pretty='')[source]

Bases : object

The computer an installation would run on.

Paramètres:
system: str
distro: str = ''
version: str = ''
codename: str = ''
base: str = ''
wsl: bool = False
machine: str = ''
pretty: str = ''
property supported: bool

Whether the installer scripts cover this system at all.

property x86_64: bool
describe()[source]

One line for a person.

Type renvoyé:

str

as_dict()[source]
Type renvoyé:

dict

axqua.install.host.base_of(os_release)[source]

The supported release this system is built on, or "".

Paramètres:

os_release (Mapping[str, str])

Type renvoyé:

str

axqua.install.host.detect(*, os_release=None, system=None, release=None, machine=None, base=None)[source]

Describe this computer. Every argument replaces what would be read, for tests.

base is the user’s own statement about an unrecognized derivative and wins over what the system reports.

Paramètres:
  • os_release (str | None)

  • system (str | None)

  • release (str | None)

  • machine (str | None)

  • base (str | None)

Type renvoyé:

Host

axqua.install.host.parse_os_release(text)[source]

The KEY=value lines of /etc/os-release as a dictionary.

Paramètres:

text (str)

Type renvoyé:

dict[str, str]

Plans d’installation

From the installer scripts to a plan that can be read before anything runs.

aXqua does not install TELEMAC or OpenFOAM by itself. It runs the installer scripts of the repository named in REPOSITORY, at the commit named in PINNED, which is the version this release of aXqua was tested with. Nothing is taken from a moving branch unless the user asks for it (--ref main).

The OpenFOAM installer of that repository is shipped with aXqua (BUNDLED, MIT license), together with the source files of Olsen’s sediment solvers (GPL-3.0-or-later), because Olsen’s web site is the only place they are published and it answered HTTP 502 in October 2026. The OpenFOAM and the ParaView/VisIt installations run that copy and download nothing from the repository; a local copy ($AXQUA_INSTALLERS) or another commit (--ref) still replaces it.

What aXqua adds to the scripts is what a click needs and a terminal does not:

It asks no password. The scripts install system packages with sudo, which needs a terminal. aXqua reads the package list out of the script (so the two cannot drift apart), finds what is missing, and hands the one command to an administrator. The scripts then run in their own mode without system packages (--skip-apt, or simply without --install-system-packages), as the ordinary user.

It says beforehand what will happen. A Plan lists the commands, the folder, the files that will exist afterwards, and everything that is not in order as findings. The runner executes exactly the commands of the plan.

It enters the result into the profile. outputs maps a key of the profile (solvers.telemac.setup_script) to the file the installation produces.

The scripts run in a cleaned environment: an active conda environment would otherwise put its own cmake, compilers and MPI in front of the system’s, and the build would mix the two.

axqua.install.recipes.BUNDLED = PosixPath('/srv/private/axqua/src/axqua/install/vendor')

The folder that holds aXqua’s own copy of OpenFOAM-installer (see the module text).

axqua.install.recipes.ENV_INSTALLERS = 'AXQUA_INSTALLERS'

A local copy of the installer scripts, used instead of downloading them.

axqua.install.recipes.REPOSITORY = 'https://github.com/Ecohydraulics/numerical-software-installers'

Where the installer scripts are published, and the commit this release was tested with.

axqua.install.recipes.SCOPES = ('user', 'system')

in the home folder, by the user alone, no administrator rights. system: in a folder below /opt that every user of the computer can run from and nobody but an administrator can change.

Type:

For whom a program is installed. user

axqua.install.recipes.SYSTEM_PATH = '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin'

the programs of the operating system first. Everything the installers build against is a system package, compiled with the system’s compilers. A compiler that somebody once built into /usr/local/bin would otherwise come first, and what it compiles cannot be linked with them.

Type:

The search path of an installation

class axqua.install.recipes.Options(folder=None, scope='user', tag='', salome=None, telemac_examples='inputs', reuse_openfoam='auto', jobs=None, visualization=True, visit=True, examples=False, smoke_test=True, installers=None, ref='', base='', bind=True, reinstall='')[source]

Bases : object

What a user can choose. Everything has a default that works.

Paramètres:
folder: Path | None = None
scope: str = 'user'
tag: str = ''
salome: Path | None = None
telemac_examples: str = 'inputs'

how much of its example cases to download. inputs: the files a run of an example reads; all: reference results and manuals as well; none: the steering files only, which come with the source code.

Type:

TELEMAC

reuse_openfoam: str = 'auto'
jobs: int | None = None
visualization: bool = True
visit: bool = True

Whether VisIt is installed with the postprocessors. Recommended, and a choice: without it, ParaView alone is entered in the profile.

examples: bool = False
smoke_test: bool = True
installers: Path | None = None
ref: str = ''
base: str = ''
bind: bool = True
reinstall: str = ''

What happens to an earlier installation in the folder (see REINSTALL).

classmethod from_dict(data)[source]
Paramètres:

data (dict[str, Any] | None)

Type renvoyé:

Options

as_dict()[source]
Type renvoyé:

dict[str, Any]

class axqua.install.recipes.Plan(target, host, options, folder, installers=None, steps=<factory>, needed=<factory>, missing=<factory>, unavailable=<factory>, package_note='', outputs=<factory>, optional_outputs=<factory>, expects=<factory>, estimate='', notes=<factory>, findings=<factory>)[source]

Bases : object

What an installation would do. Nothing in it has happened yet.

Paramètres:
target: str
host: Host
options: Options
folder: Path
installers: Path | None = None
steps: list[Step]
needed: list[str]
missing: list[str]
unavailable: list[str]
package_note: str = ''
outputs: dict[str, str]
optional_outputs: list[str]

Keys of outputs that are an addition to what this target installs. A missing one is reported and does not fail the installation.

expects: list[str]
estimate: str = ''
notes: list[str]
findings: list[Finding]
property ready: bool

Whether the installation can be started at all.

A plan without a command can still be one: ParaView alone is a package of the operating system, and what is left to do is to enter it in the profile.

as_dict()[source]
Type renvoyé:

dict[str, Any]

class axqua.install.recipes.Step(name, argv, cwd='', env=<factory>, optional=False, admin=False)[source]

Bases : object

One command of an installation. env adds to the cleaned environment.

Paramètres:
name: str
argv: list[str]
cwd: str = ''
env: dict[str, str]
optional: bool = False

what it adds is reported as missing, and the program itself is installed.

Type:

An optional command may fail without failing the installation

admin: bool = False

Run with the rights of an administrator (pkexec, or sudo in a terminal).

as_dict()[source]
Type renvoyé:

dict[str, Any]

classmethod from_dict(data)[source]
Paramètres:

data (dict[str, Any])

Type renvoyé:

Step

axqua.install.recipes.admin_command(target, missing)[source]

The one command an administrator runs to install missing.

Paramètres:
Type renvoyé:

str

axqua.install.recipes.clean_environment()[source]

The environment an installer runs in: the system’s, and nothing of conda.

The proxy and certificate variables are kept, because without them a download behind a proxy fails; the display variables are kept for the graphical installers of the postprocessors.

Type renvoyé:

dict[str, str]

axqua.install.recipes.default_folder(target, scope='user')[source]

Where target is installed when the user names no folder.

For all users, the folders below /opt are those that the discovery of axqua.core.machine searches, so the aXqua of every other user of the computer finds the installation without a profile entry.

Paramètres:
Type renvoyé:

Path

axqua.install.recipes.shadowed_tools(local=PosixPath('/usr/local/bin'), system=PosixPath('/usr/bin'))[source]

Build programs of the operating system that /usr/local/bin overrides.

Paramètres:
Type renvoyé:

list[str]

axqua.install.recipes.elevation()[source]

How this session can ask for administrator rights: pkexec or "".

pkexec shows the password dialog of the desktop, so aXqua never sees a password. It needs a graphical session; in a plain terminal session the command is shown instead and the administrator runs it.

Type renvoyé:

str

axqua.install.recipes.fetch_installers(options, *, root=None)[source]

The folder with the installer scripts, downloading them when needed.

A local copy (options.installers or $AXQUA_INSTALLERS) is used as it is and never modified. Otherwise the repository is cloned into aXqua’s data folder and set to the requested commit. A commit is fetched once; a branch is updated every time.

Paramètres:
Type renvoyé:

Path

axqua.install.recipes.find_openfoam()[source]

The etc/bashrc of an OpenFOAM v2406 that is already on this computer.

Type renvoyé:

Path | None

axqua.install.recipes.install_packages(target, missing, log_dir)[source]

Install missing through the password dialog of the desktop. Never raises.

The command is the one admin_command() shows, run by pkexec instead of sudo. The names were checked against the pattern of a package name before, so nothing but package names reaches the shell that joins the two apt-get calls.

Paramètres:
Type renvoyé:

dict[str, Any]

axqua.install.recipes.installer_python(checkout)[source]

An interpreter that can run the OpenFOAM installer, or None.

The installer is tried with the interpreter that runs aXqua first and then with the newer ones on the search path. Trying is the only reliable test: a version of the installer uses a form of formatted string that Python accepts from 3.12 on, and a later version may not.

Paramètres:

checkout (Path)

Type renvoyé:

str | None

axqua.install.recipes.packages_needed(target, checkout, host, options)[source]

The system packages target needs, as its installer script names them.

Paramètres:
Type renvoyé:

list[str]

axqua.install.recipes.packages_state(names)[source]

(missing, unavailable) of names on this system.

dpkg-query says what is installed. What it does not know is then put to apt-get --simulate, which needs no privileges and resolves what the first question cannot: a name that another installed package provides is not missing, and a name the package sources do not offer cannot be installed at all.

Paramètres:

names (list[str])

Type renvoyé:

tuple[list[str], list[str]]

axqua.install.recipes.plan(target, options=None, *, host=None, check_packages=True)[source]

What installing target on this computer takes. Never raises for a finding.

The installer scripts are read for this, because the list of system packages is read out of them: those of TELEMAC are downloaded (2 MB), the OpenFOAM installer is the copy shipped with aXqua. A plan with an error finding has no steps that could be started; a plan with warnings can.

Paramètres:
Type renvoyé:

Plan

Exemple cas de TELEMAC

The example cases that TELEMAC is distributed with, reduced to what a run reads.

These are TELEMAC’s own examples, in the folder examples of a TELEMAC installation. They are not the example cases of aXqua.

TELEMAC is distributed with about 830 example cases. Their steering files, boundary files and Fortran files are ordinary files of the repository and come with the clone. Their binary files are kept in Git LFS: 1,375 files and 1.4 GB for version 9.1.1, plus the manuals and notebooks. Git fetches these one by one when it checks the working tree out, which on the development computer took more than an hour for an installation whose build takes minutes.

Most of that is not needed to run an example. Two thirds of the files are reference results, with which the validation system of TELEMAC compares a run, and files that a run writes. What a run reads is the geometry, a previous computation file where an example continues one, and a few data files: 363 files and 460 MB.

Which files those are is not guessed from their names. TELEMAC states it itself: every file keyword in its dictionaries (sources/*/*.dico) says whether the file is read (LIT) or written (ECR). needed_inputs() reads the dictionaries of the installation at hand, collects the files that the steering files of the examples name under a keyword that is read, and keeps those that are still LFS pointers. A new version of TELEMAC with other keywords or other examples therefore needs no change here.

fetch_inputs() then asks Git LFS for exactly these files, in a few requests of many files each. That is also much faster per megabyte than the checkout, because LFS transfers several files at a time when it is asked for a list.

The installation runs the installer script with GIT_LFS_SKIP_SMUDGE=1 first, so that the checkout leaves every LFS file as a pointer of a few lines, and this module afterwards. A failure here (the download server of TELEMAC limits requests) leaves a working TELEMAC and examples without their geometry; it is reported and can be repeated with axqua install telemac-examples <folder>.

axqua.install.telemac_examples.POINTER = b'version https://git-lfs.github.com/spec/v1'

How an LFS pointer file begins.

axqua.install.telemac_examples.fetch_inputs(home, *, chunk=60, retries=3, wait=45.0, pull=<function _pull>, say=<built-in function print>)[source]

Download the input files of the example cases. Returns what was done.

{"wanted": n, "fetched": n, "megabytes": x, "missing": [paths]}. A request that fails is repeated after wait seconds, up to retries times, because the server refuses requests for a while when it has received many.

Paramètres:
Type renvoyé:

dict[str, Any]

axqua.install.telemac_examples.is_pointer(path)[source]

Whether path is a Git LFS pointer and not the file it stands for.

Paramètres:

path (Path)

Type renvoyé:

bool

axqua.install.telemac_examples.needed_inputs(home, *, folder='examples')[source]

The LFS pointers below <home>/<folder> that a run of an example reads.

Paths relative to home, sorted. Files that are already downloaded are not listed, so a second call after a download returns what is still missing.

Paramètres:
Type renvoyé:

list[Path]

axqua.install.telemac_examples.pointer_size(path)[source]

The size in bytes of the file an LFS pointer stands for (0 if unknown).

Paramètres:

path (Path)

Type renvoyé:

int

axqua.install.telemac_examples.read_keywords(home)[source]

The file keywords of this TELEMAC under which a run READS a file.

English and French names, in upper case. From the SUBMIT entry of each keyword in the dictionaries: its fifth field is LIT for a file that is read and ECR for one that is written.

Paramètres:

home (Path)

Type renvoyé:

set[str]

Exécution d’une installation

Run an installation as a process of its own, and say how far it is.

Building TELEMAC takes most of an hour and compiling OpenFOAM several, so an installation must not live inside the window that started it. It is a folder below aXqua’s data folder, like a job:

plan.json what was started, written once status.json how far it is; written only by the process that runs it install.log everything the installer printed runner.log what aXqua itself had to say

start() writes the folder and starts axqua install run <folder> detached, so that QGIS can be closed. read() reports the state and notices by itself when the process is gone without a result (the computer was restarted): an installation never stays « running » forever.

When the installer has finished, the runner does what the scripts cannot: it checks that the promised files exist (the TELEMAC script ends with success even when its own check of the build failed), enters the installation into the profile of this computer, and enters the environment once to see whether the program is really there.

Each command runs in a session of its own. Cancelling therefore reaches the whole tree of a build (make and its compilers) and nothing else, whether the runner was started detached or in a terminal.

axqua.install.runner.bind(outputs, *, probe=True)[source]

Enter an installation into the profile of this computer and check it.

Returns where the profile was written, what the check found about the new entries, and the keys of every program the profile names afterwards.

A computer without a profile gets one, filled with what aXqua finds on it, exactly as Create profile does. A profile that exists but cannot be read is left alone, because writing over it would discard whatever its owner was in the middle of.

Reading, changing and writing happen under a lock (_writing_profile()): two installations may end in the same moment, and each adds an entry of its own.

Paramètres:
Type renvoyé:

tuple[Path, list[Finding], set[str]]

axqua.install.runner.cancel(ident, *, grace=20.0)[source]

Stop an installation. What is already downloaded and built stays.

Paramètres:
Type renvoyé:

dict[str, Any]

axqua.install.runner.execute(folder, *, echo=False, interactive=False)[source]

Run the commands of an installation folder. This is the runner process.

interactive: this process has a terminal, where sudo can ask for the password of an administrator step.

Paramètres:
Type renvoyé:

int

axqua.install.runner.installs_root()[source]
Type renvoyé:

Path

axqua.install.runner.latest(target, *, active_only=False)[source]

The newest installation of target, or only one that is still running.

Paramètres:
Type renvoyé:

dict[str, Any] | None

axqua.install.runner.list_all()[source]

Every installation on record, newest first.

Type renvoyé:

list[dict[str, Any]]

axqua.install.runner.read(ident, *, lines=0)[source]

The state of one installation, corrected if its process has vanished.

Paramètres:
Type renvoyé:

dict[str, Any]

axqua.install.runner.start(plan, *, detach=True, echo=False)[source]

Record plan and run it. Detached, this returns at once.

Paramètres:
Type renvoyé:

dict[str, Any]

axqua.install.runner.tail(path, lines=40)[source]

The last lines of a log, without reading a file of many megabytes whole.

Paramètres:
Type renvoyé:

str