Allow non-admin users to set value for custom variable at instance and target level

Hi there, I am a university computing center staff managing a multi-user cryosparc instance which connects to a HPC cluster (Slurm). We implemented custom variables that enable endusers (non-admin) to provide some personally identifiable slurm flags (eg account, qos) at job level for allocation accounting and usage tracking purposes. Current situation is user has to repeatedly input these variables for every single job though they dont change for a specific user. This also causes chained job to fail such as “extensive validation” because the custom values fed to the 1st job do not get propagated to the job chain. I am wondering if there is a way that would allow (non-admin) users to set value for custom variable at instance and target level, and these custom values only apply to user who set it. Thanks

1 Like

Welcome to the forum @drewli.
Did you consider including in your script template a dictionary where you map cryosparc_username (guide) to an account number?:

{% set accounts = {"csuser2@org.internal": "acct002", "csuser3@org.internal": "acct123"} %}

and set the account like

#SBATCH --account={{ accounts[cryosparc_username] | default('acct000') }}

?

2 Likes

@wtempel I have a slightly related question. Is there a way to set custom variables on instance and target levels via CLI?

@wtempel Thank you for the tips! I was able to get something proof-of-concept working following this route.
We have a json file “user_account.json” that maps user email to slurm account
{
“userA_email”: “userA_slurm_account”,
“userB_email”: userB_slurm_account
}

A script “before_sbatch.sh” that runs right before “sbatch” command. It takes {{ cryosparc_username }} and {{ script_path_abs} as inputs, converts json to bash dict and looks up for user slurm account by email, then injects account string into {{ script_path_abs}.

#!/usr/bin/env bash
user_name="$1"
script_path="$2"
declare -A account_dict=$(
  jq -r '"(",(to_entries | .[] | "["+(.key|@sh)+"]="+(.value|@sh)),")"' \
  /FULL_PATH_TO/user_account.json
)
account=${account_dict[$user_name]}
sed -i "s/000_ACCOUNT_000/$account/" $script_path

cluster_script.sh:
…# placeholder where user slurm account will be inserted
#SBATCH -A 000_ACCOUNT_000
…
cluster_info.json:
{…
qsub_cmd_tpl": “/FULL_PATH_TO/before_sbatch.sh {{ cryosparc_username }} {{ script_path_abs }} && sbatch {{ script_path_abs }}”,
…}

I just realized the code snippet you gave was using jinjia dictionary and templating language. I thought you were referring to dictionary in shell. I agree using the builtin jinja would be much cleaner. I will change to it. Thanks again!

Update: I just tried it out and it works well. One quick question, would it be possible to save the dict variable “accounts” in a separate file and reuse it in different jinja templates – we have multiple lanes (cluster_scripts.sh files). I am new to jinja. I just tried include, import, and extends but neither seems to work…Thanks

Hi @bsobol,

@wtempel is currently away, but here is the response he drafted:


You may set instance-level custom variables using the CLI and a python dictionary:

cryosparcm cli "set_cluster_configuration_custom_vars({'custom_ram_mutliplier': 3, 'custom_max_ram_gb': 127})"

For the preparation of the dictionary, it may be useful to retrieve currently set instance-level custom variables:

cryosparcm cli "get_cluster_configuration_custom_vars()"

You may set target-level custom variables with a command like

cryosparcm cli "set_scheduler_target_property(hostname='cluster1', key='custom_vars', value={'custom_ram_mutliplier': 3, 'custom_max_ram_gb': 127})"

where you specify the name of the cluster, cluster1 in this example, lane as the “hostname”.
Currently specified target-level custom variables can be queried with a command like

cryosparcm cli "get_targets_by_lane(lane_name='cluster1')[0]['custom_vars']"

These functions may be used for CryoSPARC version v4.7, but may no longer work in future releases of CryoSPARC.


Hope this helps!

2 Likes