UCloud logo UCloud logo UCloud
v2025.1.0
  1. UCloud/Core
  2. 1. Introduction
  3. 2. Projects
  4. 3. Accounting
  5. 4. Orchestration
  6. UCloud/IM for Slurm-based HPC
  7. 5. Installation
  8. 6. Architecture and Networking
  9. 7. User and Project Management
  10. 8. Filesystem Integration
    1. 8.1. Inter-provider file transfers
  11. 9. Slurm Integration
    1. 9.1. Application Management
    2. 9.2. Built-in Applications
  12. 10. Reference
    1. 10.1. Configuration
    2. 10.2. CLI
  13. 11. Appendix
    1. 11.1. Built-in Application Index
  14. UCloud/IM for Kubernetes
  15. 12. Installation
  16. 13. Architecture and Networking
  17. 14. Filesystem Integration
  18. 15. Compute Jobs
    1. 15.1. Public Links
    2. 15.2. Public IPs
    3. 15.3. License Servers
    4. 15.4. SSH Servers
  19. 16. Integrated applications
    1. 16.1. Syncthing
    2. 16.2. Integrated terminal
  20. 17. Reference
    1. 17.1. Configuration
  21. H: Procedures
  22. 18. H: Procedures
  23. 19. H: Introduction
  24. 20. H: Auditing
  25. 21. H: Auditing scenario
  26. 22. H: GitHub actions
  27. 23. H: Deployment
  28. 24. H: 3rd party dependencies (risk assesment)
  1. Links
  2. Source Code
  3. Releases

Application management

This chapter will contain a description of how to upload and manage applications for a service provider. UCloud provides a catalog of applications which a service provider can subscribe to, assuming that they live up to certain infrastructure requirements.

The Application Catalog

The UCloud application catalog enables users to browse a comprehensive list of available software. Each application within the catalog is a UCloud abstraction that defines a piece of software, its parameters, and its startup process.

UCloud maintains an up-to-date catalog of applications commonly used in high-performance computing systems. Detailed instructions on configuring these applications are available here.

The UCloud application catalog showing a selection of applications available at a service provider.

The Structure of an Application

UCloud applications describe how to obtain, load and invoke a piece of software. This information is supplied in a YAML document which has several sections. These sections are illustrated in the diagram below.

An application describes how to obtain, load and invoke a piece of software. This also includes a list of input parameters, both optional and mandatory which can be fed into the application.

Metadata

All applications contain a small section of metadata. This metadata includes an application name and version. These together form a unique identifier, which is transmitted to the service provider letting it know which application is being started.

The UCloud user-interface allows users to quickly swap between versions of the same application, as shown in the screenshot below. This also means that the name of an application should be considered stable. The name of an application is generally not shown directly to end-users.

Versions are ordered in UCloud based entirely on when they are uploaded to the platform. Thus the newest version is always considered to be the most recently uploaded version.

The version selector allows users to quickly switch between versions of an application.

Input Parameters

The input parameters of an application describe the input which a user can feed into it. Each input parameter type has an associated widget in UCloud specialized for that type of input. The exact types supported are listed in the reference. Input parameters can be either optional or mandatory. Their values are partially validated by UCloud before being forwarded to the service provider.

The values of the input parameters are fed into the invocation sections.

A selection of input parameters shown in the UCloud user-interface.

Invocation

The invocation sections accept the user input and produce output in the job submission script. This includes changes to the sbatch directives, binding environment variables and finally invoking the actual software. The invocation sections are written using Jinja2 templates. Refer to the reference and examples for details on how to write these.

Interactive Properties

Applications can also declare support for various interactive application backends. This includes web-based applications and remote desktop applications.

Examples

This application is customizable, which allows users to change the invocation of the script through the user-interface. This is the recommended way of creating applications as they are more flexible.

application: v2

# The name of the application in UCloud
name: native-gromacs  

# The version of the application in UCloud. Should generally match the version
# specified in the software section.
version: 2021.5       

