Skip to main content
Part of CALC@HEI, the HEI research computing infrastructure — governance in transition, currently operated by the ISC staff.

Managing compute users

Every onboarding/offboarding goes through a PR, approved by an admin

Never push these changes (conf/users/, conf/authorized_keys/, accounts.yaml) straight to main. Open a PR for every user add/remove and get an admin's approval before merging — the diff is the audit trail for who was granted or revoked access, and when. The ansible-playbook, provision.py --apply and add_quota.sh steps still need a human with real access to run them after merge; the PR is only the traceability gate, not a substitute for review of what's about to run.

When someone asks for more information, or to access CALC@HEI

When a user contact us to ask for access, we give the documentation link first : (TODO : This would be later the portal page)

Here is an email template, we can add Pierre André in CC

Subject : Demande d'accès à CALC@HEI

Bonjour x,

Merci pour ton message et pour ton intérêt pour CALC@HEI, l'infrastructure de calcul pour la recherche : pour faire ta demande d'accès, tu as juste un formulaire à remplir et tout est expliqué içi : CALC@HEI

Si tu as des questions, n'hésites pas à venir nous voir ou nous appeler directement.

Bien cordialement,

(signature)

Subject : CALC@HEI access

Hello x,

Welcome to CALC@HEI, the HEI research computing infrastructure !

Your access is ready : we invite you to read our documentation to run jobs on our infrastructure

If you have any question or see anything missing in the documentation, don't hesitate to contact us so we can fix that.

About the budget on infrastructure, I let you discuss with Pierre-André.

Best regards,

( signature)

Get info from the online form

Check first that everything looks fine from the technical perspective regarding the incoming project.

Prepare :

  • username : firstname.lastname (generally the part in front of the @hevs.ch email address should be fine)
  • SSH public key
  • Project name

Prepare playbook

