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 |
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 |
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:
|
||||||||||||||||||||||||
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: 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 |
||||||||||||||||||||||||
defaultValue |
Varies (optional) | All |
Default value: 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: This property controls the minimum value (inclusive) a numeric type can have. |
||||||||||||||||||||||||
max |
int/float (optional) |
Integer, FloatingPoint |
Default value: This property controls the maximum value (inclusive) a numeric type can have. |
||||||||||||||||||||||||
step |
int/float (optional) |
Integer, FloatingPoint |
Default value: 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 |
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 |
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: |
ucloud.machine.name |
string |
The name of the machine slice used for the reservation. Example: |
ucloud.machine.category |
string |
The name of the machine type (product category) used for the reservation. Example: |
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: |
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: |
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: |
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: |
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: |
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: |
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 Example: |
ucloud.nodes |
int |
The number of nodes dedicated to the job. Example: |
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: |
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: |
ucloud.application.name |
string |
The name of the application being submitted. Example: |
ucloud.application.version |
string |
The version of the application being submitted. Example: |
Filters
The standard built-in filters of Jinja2 are supported along with the following custom filters:
| Filter | Description |
|---|---|
flag |
Signature:
If the value passed into the filter is Example:
|
option |
Signature:
If the expression is not This function will always escape the value part for use in bash. Even when bound to an environment variable. If
Examples:
|
Methods
The standard built-in methods Jinja2 are supported along with the following custom methods:
| Method | Description |
|---|---|
script |
Signature:
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:
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
|
sbatch |
Signature:
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
This will cause the generated sbatch file to include:
|
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") }}.
| Directive | Notes |
|---|---|
--account | This directive cannot be changed by an application. |
--partition | This directive cannot be changed by an application . |
--constraint | This directive can be changed but can cause conflicts with Advanced scheduling. |
--output and --error | This 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 |
port |
int | null (optional) |
Default value: The port on which the web-application will listen. If set to |
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 |
port |
int | null (optional) |
Default value: The port on which the web-application will listen. If set to |
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: 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. |
UCloud