software:
  type: Native

features:
  multiNode: true # NOTE: Without this, you will not be able to select multiple nodes

parameters:
  # The most important parameter is the Workflow parameter added below. But for
  # now, we will add an input directory parameter called "dir" which will be 
  # consumed by the workflow below.

  dir:
    type: Directory
    title: "Input directory"
    optional: false
    description: "This is an input directory used by the workflow"

  wf:
    type: Workflow
    optional: false
    title: "Workflow"
    description: |
      Change this workflow to customize what the batch script should do.

    # This is a Jinja2 template presented to the end-user and can be changed 
    # by them. Remember, that these files are service-provider agnostic and 
    # should not contain information specific to any service-provider. The 
    # service-provider is capable of configuring what happens at various 
    # points. For example the {- systemLoad -} and {- applicationLoad -} 
    # commands below are configured by the service-provider to actually load 
    # the software onto the machine.

    job: |
      {#
          
      This script is submitted to Slurm via the sbatch command.
          
      The following sbatch directives are automatically applied based on job parameters:
          
      --account=...           --partition=...           --qos=...
      --constraint=...        --output=...              --error=...
      --time=...              --cpus-per-task=...-      --gpus-per-task=...
      --mem=...               --nodes=...               --job-name=...
      --chdir=...

      Directives can be overwritten via the following method: 
      {{ sbatch("chdir", "/tmp/new/directory") }}
            
      #}
      
      {# Sbatch directives start - Change as required #}
        {{ sbatch("cpus-per-task", 4) }}
        {{ sbatch("ntasks-per-node", ucloud.machine.cpu / 4) }}
        {{ sbatch("ntasks", (ucloud.machine.nodes * ucloud.machine.cpu) / 4) }}
      {# Sbatch directives end #}
      
      {# Preambles start - Avoid touching these unless required. #}
        {- systemLoad -}
        {- applicationLoad -}
      {# Preambles end #}
    
      {# ==================================================================== #}
      {# Start the job - change as required                                                                              #}
      {# ==================================================================== #}
    
      {# NOTE: the data input parameter is bound to the Jinja2 variable of the same name. #} 
      {# This value is automatically escaped. #}

      cd {{ dir }}
      CMD=${CMD:=gmx_mpi}
      
      set -x
      set -e

      {# NOTE: srun() will expand to the correct invocation (configurable by #}
      {# service-provider) of srun in a given context #}
      {{ srun() }} $CMD pdb2gmx -f 1AKI.pdb -o 1AKI_processed.gro -water spce
      {{ srun() }} $CMD editconf -f 1AKI_processed.gro -o 1AKI_newbox.gro -c \
          -d 1.0 -bt cubic
      {{ srun() }} $CMD solvate -cp 1AKI_newbox.gro -cs spc216.gro \
          -o 1AKI_solv.gro -p topol.top
      {{ srun() }} $CMD grompp -f ions.mdp -c 1AKI_solv.gro  -p topol.top -o ions.tpr
      {{ srun() }} $CMD genion -s ions.tpr -o 1AKI_solv_ions.gro -p topol.top \
          -pname NA -nname CL -neutral
      {{ srun() }} $CMD grompp -f minim.mdp -c 1AKI_solv_ions.gro -p topol.top \
          -o em.tpr
      {{ srun() }} $CMD mdrun -v -deffnm em -nt 32
      {{ srun() }} $CMD grompp -f nvt.mdp -c em.gro -r em.gro -p topol.top \
          -o nvt.tpr
      {{ srun() }} $CMD mdrun -v -deffnm nvt -nt 32
      {{ srun() }} $CMD grompp -f npt.mdp -c nvt.gro -r nvt.gro -t nvt.cpt \
          -p topol.top -o npt.tpr
      {{ srun() }} $CMD mdrun -v -deffnm npt
      {{ srun() }} $CMD grompp -f md.mdp -c npt.gro -t npt.cpt -p topol.top \
          -o md_0_1.tpr
      {{ srun() }} $CMD mdrun -v -deffnm md_0_1
      {{ srun() }} $CMD trjconv -s md_0_1.tpr -f md_0_1.xtc \
          -o md_0_1_noPBC.xtc -pbc mol -center
      {{ srun() }} $CMD rms -s md_0_1.tpr -f md_0_1_noPBC.xtc -o rmsd.xvg -tu ns
      {{ srun() }} $CMD rms -s em.tpr -f md_0_1_noPBC.xtc -o rmsd_xtal.xvg -tu ns

      {# ==================================================================== #}
      {# End of job                                                                                                      #}
      {# ==================================================================== #}
      
      {# Postambles start - Avoid touching these unless required. #}
        {- applicationUnload -}
        {- systemUnload -}
      {# Postambles end #}

    # This is a README visible to the user before they launch the application.
    readme: |
      This is an example workflow using GROMACS.

      ### Some GROMACS Basics

      Rerum ut eos earum neque. Velit molestias illum consectetur blanditiis 
      quis veritatis officiis cupiditate. Ut quis in consequuntur 
      necessitatibus unde.
      
      ```
      gmx help (module)
      ```

      Commodi nisi non earum cupiditate. Sint ut repudiandae sed provident vel 
      magnam tempora delectus. Consequatur vero sed perspiciatis ut nihil ut. 
      Eligendi quam nulla similique reprehenderit eveniet qui. In nisi dolorum
      iure fuga ipsam velit nihil repellat.

      ```
      gmx pdb2gmx -f 1AKI_clean.pdb -o 1AKI_processed.gro -water spce
      ```

# Keep this empty for now. Will become optional later.
invocation: ""

This is an example application showing a non-customizable application using most of the features available in the application system.

application: v2 # Required to signify version used for the application definition

name: example
version: v1.32

parameters:
  count:
    type: Integer
    title: "An optional counter"
    description: >
      This is an optional counter which will be bound to the environment variable
      called `COUNT`.
  a_flag:
    type: Boolean
    title: "An optional flag"
    description: >
      This is an optional flag. If turned on, it will produce `--flag` if it is
      not turned on (the default) then it will not produce any arguments.
  input:
    type: File
    optional: false
    title: "Example input file"
    description: >
      This is an example input file. It was made mandatory by setting
      `optional: false`
  output:
    type: Directory
    optional: false
    title: "Output directory"
    description: >
      This is a directory used for output.

software:
  type: Native

environment:
  COUNT: "{{ count }}"

invocation: |
  example-exe \
    --input {{ input }} \
    {{ output | option("--out") }} \
    {{ a_flag | flag("--flag") }}
application: v2

name: minimal
version: v1.32

software:
  type: Native

invocation: |
  echo "Hello World!"

This example shows the absolute minimum required to create an application. This example is intended to show which section are mandatory and which are optional.

Reference

Metadata

The metadata section provides basic metadata about the document and the application contained within. This section is mandatory and placed at the top-level.

Property Type Description
application —

Must be equal to v2.

name string

The name of an application. This name must be unique, for a given application and remain stable across different versions of the application. By convention, this name should be written using lower-kebab-case. The name must not contain any type of whitespace.

version string

The version of an application. There can only be one application with a given (name, version) tuple. Attempting to re-create an application with the same version is not allowed.

Parameters

The parameters section contains the input parameters for a given application. Parameters are supplied in the parameters top-level section. The top-level section has a type of map<string, parameter> where the key is the name of the parameter. The parameter type is defined in this section.

Property Type Valid for Description
type string All

The type of parameter. This controls the widget used in the UCloud user-interface along with validation logic. The type supplied controls how some properties of a parameter works. See the β€œValid for” column in this table. The following types are available:

TypeDescription
FileDisplays a file selector widget. Only a single file can be selected with this parameter.
DirectoryDisplay a folder selector widget. Only a single folder can be selected with this parameters.
IntegerAn integer widget. Optional minimum and maximum values can be selected.
FloatingPointA floating point number widget. Optional minimum and maximum values can be selected.
BooleanA boolean (on/off) widget.
TextA text input field which can contain a single line of text.
TextAreaA text input field which can contain multiple lines of text.
EnumerationAn input field which allows the user to select from a number of pre-defined options.
LicenseDisplays a widget for selecting a license to attach to the job.
JobDisplays a job selector widget. This allows a user to select a companion job. This option is not used for the Slurm Integration.
PublicIPDisplays a widget for selecting a public license to attach to the job. This option is not used for the Slurm integration.
title string All

A human-readable title used for this parameter. This property should be short (less than 120 characters) and be limited to a single line.

description string All

A human-readable description used for this parameter. The description can use limited markdown for markup, but it cannot use any HTML tags or references to external resources. The first-line is always shown without further interaction from the user. Lines beyond the first might require user interaction to show.

optional boolean (optional) All

Default value: true

This property controls if a parameter is mandatory or not. If this property is not supplied or if it is supplied with a value of true, then the parameter is considered optional. Otherwise, it is considered to be mandatory and a job cannot be submitted with this application without supplying a value for the parameter.

defaultValue Varies (optional) All

Default value: null

This property controls the default value of a parameter. The default value is used only if a parameter is optional and no value is supplied for the parameter. The type of the property should match the type of parameter. It is not possible to set default values for files or directories.

min int/float (optional) Integer, FloatingPoint

Default value: null

This property controls the minimum value (inclusive) a numeric type can have.

max int/float (optional) Integer, FloatingPoint

Default value: null

This property controls the maximum value (inclusive) a numeric type can have.

step int/float (optional) Integer, FloatingPoint

Default value: null

This property controls the step size of clicking increment/decrement buttons in the user-interface for numeric inputs.

options { title: string, value: string }[] Enumeration

This property controls the options to show in the user-interface for an enumeration. Only options present in this property can be selected by the user.

If a defaultValue is also defined then this must match the value of a valid option.

Software

The software section contains information about how to (optionally) build software along with information about how to load the software. This is supplied in the software top-level section.

Property Type Description
type string

Must be "Native" for application used in the UCloud/IM for Slurm integration.

Environment Bindings and Program Invocation

The environment section contains bindings of environment variable needed in a given application. These are supplied in the environment top-level section with a type of map<string, InvocationString>. The key is the name of the variable. The InvocationString is defined below.

Similarly, the program invocation is defined in the top-level invocation property also of type InvocationString. The program invocation is passed into the job submission script after rendering is complete. Thus the program invocation will be interpreted by a bash interpreter.

An InvocationString is a template string which follows the format of Jinja2. Invocation strings bound to environment variables will have no automatic escaping. Invocation strings which are bound to the program invocation will instead use bash escaping. Regardless of if it is bound to a program invocation or an environment variable, the same variables and filters are available.

Variables

All input parameters submitted to the job are available at the top-level using the same name as described in the parameters section of the application. If a variable has a default value and none was supplied, then the default value is made available. It is not possible to detect directly if a user supplied no value if a default is available. Normal variables can be accessed with the following snippet:

{{ myParameter }}

Optional parameters for which the user did not supply a value, and the parameter has no default, will not be made available in the template. It is possible to detect if no value is supplied with the following snippet:

{% if optionalParameter == None %}
The optional parameter was not supplied
{% else %}
The optional parameter is {{optionalParameter}} 
{% endif %}

Metadata about the job is made available through the ucloud top-level property. The properties in the ucloud property are also automatically bound to environment variables using the same name but in UPPER_SNAKE_CASE. Thus ucloud.machine.memoryInGigs becomes UCLOUD_MACHINE_MEMORY_IN_GIGS. The contents of the ucloud property is defined in the table below:

Property Type Description
ucloud.jobId string

The UCloud job ID. Note that this is supplied as a string, even though most job IDs are numeric. You should not depend on the IDs being numeric. The IDs are unique and do not change. An ID is never re-used at a given provider.

Example: "51239184"

ucloud.machine.name string

The name of the machine slice used for the reservation.

Example: "u1-standard-64"

ucloud.machine.category string

The name of the machine type (product category) used for the reservation.

Example: "u1-standard"

ucloud.machine.cpu int

The number of (v)CPUs available to the machine slice. This is retrieved from the product configuration and not from the actual compute nodes.

Example: 64

ucloud.machine.cpuModel string (optional)

The model of the CPU available to the machine type used in the reservation. This is retrieved from the product configuration and not from the actual compute nodes.

Example: "AMD EPYC 7742"

ucloud.machine.memoryInGigs int

The amount of memory available to the machine reservation in gigabytes. This is retrieved from the product configuration and not from the actual compute nodes.

Example: 512

ucloud.machine.memoryModel string (optional)

The model of the memory available to the machine type used in the reservation. This is retrieved from the product configuration and not from the actual compute nodes.

Example: "DDR4-2400"

ucloud.machine.gpu int

The amount of GPUs made available to the machine type used in the reservation. This is retrieved from the product configuration and not from the actual compute nodes.

Example: 4

ucloud.machine.gpuModel string (optional)

The model of the GPUs available to the machine type used in the reservation. This is retrieved from the product configuration and not from the actual compute nodes.

Example: "NVIDIA H100"

ucloud.webPort/ucloud.vncPort int (optional)

If the application has requested a dynamic port allocation for a vnc/web-interface, then this property will contain a port which the application is expected to use. The dynamic port will be allocated such that it is highly unlikely to be in use on the node.

Note that UCloud/IM cannot guarantee that this port is not in use. But UCloud/IM will attempt to not generate duplicates directly. This won’t stop users from, at random, running work listening on the same port. Applications should attempt to exit immediately in case such a conflict occurs.

Ports are generated in the range between TODO and TODO.

Example: 52382

ucloud.nodes int

The number of nodes dedicated to the job.

Example: 4

ucloud.partition string

The partition which the job is going to be submitted to. This is derived from the configuration and the machine slice.

Example: "cpu"

ucloud.qos string

The quality-of-service (QoS) which the job is going to be submitted with. This is derived from the configuration and the machine slice.

Example: "normal"

ucloud.application.name string

The name of the application being submitted.

Example: "quantum-espresso"

ucloud.application.version string

The version of the application being submitted.

Example: "7.3"

Filters

The standard built-in filters of Jinja2 are supported along with the following custom filters:

Filter Description
flag

Signature:

boolean_expression | flag(onFlag[, offFlag]) -> string

If the value passed into the filter is True then the onFlag will be produced. Otherwise the offFlag will be produced. If offFlag is not specified then "" is returned instead.

Example:

{{ True | flag("--yes", "--no") }}            -> "--yes"
{{ False | flag("--yes", "--no") }}           -> "--no"
{{ True | flag("--yes") }}                    -> "--yes"
{{ False | flag("--yes") }}                   -> ""
option

Signature:

expression | option(optionFlag[, addSpace]) -> string

If the expression is not None then a non-positional option is added to the output. If addSpace is True then a space is added between the optionalFlag and the value. If it is False then no space is added. If it is omitted then a value is automatically chosen based on the option flag. Specifically, if the optionFlag ends in = then no space is added, otherwise a space is added.

This function will always escape the value part for use in bash. Even when bound to an environment variable. If addSpace evaluates to False then the option itself is also escaped. The option is not escaped if addSpace evaluates to true.

Examples:

{{ None | option("--an-optional-option") }}   -> ""
{{ 42 | option("--count") }}                  -> "--count '42'"
{{ 42 | option("--count=") }}                 -> "'--count=42'"
{{ 42 | option("--count", false) }}           -> "'--count42'"
{{ 42 | option("--count=", true) }}           -> "--count= '42'"
{{ "/path/with spaces" | option("--file") }}  -> "--file '/path/with spaces'"

Methods

The standard built-in methods Jinja2 are supported along with the following custom methods:

Method Description
script

Signature:

script(path) -> string

Requests the execution of a script. The script will use the standard script protocol and run in the context of the user launching the job. The script will receive the same parameters as are available to the template, including all parameters. Any variables set inside of the Jinja template are not included. The script must return the output in the following format:

{
    /* string */
    "output": ""
}

The output is rendered with no escaping applied to it. Note that this output does not pass back through Jinja and thus cannot be used to generate templates at runtime.

Example:

This example assumes that the machine slice used for the job has the name u1-standard-64.

{{ script("/opt/ucloud/scripts/my-script") }} -> "u1-standard-64"
#!/usr/bin/env python3
# File: /opt/ucloud/scripts/my-script

import sys
import json

with open(sys.argv[1]) as fp:
    request = json.load(fp)

response = { "output": request["ucloud"]["machine"]["name"] }
print(json.dumps(response))
sbatch

Signature:

sbatch(directiveName, value) -> void

Changes the sbatch directives used in the application. See the sbatch directives section below.

Example:

This example assumes a directory parameter in the application called inputDir.

{{ sbatch("chdir", inputDir) }}

This will cause the generated sbatch file to include:

#SBATCH --chdir ${inputDir}

Control Structures

The templating engine used for InvocationStrings supports the control structures of Jinja2, with the following exceptions:

  • {% extends ... %} has been disabled
  • {% from ... %} has been disabled
  • {% import ... %} has been disabled
  • {% include ... %} has been disabled

Sbatch

Sbatch directives are automatically added for most options which are relevant for a job. If an application needs to customize these, then this can also be done at an application level. This is done by adding the top-level sbatch property of type map<string, InvocationString>. This property follows the same rules of environment bindings. The directives generally take precedence over the directives generated by UCloud. Some caveats are covered by the table below:

As an alternative, it is possible to override sbatch directives directly from the invocation (either via a customizable workflow or in the invocation parameter) by using {{ sbatch("directive-name", "value") }}.

DirectiveNotes
--accountThis directive cannot be changed by an application.
--partitionThis directive cannot be changed by an application .
--constraintThis directive can be changed but can cause conflicts with Advanced scheduling.
--output and --errorThis will cause issues with log output in UCloud, but can be changed.
--cpus-per-task (and similar)These can be changed but may produce surprising results. You should adjust other options to ensure that the Slurm resource reservation still matches the one from UCloud.

Web Applications

The web-based interactive applications can be configured in the web top-level property. It has the following options available to it:

Property Type Description
enabled boolean

If true, then this application exposes a web-application. If false, then all other properties in this section are ignored.

port int | null (optional)

Default value: null

The port on which the web-application will listen. If set to null then dynamic port allocation is used and the port is exposed through the ucloud.webPort template property/UCLOUD_WEB_PORT environment variable. Applications running on Slurm should generally use dynamic port allocation unless the software only supports fixed ports.

Remote Desktop Environments (VNC)

Remote desktop environments (via VNC) can be configured through the vnc top-level section. It has the following properties available to it:

Property Type Description
enabled boolean

If true, then this application exposes a web-application. If false, then all other properties in this section are ignored.

port int | null (optional)

Default value: null

The port on which the web-application will listen. If set to null then dynamic port allocation is used and the port is exposed through the ucloud.vncPort template property/UCLOUD_VNC_PORT environment variable. Applications running on Slurm should generally use dynamic port allocation unless the software only supports fixed ports.

Features

Various optional features can be enabled through the features top-level section. These properties are described by the table below. All properties in the features section have a default value.

Property Type Description
multiNode boolean (optional)

Default value: false

This feature allows a user to add multiple nodes to a single job. This must be explicitly enabled for all applications which are capable of doing multi-node processing.

Previous Slurm Integration
Next Built-in Applications