Populating a form.yml (in this case, for the MATLAB app) with available module versions?

Hi there,

Pretty simple question I think. I want to modify the MATLAB app form.yml to make selectable the actual versions we have visible on our system, so we don’t have to maintain the MATLAB app separately from MATLAB/the modules system.

I’ve seen a bunch of examples of custom forms, but I’m not a JavaScript or Ruby programmer, and I suspect that what I’m doing is a lot easier than any the things that those dynamic forms do, and that are somewhat easier than the documentation examples too.

I imagine this would also be helpful to other MATLAB users/to be documented.

I guess one requirement here might be that the OOD server has direct access to your modules tree, but that happens to already be true in our environment.

Thanks for the pointers!

@travert please advise.


To get a list of the versions for MatLab using jq you could run a query like:
$LMOD_DIR/spider -o spider-json $MODULEPATH | jq '.matlab[].Version'

This will output the versions of the MatLab app as strings.

Outputting this to a file, then using the contents of that file to then populate the form.yml file for the versions would ensure the app and system match.

Is this the type of information you were looking for? Sorry, I’m a little unsure if this actually addresses what you were after.

Yeah. I guess ideally I would populate at the time the form was loaded, but I’ve seen reasons you wouldn’t want to do that (person might get no versions at all if there were a temporary delay, etc.).

I guess I’m not clear on the workflow here… I could just have the above command run periodically and update the file, and then the form.yml will read that file, or something else?

I did this with our MATLAB app form. I wanted to present “MATLAB ver#” as the drop down, and the option value be the Version.fullname which is what I use to load the module in the script.

@travert Please feel free to comment on any issues with doing it this way. I’m sure this is not the most efficient/best way to do it. :slight_smile:

In the top of form.yml.erb:

  require 'open3'
  # Use spider to get all current app version data in json format
  get_app_versions_cmd = "/apps/lmod/lmod/libexec/spider"
  get_app_versions_args = [ "-o", "spider-json", "/apps/mf/gb/" ]
  get_app_stdout, get_app_stderr, get_app_status = Open3.capture3(get_app_versions_cmd , *get_app_versions_args) # stdout is json string
  # use jq to parse json and output list of formatted select widget lines e.g. [ "Name Ver", "module/version" ]
  jqo, jqe, jqs, = Open3.capture3("/usr/bin/jq --compact-output '.matlab[] | [ \"MATLAB \" + .Version,.fullName ] '",:stdin_data=>get_app_stdout)
  @app_versions_list = []
  #put lines in array "app_versions_list" for use in form.
  jqo.each_line do |aver|
  #  puts aver

Then for the attribute entry:

    widget: select
    label: "MATLAB Version"
    help: "This chooses the version of the software you want to load."
    <%- @app_versions_list.each do |h| %>
      - <%= h %> 
    <%- end %>

Thanks @blixuga; looking forward to seeing what @travert has to say.

Thanks to both of you for your time!

Because this method would remove any kind of version control, it’s not something I’ve done because that is a very important part of any process we use.

That said, I can still imagine scenarios where this can make sense.

@novosirj for the workflow I was basically thinking the same of running the command as a cronjob to then output to a file which would then be handled by another cronjob which would use a script to process what was written to the file to then write to the form.yml. This lets you also choose which language/tech you would prefer to parse that data and write it with since it sounds like Bash or a more admin flavored language might be what you prefer.

I suggested writing to a file mainly because then you can at least see what was captured and maybe have some visibility if for whatever reason the form renders incorrectly or there’s some error. It also just seems safer than running the command to also then pipe the output to the form directly, but I’m just going on my own preference here for having some kind of history at least to see changes (I’d also have those files role after some time I felt happy with). But, that’s also bringing version control back in some way, so that might not make total sense.

@blixuga has a pretty clever solution that would eliminate the above work flow though, very cool solution for something like this actually. I guess my only question would be how much lag there is for this to run when the form is loaded for the user, which a cronjob might avoid, but if that lag is negligible then it seems like a very good solution to what is needed. Though, it is also in Ruby :wink: and the post sounded like you were trying to avoid such solutions.

I’m not so much interested in avoiding Ruby as don’t know it now and am not sure that for something this simple that it would pay to learn it.

Understood about the points re: version control. I guess my counter would be that if there’s version control maintaining the modules/software version installs, this is effectively rendering that, and is not a thing that needs to be preserved on its own, but I do think there is some value to something not being able to change without you changing it (will never be a large part of what I do).

Will test it out on our system. I don’t get the feeling that this is something that’s run even once per minute (maybe not once per hour), so the cumulative time wasted might be negligible.