Admin scripts
Root-owned admin scripts for CALC@HEI, historically living only as files in
/root/ on Chacha and Disco. As of 2026-08-04 they're mirrored in this
repo at provisioning/nodes/scripts/ for
versioning — edit there and redeploy, rather than editing in place on the
servers. calc/provisioning/deploy.sh pushes them to
/root/provisioning/nodes/scripts/ on both hosts — that's the path admins
and cron should use now, not the old flat /root/*.sh layout. rm_vscode.sh
is the only script with an automated caller (root's hourly crontab); deploy.sh
re-asserts that cron line on every run, and PRUNE_LEGACY=1 ./deploy.sh
removes the old flat copies once the new tree is confirmed in place.
/root is a local ext4 filesystem on each host's own root LV, not a shared
mount — the two servers each keep an independent copy. Checked by md5sum on
2026-08-04: the eleven scripts common to both hosts were byte-identical, i.e.
kept in sync by hand rather than actually shared.
Deployment drift found 2026-08-04
check_vscode.shandcheck_apptainer_instances.shexist on Chacha but were missing from/rooton Disco.migrate_apptainer_caches.shexists on Chacha only and was undocumented here until now.dance_config.cfg(asacctmgr loaddump) andslurm_disco.conf(a diff-comparison reference file, despite the name) are Chacha-only by design and aren't scripts — left out of the repatriation.
Removed 2026-08-04
add_slurmuser.sh— superseded bycalc/provisioning/accounts.yaml+provision.py(see SLURM configuration and user creation). Deleted from the repo and from/rooton both Chacha and Disco. It also had a broken group-membership check (if [ ! id -nGz "$1" | grep -qzxF 'slurm' ] ; then— a pipeline invalid inside[ ], failing on every run and always falling through tousermod -aG slurm, harmless only because that's idempotent).batch_add_sshusers.sh— never worked (the CSV/argument format it assumed never matchedadd_sshuser.sh's actual(username, uid)calling convention). Deleted from the repo and from/rooton both hosts.
Removed 2026-08-05
add_sshuser.shandadd_cifs_mount.sh— superseded byprovisioning/ansible/(see Ansible), which was consolidated into this repo the same day. Ansible'susers.ymlplaybook already creates the Linux account, deploys the SSH key fromconf/authorized_keys/<name>.pub, sets up the apptainer/dataset/results/ shared_datasets dirs and symlinks, and grants every user a blanketmount -t cifs //*/* /home/<user>/*sudoers rule unconditionally — making both scripts redundant for standard onboarding.accounts.yamldropped thessh_keyfield it briefly carried; it's SLURM-only again. See Managing compute users for the new onboarding flow.
Correctness issues found and fixed in the repo copy (2026-08-04)
These were bugs in the scripts as deployed; fixing them in the repo doesn't change the live copy on the servers until redeployed.
add_group.sh— group directories were createdchmod 670, which gives the grouprwxbut the owner (root) no execute bit. This only "worked" because root bypasses permission checks; a non-root process relying on the mode bits as documented would not have been able to traverse it. Changed to770. Doesn't retroactively fix already-created group directories.migrate_apptainer_caches.sh— hardcoded/data/apptainer, which is Chacha's path only; running it on Disco (where the apptainer cache lives under/data/disk01/apptainer) would have migrated to the wrong place with no warning. Added a hostname branch to pick the right path per host.
Users scripts
Scripts ran without arguments print the usage help. Onboarding (Linux account creation, SSH keys, CIFS mount rights) is now Ansible's job — see Ansible and Managing compute users. The scripts below cover what Ansible doesn't: quotas, project-group storage, and offboarding.
add_group.sh
Adds a group directory for a project with several users
./add_group.sh project 9011 "user.name1 user.name2"
It will create a shared directory in /data/shared/groups/project that will be available from both servers to user.name1 and user.name2 and a symlink to this directory on each one home dir /home/user.name/group/
NOTE : needs to be run first on Disco because Chacha can't modify the NFS directories that are shared by Disco
remove_sshuser.sh
Revokes a user's SSH/login access without touching their data — locks the
account (usermod -L, shell → /usr/sbin/nologin) and moves aside the
user's ~/.ssh/authorized_keys. Ansible has no removal logic, so it also
prints a reminder to drop the user from the Ansible roster
(provisioning/ansible/conf/users/*.yml and conf/authorized_keys/) —
otherwise the next playbook run silently re-creates access.
./remove_sshuser.sh jean.machin
Home dir, datasets and apptainer cache are left in place — see How to remove a user for the full offboarding checklist (quotas, SLURM, data retention).
fix_data_mount_ownership.sh
One-off fix for /data/disk01, /data/disk01/apptainer and their space
equivalents on Chacha, found owned by a regular user instead of
root:root at two directory levels — see
todo. Only chowns
those four specific paths, never recursive, so per-user leaf directories
underneath keep their existing ownership.
./fix_data_mount_ownership.sh
Chacha-only — Disco's equivalent tree was checked and is correctly
root:root. Idempotent — skips any path already root:root or missing.
Disk quotas
Quotas are declared for every user in calc/provisioning/nodes/users_quota.list
— one line per user, <user> <root_hard> <data_hard> <shared_hard> — and applied
by sync_quotas.sh, which picks the right mounts for the host it runs on (/
and /data on Chacha; /, /data/disk01 and /data/space on Disco). Soft
limits are derived at 90 % of the hard limit.
./sync_quotas.sh # dry run: what would change, plus who is over
./sync_quotas.sh --apply
Idempotent, and it refuses to hand anyone a limit below what they already hold,
which would leave their next write failing with EDQUOT. For a deliberate
reduction of someone already above the target, --grace sets the soft limit to
the target and the hard limit just above current usage: the 7-day grace
countdown starts and quota warns them, but writes keep working. --force
overrides the refusal outright and will break a running job.
Every run ends with a quota-pressure report — OVER, SOFT (in grace) and
FREE (no limit at all) per user per mount.
The Ansible common role deploys both files and runs the
check on every pass, failing the play if any account is missing a quota. It never
runs --apply: narrowing a quota should be a deliberate act, not a side effect of
a routine playbook run.
repquota, not quota -uquota -u <user> prints nothing for a filesystem where the user has no quota
yet. Any check built on it silently reads their usage as zero — for exactly the
accounts a backfill exists to fix. repquota reports usage whether or not a
limit is set. This cost five users a broken /data quota on
2026-08-20.
add_quota.sh
Superseded by sync_quotas.sh above, which covers every user from the versioned
list rather than one user per invocation. Kept for one-off manual overrides.
./add_quota.sh user.name 10G 200G 100G
You can also unset a quota : you just need to specify a unit like 0M to unset a quota.
./add_quota.sh user.name 0M 0M 0M
NOTE : Running twice doesn't affect the quota used.
Scripts list
- add_group.sh : Adds a group directory for a project with several users NOTE : needs to be run first on Disco because Chacha can't modify the NFS directories that are shared by Disco
- add_quota.sh : Adds a quota for a single user — superseded by sync_quotas.sh, kept for one-off overrides
- sync_quotas.sh : Applies users_quota.list to every user on the host; idempotent, refuses to narrow a limit below current usage, reports who is over
- remove_sshuser.sh : Revokes a user's SSH/login access (lock account, revoke key) without touching their data
- backup_slurm_data.sh : Backups the Slurm configuration files and backups the SLURM database : be advised it stops/starts the Mysql service to backup the DB
- check_apptainer_instances.sh : Checks if a process was launched with Apptainer outside of SLURM. Present on Chacha; missing from Disco's
/root. - check_vscode.sh : Checks any VScode process running. Present on Chacha; missing from Disco's
/root. - fix_data_mount_ownership.sh : One-off fix for
/data/disk01//data/spacedirectory ownership on Chacha. Run 2026-08-08. - install_fastfetch.sh : Extracts
fastfetch.tar.gz(must already be present in/root) into/usr/local/bin. - migrate_apptainer_caches.sh : One-off migration of a user's
.apptainercache dir to the per-user directory under the node's apptainer mount. Chacha only. - rm_vscode.sh : Ran automatically every hour by root's crontab (
5 * * * *,crontab -u root -l) on both hosts, to remove any VScode cache dirs on every user.deploy.shkeeps this entry pointed at/root/provisioning/nodes/scripts/rm_vscode.sh. - users_quota.list : The declared quota for every user, versioned in
calc/provisioning/nodes/; consumed by sync_quotas.sh