Linux accounts, UID/GID and SSH keys for Chacha/Disco are managed by Ansible, not by a script in this directory — see Ansible for the full picture and the known gap (conf/users/*.yml UIDs can disagree with what's live; check getent passwd on a real node before trusting the YAML).

Check uid/gid to assign

Add the first available uid/gid to provisioning/ansible/conf/users/uid-others.yml (the dance_uids cohort in conf/users/roles.yml, covering Chacha/Disco/Mambo).

cd provisioning/ansible/conf/users/
vim uid-others.yml

uid_others:
- { id: '25506', name: 'urs.mueller', shell: '/bin/bash', email: 'Urs Mueller <urs.mueller@hevs.ch>' }

NOTE : double check you correctly took an id not already assigned, no error control here.

Also burn that number in the rack's UID register, provisioning/uid/uid-map.csv — dance doesn't read it, but the rack's uid-alloc.py does, and dance's numbers land inside its bands (see UID allocation). Append a row with the same uid/gid, empty email, status reserved, and note conf/users value for <user>; no live number confirmed:

25526,25526,urs.mueller,,reserved,conf/users value for urs.mueller; no live number confirmed

Add SSH key

Add the public key from the form as provisioning/ansible/conf/authorized_keys/urs.mueller.pub — that directory is the source of truth for SSH access across the whole fleet, including Chacha/Disco.

Apply the Ansible playbook

From provisioning/ansible/:

ansible-playbook users.yml -e 'h=dance'

This creates the Linux account (with the UID from conf/users/), deploys the SSH key, and sets up the apptainer/dataset/results/shared_datasets directories and symlinks — see the Ansible doc for setup (setup.cfg, vault password) if this is the first run.

Configure SLURM account

Accounts and users are declared in provisioning/accounts.yaml and applied with provisioning/slurm/provision.py, run from Chacha (it owns slurmdbd). See SLURM configuration for how the tiers/QOS mapping works.

  1. If it's a new project, add it under groups: with the tier matching the SLA from the form (premium_rs or standard_rs).

  2. Add the user under users::

    • username
    • group: the project name from step 1 (or an existing group, or students)
    • partition: dance for the whole cluster, or chacha / disco for just one server
    - username: urs.mueller
    group: ProjectName
    partition: dance
  3. Apply it from provisioning/slurm/ (it reads ../accounts.yaml):

    ./provision.py --validate # structure check, no cluster access needed
    ./provision.py # dry run — prints the sacctmgr commands
    ./provision.py --apply # actually creates the account/user

    --apply only ever adds what's missing; it never touches an existing association's limits — that's what --check reports, for a human to decide on.

Configure quotas

Run the script from Disco first, then Chacha : add_quota.sh

With :

  • username
  • hard limits quota for /, /data, and /data/shared
./add_quota.sh urs.mueller 20G 100G 100G

NOTE: For students, quota on root filesystem should be 10G to make them learn to really pay attention to where the put their images / containers / datasets. For researchers it is 20G to allow quick testing as long as they don't cumulate containers in their home without cleaning

Send an email to the user

Using this template, and by adding Pierre André in CC :

Subject : Accès à CALC@HEI

Bonjour x,

Bienvenue sur CALC@HEI, l'infrastructure de calcul pour la recherche !

Ton accès vient d'être créé : nous t'invitons à lire notre documentation pour pouvoir lancer des jobs sur notre infrastructure.

Si tu as des questions ou si tu vois une information qui manque dans la documentation, n'hésites pas à nous contacter pour qu'on puisse résoudre ça.

Bien cordialement,

(signature)

How to move a user to another account

Change the user's group in provisioning/accounts.yaml, then from provisioning/slurm/ (each step dry-runs without --apply, and every write needs sudo):

sudo ./provision.py --apply # associations under the new account
sudo ./provision.py --fix-accounts --apply # repoint DefaultAccount
sudo ./provision.py --prune-extra --apply # drop the association they left

The order matters: --apply creates the account first if the group is new, which the other two do not. --prune-extra holds back any association the user still has queued jobs against, so if they were running something, re-run it once their queue has drained — until then those jobs keep charging the old account. See SLURM configuration.

How to remove a user

Offboarding revokes access but doesn't delete data — home dir, datasets and apptainer cache are left in place so a deliberate retention decision can be made separately, later.

  1. Revoke SSH/login access. Run from Disco, then Chacha : remove_sshuser.sh

    ./remove_sshuser.sh urs.mueller

    This locks the account (usermod -L, shell → /usr/sbin/nologin) and moves the SSH key aside on the user's ~/.ssh/authorized_keys.

    Also remove the user from the Ansible roster — delete their entry from provisioning/ansible/conf/users/uid-others.yml (or whichever cohort file they're in) and their key from provisioning/ansible/conf/authorized_keys/urs.mueller.pub. Ansible only creates/converges towards present state — it has no removal logic — so the next ansible-playbook users.yml -e 'h=dance' run would otherwise silently reset the shell back to /bin/bash and re-add the SSH key, undoing this step.

  2. Reset quotas so the account no longer counts against the shared filesystems, run from Disco then Chacha : add_quota.sh

    ./add_quota.sh urs.mueller 0M 0M 0M
  3. Remove the SLURM user. Delete the user's whole entry from provisioning/accounts.yaml, then from provisioning/slurm/:

    ./provision.py --prune # dry run — prints the sacctmgr commands
    ./provision.py --prune --apply # actually removes the association

    See SLURM configuration. If the user was the last member of a project account, deciding whether to also remove that account is a separate judgment call — --prune only ever removes users.

  4. Check for extras that aren't part of standard onboarding and clean up if present: a group symlink at /home/urs.mueller/group (add_group.sh). Note the generic CIFS-mount sudoers rule Ansible applies to every user (/etc/sudoers.d/ursmueller) isn't cleaned up by locking the account — it becomes moot once the account itself is locked and removed from the Ansible roster (step 1).

  5. Data retention. Home dir, datasets and apptainer cache are intentionally left untouched by the steps above. Archiving or deleting them is a separate decision — check with the user/PI before removing anything.