---
title: Connect workloads
description: Choose how your scheduler or tools call OpenLM LicOps in OpenLM Platform, and set the address, license names, fail mode, and server choice.
product: OpenLM Platform
---

To gate a licensed job, have it make three requests to LicOps: admit when it is submitted, dispatch when it starts, and release when it ends. LicOps only gates the jobs that ask it, so something in your environment has to make the requests. Pick the integration that matches where your jobs run:

| Your jobs run on | Use | Who makes the requests |
| --- | --- | --- |
| Slurm | [Slurm adapters](https://www.openlm.com/documentation/cloud/deployment-operations/licops/slurm) | An `sbatch` wrapper on the submit nodes, and controller prolog and epilog hooks. |
| IBM Spectrum LSF | [LSF adapters](https://www.openlm.com/documentation/cloud/deployment-operations/licops/lsf) | An `esub` on the submit hosts, and queue `PRE_EXEC` and `POST_EXEC` hooks. |
| Kubernetes | [Kubernetes workloads](https://www.openlm.com/documentation/cloud/deployment-operations/licops/kubernetes) | The admission webhook for annotated pods, or the job itself. |
| Anything else | [Call the admission API](https://www.openlm.com/documentation/cloud/deployment-operations/licops/admission-api) | Your own wrapper, script, or service. |

OpenLM supplies the Slurm and LSF adapters, and an integration kit with a wrapper script, a Python client, an OpenAPI description of the API and Kubernetes examples. Contact OpenLM to get them.

For other schedulers, call the admission API from your submit hook. See [Call the admission API](https://www.openlm.com/documentation/cloud/deployment-operations/licops/admission-api).

## Before you connect anything

Before you connect a workload, find the LicOps address, get the license names right, and decide what happens when LicOps is unreachable.

### Find the LicOps address

Every integration needs one address: the LicOps admission API on port `8100`. The following table lists the address for each caller:

| Caller | Address |
| --- | --- |
| Slurm or LSF adapters | `http://<licops-host>:8100/api/v1/admission-controller` |
| A workload in the same Kubernetes cluster | `http://openlm-router-api.<namespace>.svc:8100` |
| Your own tools | `http://<licops-host>:8100`, with the paths in [API reference](https://www.openlm.com/documentation/cloud/deployment-operations/reference) |

To confirm the address, run this command from the host that will make the calls, not from your own workstation:

```bash
curl -s -o /dev/null -w '%{http_code}\n' http://<licops-host>:8100/api/v1/status
```

`200` means the address is right. Port `30001` is not the API: it speaks the FlexLM protocol, so an HTTP request there stops responding or fails.

### Use the exact license names

Every request names a pool by its vendor daemon and feature, such as `MLM` and `MATLAB`. The names must match the pool exactly, including case: a request for `mlm` or `Matlab` matches nothing and is denied as `NoServerAvailable`, which looks like an outage rather than a typo. Copy the names from `GET /api/v1/stats`, as described in [Configure OpenLM LicOps](https://www.openlm.com/documentation/cloud/deployment-operations/configuration#check-that-licops-lists-your-license-pools).

Some features contain spaces, such as `Acrobat Pro`. Send them with a real space in the API. The Slurm license map writes the space as `%20`, because the map itself is separated by spaces. The adapter turns it back into a space before it calls LicOps.

### Release on every ending

A job's seat stays counted until its release arrives, or until its session times out. A job that fails, is canceled, or times out must release as surely as one that succeeds, or the seat stays taken while nobody uses it and other jobs are denied. The scheduler adapters release from hooks the scheduler runs whatever happens to the job. If you write your own integration, release from a `finally` block, a `trap`, or a hook that always runs.

### Decide what happens when LicOps is unreachable

If LicOps is down or slow, the adapters cannot ask for a seat. You choose what they do, separately for admit and for dispatch. The following table compares the two choices:

| Aspect | Fail open: run the job anyway | Fail closed: hold or refuse the job |
| --- | --- | --- |
| While LicOps is down | Jobs keep flowing. | Jobs stop. |
| The risk | More jobs start than the seats allow, and some fail at checkout. | The cluster idles until LicOps is back. |
| Suits | Dispatch, where the seat was already admitted, and widely licensed tools | Admit, for licenses where compliance matters more than throughput |

The Slurm and LSF adapters read `OL_FAIL_MODE_ADMIT` and `OL_FAIL_MODE_DISPATCH`, each `open` or `closed`. Both default to `open`. The integration kit's wrapper script has its own setting, `OL_FAIL_MODE`, which defaults to `closed`. They also give up on a request after `OL_TIMEOUT` seconds, 2 by default, and then apply the fail mode, so a slow LicOps never holds up submission for long. Decide deliberately and write down which you chose.

## Decide whether LicOps also chooses the server

LicOps always decides whether a job may start. Whether the job then checks out from the server LicOps chose depends on how its checkout reaches the license server. The following table lists where the application checks out for each integration:

| Integration | Where the application checks out |
| --- | --- |
| Slurm or LSF adapters, by default | From the servers in the application's own license settings. LicOps gates the job but does not steer its checkout, so rules that choose a server, such as **Cascade across servers in priority order**, do not change where it checks out. |
| Slurm or LSF adapters, with checkout routing | Through the LicOps listen port, `30001`, which passes the checkout to the server LicOps chose for that job. |
| The Kubernetes admission webhook | Through a sidecar in the pod, which passes it to LicOps the same way. |
| A Kubernetes job or your own integration calling the API | From the server dispatch names, when you set `LM_LICENSE_FILE` to the `licenseFile` that dispatch returns. |

Admission only is the simpler place to start, and already stops jobs from starting without a seat. Add checkout routing when you want the placement rules to apply to the checkouts themselves.

With checkout routing, LicOps recognizes each checkout by the IP address of the node it comes from. The compute nodes must reach the LicOps host directly, without address translation in between. The node's existing license setting stays in place behind the LicOps entry, so if LicOps is unreachable, the application falls back to its usual server.
