Struggling to enable dynamic forms

I’m trying to make use of the new dynamic forms for my interactive apps. Both for account+partition but also for limiting invalid options using data-option-for-cluster-xxx: false.

My impression from the docs was that I just had to enable the option in a ondemand.d/dynamic.yml:

bc_dynamic_js: true
brand_bg_color: "#FF0000"

(I also added the color to verify that this config is read).

and then I should just be able to use it with

cluster:
  - "vera"
form:
  - cluster
  - bc_account
  - bc_num_hours
  - node_type
  - version
  - working_dir
  - bc_email_on_started
attributes:
  node_type:
    widget: "select"
    label: "Node type"
    options:
      - [ "T4:1", "T4:1"]
      - [ "T4:2", "T4:2", data-option-for-cluster-vera: false ]
...

but my vera cluster still shows T4:2 as an option. My app doesn’t supply it’s own form.js, which I thought was only necessary if you did strange things.

I also have tried to enable auto_account things, but i’m not sure I’m using the right syntax. I just listed them under attributes.

attributes:
  auto_accounts:
  auto_queues:
...

I also tried bc_osc_jupyter (fork) which does have it’s own form.js, but even there, no good.

What could I be missing here? Any deeper digging I can do to figure out what I might be missing?

For the auto_* fields, make sure and place those under the form stanza otherwise they don’t show up as attributes.

For the other problem, I’m not sure if an ood_portal_update is needed once you add those fields in your ondemand.d/dynamic.yml. I don’t see it in the docs, but I would think ood needs to pick this up and put it in memory so that seems like it should be needed there. Did the color change that you set without that command?

I realize now that I forgot to mention I run a container build, based on https://github.com/OSC/ondemand/blob/master/Dockerfile (with some minor additions for our system), so I do re-generate the portal each time i restart my container, and yes, the color changed.

I just saw 'data-filepicker: true' doesn't show 'choose path' button - #2 by mustafaarif and realized i have the exact same situation, so I’m starting to suspect perhaps this container is missing some vital parts, as I don’t seem to be getting any “form.js” anywhere in my container.

Have you tried setting this option in /etc/ood/config/apps/dashboard/env and the option is OOD_BC_DYNAMIC_JS=TRUE
Restarting the user nginx webserver might be required after making this change.

I have form.js file in my each application root directory.

Thank you both for the suggestions.
Moving the auto_* fields under form, I do get the entire list of projects and partitions, but there is no dynamic changes when selecting this (just like for the other select widgets), so I must still be missing something.

I have managed to identify enabling bc_dynamic_js: true does add an extra script at the end of the form:

<script src="/pun/sys/dashboard/assets/batch_connect-033c63485c232ee96ec2642db85159118cde9e46f3d778885d0f69e3bccde9b9.js" nonce="e/uBPS0QgxCSMV3RDlgQsQ=="></script>

which seems aligns with apps/dashboard/app/views/batch_connect/session_contexts/_form.html.erb

<%= javascript_include_tag 'batch_connect', nonce: true if Configuration.bc_dynamic_js? %>

So, so far so good, it seems to be picked up by OOD, but this JS code (which unfortunately isn’t readable) just isn’t removing any options from the select widget.
The custom form.js I added manually to the app filepicker works fine.

I also expected auto_* forms to differ thanks to dynamic_accounts in:

apps/dashboard/app/lib/smart_attributes/attributes/auto_accounts.rb

but I’m not seeing any data-option-for-auto-accounts-xxx in the final HTML, I just get the entire list of all queues and accounts (most of which aren’t valid for my user):

<div class="form-group"><label for="batch_connect_session_context_auto_accounts">Account</label><select class="form-control" name="batch_connect_session_context[auto_accounts]" id="batch_connect_session_context_auto_accounts">
    <option value="c3se-staff">c3se-staff</option>
</select></div>
<div class="form-group"><label for="batch_connect_session_context_auto_queues">Partition</label><select class="form-control" name="batch_connect_session_context[auto_queues]" id="batch_connect_session_context_auto_queues">
    <option value="vera">vera</option> <-- this should have data-option-for-accounts...
    <option value="teobio">teobio</option>  <-- this should have data-option-for-accounts...
    ...
</div>

which is the same output regardless of if bc_dynamic_js is enabled or not.

Ok, looking back at this I think it might be a simple syntax error at this point.

Instead of:

...
attributes:
  node_type:
    widget: "select"
    label: "Node type"
    options:
      - [ "T4:1", "T4:1"]
      - [ "T4:2", "T4:2", data-option-for-cluster-vera: false ]
...

What happens when you change that to this:

attributes:
  node_type:
    widget: "select"
    label: "Node type"
    options:
      - [ 
        "T4:1", "T4:1",
        "T4:2", "T4:2", data-option-for-cluster-vera: false 
        ]
...

The brackets may be what is throwing this off.

I think the syntax was fine, in both cases, the generated HTML ends up as <option data-option-for-cluster-vera="false" value="T4:2">T4:2</option>

Turns out the JS doesn’t work unless you have multiple clusters to select from, as otherwise the cluster just isn’t even part of the form that the script checks for.
Adding another (nonexistent) cluster

cluster:
  - "vera"
  - "dummy"

and to my clusters.d/dummy.yml I can get the JS to somewhat work.

I’m running 2 different OOD instances, one for each cluster (as i must keep users separate ) and wanted to reuse my apps form.yml code between them without having to maintain two different branches for everything.


But I’m still confused about the dynamic auto_queue should have still worked. I can get the auto_accounts to react dynamically when using both the vera and dummy clusters, but there seems to be no connection to partitions when I have a single cluster.
The code apps/dashboard/app/lib/account_cache.rb has

  # To be used with dynamic forms. This method stithes together data
  # about the account's availablity WRT clusters, queues & QoS'.
  #
  # @return [Array] - the dynamic form options
  def dynamic_accounts
    # raise StandardError, accounts.inspect
    Rails.cache.fetch('dynamic_account_info', expires_in: 4.hours) do
      job_cluster_names = Configuration.job_clusters
                                       .map(&:id)
                                       .map(&:to_s)

      accounts.group_by(&:name).map do |account_name, grouped_accounts|
        valid_clusters = grouped_accounts.map(&:cluster)
        invalid_clusters = job_cluster_names - valid_clusters

        data = invalid_clusters.map do |invalid_cluster|
          ["data-option-for-cluster-#{invalid_cluster}", false]
        end.compact.to_h

        [account_name, account_name, data]
      end
    end
  end

where it claims “WRT clusters, queues & QoS”, but it clearly only has code for “cluster”, and makes no considerations for queues.

Ok. Yeah I’m not sure how to handle that, the dynamic forms aren’t really for this type of thing, it’s more for you make a choice and that effects other choices, but this sounds like some version control with git is in there as well and so different systems see different things maybe. Sounds exotic ah you are sort of doing that already with the VC then expecting the dynamic forms to sort of understand that, which they won’t because there’s not really choices.

As for the queues I’ll have to look into that. It works here at OSC so it could be that comment is wrong above the code.

And looking around a bit it’s actually this file:

And this looks to work by getting information from the user’s account about the queues:

Is there when you have 2? When you say ‘no connection to paritions’ are you meaning that the field isn’t popualted? I’m not quite sure what that means.

Sounds exotic

Weeeell, not that exotic I think. I just wanted to keep a single config across two systems. I was expecting the cluster form to be a hidden field in the HTML form, which would have made it visible for the JS code, but when only a single value is available the entire option is stripped out completely from the HTML.
I think this actually does work for hiding any third variants as long as you have 2 clusters (which just forces the form option to be present).
I guess I’ll just have to change my approach here and maintain two branches for all apps.


Is there when you have 2? When you say ‘no connection to paritions’ are you meaning that the field isn’t popualted? I’m not quite sure what that means.

I don’t know what you mean by 2. What I mean is that, e.g. there correctly a link between the cluster and the account:

I.e. not all accounts are valid for all clusters.

There is also a another data-option-for connection between the QoS and the account:

becuase again correctly, not all accounts<->qos options are necessarily valid options

This also applies to partitions(==queues) and accounts. Accounts in SLURM can assign allocations to only some partitions. Exactly the same as with QoS. I know OSC doesn’t happen to use partitions like this, and assumes all partitions are valid for all accounts, but this isn’t generally true at all (i think it’s actually pretty common to have a private partition for specific accounts).

I wrote about this in my original feature request, where I have some examples: Caching SLURM account information for use in app forms · Issue #1970 · OSC/ondemand · GitHub
The only place in the code that uses data-option-for-auto-accounts- is the QoS part, and there isn’t anything trying to do the corresponding data-option-for-auto-queues-, so I can only deduce this information isn’t caught by the auto_* fields.

I just meant 2 clusters there.

Is this the feature you’re looking for @Micket?