Subtenant Applications

An application has a set of services. A service has a set of containers. An application is deployed to a set of sites through an application deployment specification.

In a site, each service in an application can run in one or more instances. A service instance is the smallest scheduled unit, which means that all containers in a service are always scheduled together.

All service instances in an application running in a site have their own isolated ip network (the application network), alternatively share an isolated ip network with selected other applications within the same tenant (shared application network).

The containers in an application instance run in the same network namespace and in the same PID namespace.

If a container crashes or its liveness probe fails, it is immediately restarted. Other containers in the same service instance as the failing container are not restarted in this case.

Application Versioning

An application has a version. If an application specification is changed without changing the version, the system will adapt to the new specification by restarting affected containers etc.

In order to do a controlled upgrade of an application, modify the application specification, update the version string, and describe the upgrade procedure in the upgrade-from list.

The system keeps track of the last 3 version of an application specification. This list of versions is updated every time the version field is updated.

The list of old versions can be retrieved by passing the query parameter version-list in the GET request for the configuration of a given application.

Create a new application

SecurityaccessToken
Request
path Parameters
tenant-name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

name of tenant

query Parameters
validate
string <enumeration>

Validate the request but do not actually perform the requested operation

Value: "true"
Request Body schema:
name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

The name of the application.

version
string <version> ^[a-zA-Z0-9\-.+]+$

The version of the application.

object

Map of string keys and values that can be used to categorize applications. These labels are not used directly by system.

A label name consists of an optional prefix followed by /, followed by a name segment. The optional prefix is a DNS host name (must match inet:domain-name). The name segment must match ava:name.

The prefix system is used for labels assigned by the system.

Label names without prefixes are reserved for application owners.

For example:

  • system/controller
  • example.com/location.city
  • example.com/color
  • color
required
Array of containers (object) or vm (object)
object

Constraints on per-application resources.

object
on-mutable-variable-change
string <enumeration>
Default: "restart-service-instance"
  • upgrade-application: Run the application upgrade procedure.
  • restart-service-instance: Restart affected service instances. The service instances are restarted without the coordination that upgrade-application provides. This is the quickest way to change the service instances, but it means that there might be no service instances running for a short period of time.
  • ignore: Do not do anything.
    This can be useful if the containers for example use the mutable variable only when they start.

Controls what happens if a mutable variable that is referenced in a container's env, cmd, or entrypoint is changed.

Array of objects

The order of the entries in this list is significant.

If present and the application's version is changed, the application is upgraded according to this specification. The list entries are checked in the given order. If the application's current version matches the version-regexp in the list entry, it is used, and the rest of the list entries are ignored.

If no list entry matches, containers are stopped and restarted as needed, without any synchronization.

If the application's version isn't changed, but the application specification is modified, containers are stopped and restarted as needed, without any synchronization.

Responses
201

Created

400

Bad Request

401

Unauthorized

403

Forbidden

404

Not Found

409

Conflict (instance exists)

503

Service Unavailable (strongbox sealed)

post/v1/config/tenants/{tenant-name}/applications
Request samples
name: myapp
version: 2.4.2
labels:
  color: green
services:
  - name: mysvc
    delayed-shutdown:
      timeout: 30m
      max-number-of-instances: 3
    mode: replicated
    replicas: 2
    placement:
      preferred-affinity:
        services: []
      preferred-anti-affinity:
        services:
          - mydb
      match-host-labels: movie-theater-owner.com/host_size = medium
    volumes:
      - name: fast-storage
        ephemeral-volume:
          size: 1GB
          file-mode: "770"
          file-ownership: 1000:1000
          match-volume-labels: movie-theater-owner.com/speed = fast
      - name: persistent-storage
        persistent-volume:
          size: 1GB
          file-mode: "770"
          file-ownership: 1000:1000
          match-volume-labels: movie-theater-owner.com/speed = fast
      - name: my-config
        config-map:
          items:
            - name: api-cacert.pem
              data: ${SYS_API_CA_CERT}
              file-mode: "444"
              file-ownership: 0:0
            - name: test0.conf
              data: |
                foo: bar
                secret: ${MY_SECRET}
              file-mode: "400"
              file-ownership: 100:0
      - name: my-secrets
        vault-secret:
          vault: foo
          secret: for-alpine
          file-mode: "440"
          file-ownership: 0:100
    share-pid-namespace: false
    variables:
      - name: MY_SECRET
        value-from-vault-secret:
          vault: foo
          secret: for-all
          key: cax
    init-containers:
      - name: setup
        mounts:
          - volume-name: my-config
            files:
              - name: api-cacert.pem
                mount-path: /certs/api-cacert.pem
            mode: read-only
        additional-capabilities: []
        devices:
          device-labels:
            - rtc
        memory: 10MiB
        cpus: 0.5
        cpu-shares: 1024
        container-log-size: 0B
        container-log-max-days: 100
        container-log-archive: false
        image: popcorn-systems/mydb:3.2
        entrypoint:
          - do-setup.sh
        cmd: []
        user: 100
        container-layer-size: 10 MiB
        env:
          APPROLE_SECRET_ID: ${SYS_APPROLE_SECRET_ID}
        approle: name
        security:
          selinux:
            disabled: true
          apparmor:
            disabled: true
        gpu:
          labels:
            - gpu-all
          number-gpus: 1
          gpu-patterns:
            - vendor == "NVIDIA", display-mode == "Enabled"
    containers:
      - name: mydb
        mounts:
          - volume-name: fast-storage
            mount-path: /cache
            mode: read-write
          - volume-name: my-config
            files:
              - name: api-cacert.pem
                mount-path: /certs/api-cacert.pem
              - name: test0.conf
                mount-path: /etc/t.conf
            mode: read-only
          - volume-name: my-secrets
            mount-path: /etc/secrets
            mode: read-only
        additional-capabilities: []
        devices:
          device-labels:
            - rtc
        memory: 1GiB
        cpus: 0.5
        cpu-shares: 1024
        container-log-size: 100 MiB
        container-log-max-days: 14
        container-log-archive: false
        image: popcorn-systems/mydb:3.2
        entrypoint:
          - /bin/start-mydb
        cmd:
          - "-s"
        user: 1000:1000
        container-layer-size: 10 MiB
        env:
          FOO: "42"
          BAZ: ${MY_SECRET}
          APPROLE_SECRET_ID: ${SYS_APPROLE_SECRET_ID}
          API_CA_CERT: ${SYS_API_CA_CERT}
        approle: name
        security:
          selinux:
            disabled: true
          apparmor:
            disabled: true
        gpu:
          labels:
            - gpu-all
          number-gpus: 1
          gpu-patterns:
            - vendor == "NVIDIA", display-mode == "Enabled"
        delayed-shutdown-cmd:
          - /bin/xctrl
          - "--shutdown"
        on-mounted-file-change:
          cmd:
            - touch
            - /tmp/cfg-chg
        probes:
          startup:
            exec:
              cmd:
                - nc
                - "-l"
                - "-p"
                - "9001"
                - "-e"
                - echo
                - probe-started
            initial-delay: 0s
            timeout: 3s
            period: 10s
            success-threshold: 1
            failure-threshold: 3
          readiness:
            tcp:
              port: 443
            initial-delay: 0s
            timeout: 1s
            period: 10s
            success-threshold: 1
            failure-threshold: 3
          liveness:
            http:
              scheme: https
              host: foo.com
              port: 443
              path: /healthz
              request-headers:
                Accept: application/yaml
            initial-delay: 0s
            timeout: 1s
            period: 10s
            success-threshold: 1
            failure-threshold: 3
    network:
      ingress-ip-per-instance:
        protocols:
          - name: tcp
            port-ranges: "9000"
        match-interface-labels: movie-theater-owner.com/external
        match-ipv4-range-labels: movie-theater-owner.com/private
        dns-records:
          domains:
            - domain: default
              srv:
                - name: _http._tcp
                  priority: 0
                  port: 80
      outbound-access:
        default-action: allow
        rules:
          192.0.2.0/24: deny
    site-dns-records:
      domains:
        - domain: default
          srv:
            - name: _http._tcp
              priority: 1
              port: 80
              weight: 100
              target: nginx.web.acme.foo.bar.com
          cname:
            - name: www
              cname: nginx.web.acme.foo.bar.com
          naptr:
            - name: mailer
              order: 102
              preference: 10
              flags: U
              services: E2U+email
              regexp: "!^.*$!mailto:information@example.com!"
              replacement: _http._tcp.nginx.web.acme.foo.bar.com
resources:
  network:
    upstream-bandwidth-per-host: 100Mbit/s
    downstream-bandwidth-per-host: 1Gbit/s
network:
  shared-application-network: mynetwork
on-mutable-variable-change: restart-service-instance
upgrade-from:
  - version-regexp: "2\\.4\\..*"
    method: per-service
    services:
      - name: mysvc
        instances-in-parallel: 1
        healthy-time: 1m
  - version-regexp: "2\\.3\\..*"
    method: per-service
    services:
      - name: mysvc
        instances-in-parallel: 2
        healthy-time: 10m
  - version-regexp: "2\\..*"
    method: stop-and-restart

Retrieve the configuration of all applications

SecurityaccessToken
Request
path Parameters
tenant-name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

name of tenant

query Parameters
fields
string

Retrieve only requested fields from the resource

See section fields

validate
string <enumeration>

Validate the request but do not actually perform the requested operation

Value: "true"
keys
string <enumeration>

Retrieve only the keys for the list

Value: "true"
count
string <enumeration>

Retrieve only the number of elements in the list

Value: "true"
Responses
200

OK

400

Bad Request

401

Unauthorized

403

Forbidden

404

Not Found

412

Precondition Failed

503

Service Unavailable (strongbox sealed)

get/v1/config/tenants/{tenant-name}/applications
Response samples
- name: myapp
  version: 2.4.2
  labels:
    color: green
  services:
    - name: mysvc
      delayed-shutdown:
        timeout: 30m
        max-number-of-instances: 3
      mode: replicated
      replicas: 2
      placement:
        preferred-affinity:
          services: []
        preferred-anti-affinity:
          services:
            - mydb
        match-host-labels: movie-theater-owner.com/host_size = medium
      volumes:
        - name: fast-storage
          ephemeral-volume:
            size: 1GB
            file-mode: "770"
            file-ownership: 1000:1000
            match-volume-labels: movie-theater-owner.com/speed = fast
        - name: persistent-storage
          persistent-volume:
            size: 1GB
            file-mode: "770"
            file-ownership: 1000:1000
            match-volume-labels: movie-theater-owner.com/speed = fast
        - name: my-config
          config-map:
            items:
              - name: api-cacert.pem
                data: ${SYS_API_CA_CERT}
                file-mode: "444"
                file-ownership: 0:0
              - name: test0.conf
                data: |
                  foo: bar
                  secret: ${MY_SECRET}
                file-mode: "400"
                file-ownership: 100:0
        - name: my-secrets
          vault-secret:
            vault: foo
            secret: for-alpine
            file-mode: "440"
            file-ownership: 0:100
      share-pid-namespace: false
      variables:
        - name: MY_SECRET
          value-from-vault-secret:
            vault: foo
            secret: for-all
            key: cax
      init-containers:
        - name: setup
          mounts:
            - volume-name: my-config
              files:
                - name: api-cacert.pem
                  mount-path: /certs/api-cacert.pem
              mode: read-only
          additional-capabilities: []
          devices:
            device-labels:
              - rtc
          memory: 10MiB
          cpus: 0.5
          cpu-shares: 1024
          container-log-size: 0B
          container-log-max-days: 100
          container-log-archive: false
          image: popcorn-systems/mydb:3.2
          entrypoint:
            - do-setup.sh
          cmd: []
          user: 100
          container-layer-size: 10 MiB
          env:
            APPROLE_SECRET_ID: ${SYS_APPROLE_SECRET_ID}
          approle: name
          security:
            selinux:
              disabled: true
            apparmor:
              disabled: true
          gpu:
            labels:
              - gpu-all
            number-gpus: 1
            gpu-patterns:
              - vendor == "NVIDIA", display-mode == "Enabled"
      containers:
        - name: mydb
          mounts:
            - volume-name: fast-storage
              mount-path: /cache
              mode: read-write
            - volume-name: my-config
              files:
                - name: api-cacert.pem
                  mount-path: /certs/api-cacert.pem
                - name: test0.conf
                  mount-path: /etc/t.conf
              mode: read-only
            - volume-name: my-secrets
              mount-path: /etc/secrets
              mode: read-only
          additional-capabilities: []
          devices:
            device-labels:
              - rtc
          memory: 1GiB
          cpus: 0.5
          cpu-shares: 1024
          container-log-size: 100 MiB
          container-log-max-days: 14
          container-log-archive: false
          image: popcorn-systems/mydb:3.2
          entrypoint:
            - /bin/start-mydb
          cmd:
            - "-s"
          user: 1000:1000
          container-layer-size: 10 MiB
          env:
            FOO: "42"
            BAZ: ${MY_SECRET}
            APPROLE_SECRET_ID: ${SYS_APPROLE_SECRET_ID}
            API_CA_CERT: ${SYS_API_CA_CERT}
          approle: name
          security:
            selinux:
              disabled: true
            apparmor:
              disabled: true
          gpu:
            labels:
              - gpu-all
            number-gpus: 1
            gpu-patterns:
              - vendor == "NVIDIA", display-mode == "Enabled"
          delayed-shutdown-cmd:
            - /bin/xctrl
            - "--shutdown"
          on-mounted-file-change:
            cmd:
              - touch
              - /tmp/cfg-chg
          probes:
            startup:
              exec:
                cmd:
                  - nc
                  - "-l"
                  - "-p"
                  - "9001"
                  - "-e"
                  - echo
                  - probe-started
              initial-delay: 0s
              timeout: 3s
              period: 10s
              success-threshold: 1
              failure-threshold: 3
            readiness:
              tcp:
                port: 443
              initial-delay: 0s
              timeout: 1s
              period: 10s
              success-threshold: 1
              failure-threshold: 3
            liveness:
              http:
                scheme: https
                host: foo.com
                port: 443
                path: /healthz
                request-headers:
                  Accept: application/yaml
              initial-delay: 0s
              timeout: 1s
              period: 10s
              success-threshold: 1
              failure-threshold: 3
      network:
        ingress-ip-per-instance:
          protocols:
            - name: tcp
              port-ranges: "9000"
          match-interface-labels: movie-theater-owner.com/external
          match-ipv4-range-labels: movie-theater-owner.com/private
          dns-records:
            domains:
              - domain: default
                srv:
                  - name: _http._tcp
                    priority: 0
                    port: 80
        outbound-access:
          default-action: allow
          rules:
            192.0.2.0/24: deny
      site-dns-records:
        domains:
          - domain: default
            srv:
              - name: _http._tcp
                priority: 1
                port: 80
                weight: 100
                target: nginx.web.acme.foo.bar.com
            cname:
              - name: www
                cname: nginx.web.acme.foo.bar.com
            naptr:
              - name: mailer
                order: 102
                preference: 10
                flags: U
                services: E2U+email
                regexp: "!^.*$!mailto:information@example.com!"
                replacement: _http._tcp.nginx.web.acme.foo.bar.com
  resources:
    network:
      upstream-bandwidth-per-host: 100Mbit/s
      downstream-bandwidth-per-host: 1Gbit/s
  network:
    shared-application-network: mynetwork
  on-mutable-variable-change: restart-service-instance
  upgrade-from:
    - version-regexp: "2\\.4\\..*"
      method: per-service
      services:
        - name: mysvc
          instances-in-parallel: 1
          healthy-time: 1m
    - version-regexp: "2\\.3\\..*"
      method: per-service
      services:
        - name: mysvc
          instances-in-parallel: 2
          healthy-time: 10m
    - version-regexp: "2\\..*"
      method: stop-and-restart
  

Update an application

SecurityaccessToken
Request
path Parameters
tenant-name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

name of tenant

application-name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

The name of the application.

query Parameters
validate
string <enumeration>

Validate the request but do not actually perform the requested operation

Value: "true"
Request Body schema:
name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

The name of the application.

version
string <version> ^[a-zA-Z0-9\-.+]+$

The version of the application.

object

Map of string keys and values that can be used to categorize applications. These labels are not used directly by system.

A label name consists of an optional prefix followed by /, followed by a name segment. The optional prefix is a DNS host name (must match inet:domain-name). The name segment must match ava:name.

The prefix system is used for labels assigned by the system.

Label names without prefixes are reserved for application owners.

For example:

  • system/controller
  • example.com/location.city
  • example.com/color
  • color
required
Array of containers (object) or vm (object)
object

Constraints on per-application resources.

object
on-mutable-variable-change
string <enumeration>
Default: "restart-service-instance"
  • upgrade-application: Run the application upgrade procedure.
  • restart-service-instance: Restart affected service instances. The service instances are restarted without the coordination that upgrade-application provides. This is the quickest way to change the service instances, but it means that there might be no service instances running for a short period of time.
  • ignore: Do not do anything.
    This can be useful if the containers for example use the mutable variable only when they start.

Controls what happens if a mutable variable that is referenced in a container's env, cmd, or entrypoint is changed.

Array of objects

The order of the entries in this list is significant.

If present and the application's version is changed, the application is upgraded according to this specification. The list entries are checked in the given order. If the application's current version matches the version-regexp in the list entry, it is used, and the rest of the list entries are ignored.

If no list entry matches, containers are stopped and restarted as needed, without any synchronization.

If the application's version isn't changed, but the application specification is modified, containers are stopped and restarted as needed, without any synchronization.

Responses
204

No Content

400

Bad Request

401

Unauthorized

403

Forbidden

404

Not Found

412

Precondition Failed

503

Service Unavailable (strongbox sealed)

patch/v1/config/tenants/{tenant-name}/applications/{application-name}
Request samples
name: myapp
version: 2.4.2
labels:
  color: green
services:
  - name: mysvc
    delayed-shutdown:
      timeout: 30m
      max-number-of-instances: 3
    mode: replicated
    replicas: 2
    placement:
      preferred-affinity:
        services: []
      preferred-anti-affinity:
        services:
          - mydb
      match-host-labels: movie-theater-owner.com/host_size = medium
    volumes:
      - name: fast-storage
        ephemeral-volume:
          size: 1GB
          file-mode: "770"
          file-ownership: 1000:1000
          match-volume-labels: movie-theater-owner.com/speed = fast
      - name: persistent-storage
        persistent-volume:
          size: 1GB
          file-mode: "770"
          file-ownership: 1000:1000
          match-volume-labels: movie-theater-owner.com/speed = fast
      - name: my-config
        config-map:
          items:
            - name: api-cacert.pem
              data: ${SYS_API_CA_CERT}
              file-mode: "444"
              file-ownership: 0:0
            - name: test0.conf
              data: |
                foo: bar
                secret: ${MY_SECRET}
              file-mode: "400"
              file-ownership: 100:0
      - name: my-secrets
        vault-secret:
          vault: foo
          secret: for-alpine
          file-mode: "440"
          file-ownership: 0:100
    share-pid-namespace: false
    variables:
      - name: MY_SECRET
        value-from-vault-secret:
          vault: foo
          secret: for-all
          key: cax
    init-containers:
      - name: setup
        mounts:
          - volume-name: my-config
            files:
              - name: api-cacert.pem
                mount-path: /certs/api-cacert.pem
            mode: read-only
        additional-capabilities: []
        devices:
          device-labels:
            - rtc
        memory: 10MiB
        cpus: 0.5
        cpu-shares: 1024
        container-log-size: 0B
        container-log-max-days: 100
        container-log-archive: false
        image: popcorn-systems/mydb:3.2
        entrypoint:
          - do-setup.sh
        cmd: []
        user: 100
        container-layer-size: 10 MiB
        env:
          APPROLE_SECRET_ID: ${SYS_APPROLE_SECRET_ID}
        approle: name
        security:
          selinux:
            disabled: true
          apparmor:
            disabled: true
        gpu:
          labels:
            - gpu-all
          number-gpus: 1
          gpu-patterns:
            - vendor == "NVIDIA", display-mode == "Enabled"
    containers:
      - name: mydb
        mounts:
          - volume-name: fast-storage
            mount-path: /cache
            mode: read-write
          - volume-name: my-config
            files:
              - name: api-cacert.pem
                mount-path: /certs/api-cacert.pem
              - name: test0.conf
                mount-path: /etc/t.conf
            mode: read-only
          - volume-name: my-secrets
            mount-path: /etc/secrets
            mode: read-only
        additional-capabilities: []
        devices:
          device-labels:
            - rtc
        memory: 1GiB
        cpus: 0.5
        cpu-shares: 1024
        container-log-size: 100 MiB
        container-log-max-days: 14
        container-log-archive: false
        image: popcorn-systems/mydb:3.2
        entrypoint:
          - /bin/start-mydb
        cmd:
          - "-s"
        user: 1000:1000
        container-layer-size: 10 MiB
        env:
          FOO: "42"
          BAZ: ${MY_SECRET}
          APPROLE_SECRET_ID: ${SYS_APPROLE_SECRET_ID}
          API_CA_CERT: ${SYS_API_CA_CERT}
        approle: name
        security:
          selinux:
            disabled: true
          apparmor:
            disabled: true
        gpu:
          labels:
            - gpu-all
          number-gpus: 1
          gpu-patterns:
            - vendor == "NVIDIA", display-mode == "Enabled"
        delayed-shutdown-cmd:
          - /bin/xctrl
          - "--shutdown"
        on-mounted-file-change:
          cmd:
            - touch
            - /tmp/cfg-chg
        probes:
          startup:
            exec:
              cmd:
                - nc
                - "-l"
                - "-p"
                - "9001"
                - "-e"
                - echo
                - probe-started
            initial-delay: 0s
            timeout: 3s
            period: 10s
            success-threshold: 1
            failure-threshold: 3
          readiness:
            tcp:
              port: 443
            initial-delay: 0s
            timeout: 1s
            period: 10s
            success-threshold: 1
            failure-threshold: 3
          liveness:
            http:
              scheme: https
              host: foo.com
              port: 443
              path: /healthz
              request-headers:
                Accept: application/yaml
            initial-delay: 0s
            timeout: 1s
            period: 10s
            success-threshold: 1
            failure-threshold: 3
    network:
      ingress-ip-per-instance:
        protocols:
          - name: tcp
            port-ranges: "9000"
        match-interface-labels: movie-theater-owner.com/external
        match-ipv4-range-labels: movie-theater-owner.com/private
        dns-records:
          domains:
            - domain: default
              srv:
                - name: _http._tcp
                  priority: 0
                  port: 80
      outbound-access:
        default-action: allow
        rules:
          192.0.2.0/24: deny
    site-dns-records:
      domains:
        - domain: default
          srv:
            - name: _http._tcp
              priority: 1
              port: 80
              weight: 100
              target: nginx.web.acme.foo.bar.com
          cname:
            - name: www
              cname: nginx.web.acme.foo.bar.com
          naptr:
            - name: mailer
              order: 102
              preference: 10
              flags: U
              services: E2U+email
              regexp: "!^.*$!mailto:information@example.com!"
              replacement: _http._tcp.nginx.web.acme.foo.bar.com
resources:
  network:
    upstream-bandwidth-per-host: 100Mbit/s
    downstream-bandwidth-per-host: 1Gbit/s
network:
  shared-application-network: mynetwork
on-mutable-variable-change: restart-service-instance
upgrade-from:
  - version-regexp: "2\\.4\\..*"
    method: per-service
    services:
      - name: mysvc
        instances-in-parallel: 1
        healthy-time: 1m
  - version-regexp: "2\\.3\\..*"
    method: per-service
    services:
      - name: mysvc
        instances-in-parallel: 2
        healthy-time: 10m
  - version-regexp: "2\\..*"
    method: stop-and-restart

Delete an application

SecurityaccessToken
Request
path Parameters
tenant-name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

name of tenant

application-name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

The name of the application.

query Parameters
validate
string <enumeration>

Validate the request but do not actually perform the requested operation

Value: "true"
Responses
204

No Content

400

Bad Request

401

Unauthorized

403

Forbidden

404

Not Found

412

Precondition Failed

503

Service Unavailable (strongbox sealed)

delete/v1/config/tenants/{tenant-name}/applications/{application-name}

Replace or create a new application

SecurityaccessToken
Request
path Parameters
tenant-name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

name of tenant

application-name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

The name of the application.

query Parameters
validate
string <enumeration>

Validate the request but do not actually perform the requested operation

Value: "true"
Request Body schema:
name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

The name of the application.

version
string <version> ^[a-zA-Z0-9\-.+]+$

The version of the application.

object

Map of string keys and values that can be used to categorize applications. These labels are not used directly by system.

A label name consists of an optional prefix followed by /, followed by a name segment. The optional prefix is a DNS host name (must match inet:domain-name). The name segment must match ava:name.

The prefix system is used for labels assigned by the system.

Label names without prefixes are reserved for application owners.

For example:

  • system/controller
  • example.com/location.city
  • example.com/color
  • color
required
Array of containers (object) or vm (object)
object

Constraints on per-application resources.

object
on-mutable-variable-change
string <enumeration>
Default: "restart-service-instance"
  • upgrade-application: Run the application upgrade procedure.
  • restart-service-instance: Restart affected service instances. The service instances are restarted without the coordination that upgrade-application provides. This is the quickest way to change the service instances, but it means that there might be no service instances running for a short period of time.
  • ignore: Do not do anything.
    This can be useful if the containers for example use the mutable variable only when they start.

Controls what happens if a mutable variable that is referenced in a container's env, cmd, or entrypoint is changed.

Array of objects

The order of the entries in this list is significant.

If present and the application's version is changed, the application is upgraded according to this specification. The list entries are checked in the given order. If the application's current version matches the version-regexp in the list entry, it is used, and the rest of the list entries are ignored.

If no list entry matches, containers are stopped and restarted as needed, without any synchronization.

If the application's version isn't changed, but the application specification is modified, containers are stopped and restarted as needed, without any synchronization.

Responses
201

Created

204

No Content

400

Bad Request

401

Unauthorized

403

Forbidden

404

Not Found

412

Precondition Failed

503

Service Unavailable (strongbox sealed)

put/v1/config/tenants/{tenant-name}/applications/{application-name}
Request samples
name: myapp
version: 2.4.2
labels:
  color: green
services:
  - name: mysvc
    delayed-shutdown:
      timeout: 30m
      max-number-of-instances: 3
    mode: replicated
    replicas: 2
    placement:
      preferred-affinity:
        services: []
      preferred-anti-affinity:
        services:
          - mydb
      match-host-labels: movie-theater-owner.com/host_size = medium
    volumes:
      - name: fast-storage
        ephemeral-volume:
          size: 1GB
          file-mode: "770"
          file-ownership: 1000:1000
          match-volume-labels: movie-theater-owner.com/speed = fast
      - name: persistent-storage
        persistent-volume:
          size: 1GB
          file-mode: "770"
          file-ownership: 1000:1000
          match-volume-labels: movie-theater-owner.com/speed = fast
      - name: my-config
        config-map:
          items:
            - name: api-cacert.pem
              data: ${SYS_API_CA_CERT}
              file-mode: "444"
              file-ownership: 0:0
            - name: test0.conf
              data: |
                foo: bar
                secret: ${MY_SECRET}
              file-mode: "400"
              file-ownership: 100:0
      - name: my-secrets
        vault-secret:
          vault: foo
          secret: for-alpine
          file-mode: "440"
          file-ownership: 0:100
    share-pid-namespace: false
    variables:
      - name: MY_SECRET
        value-from-vault-secret:
          vault: foo
          secret: for-all
          key: cax
    init-containers:
      - name: setup
        mounts:
          - volume-name: my-config
            files:
              - name: api-cacert.pem
                mount-path: /certs/api-cacert.pem
            mode: read-only
        additional-capabilities: []
        devices:
          device-labels:
            - rtc
        memory: 10MiB
        cpus: 0.5
        cpu-shares: 1024
        container-log-size: 0B
        container-log-max-days: 100
        container-log-archive: false
        image: popcorn-systems/mydb:3.2
        entrypoint:
          - do-setup.sh
        cmd: []
        user: 100
        container-layer-size: 10 MiB
        env:
          APPROLE_SECRET_ID: ${SYS_APPROLE_SECRET_ID}
        approle: name
        security:
          selinux:
            disabled: true
          apparmor:
            disabled: true
        gpu:
          labels:
            - gpu-all
          number-gpus: 1
          gpu-patterns:
            - vendor == "NVIDIA", display-mode == "Enabled"
    containers:
      - name: mydb
        mounts:
          - volume-name: fast-storage
            mount-path: /cache
            mode: read-write
          - volume-name: my-config
            files:
              - name: api-cacert.pem
                mount-path: /certs/api-cacert.pem
              - name: test0.conf
                mount-path: /etc/t.conf
            mode: read-only
          - volume-name: my-secrets
            mount-path: /etc/secrets
            mode: read-only
        additional-capabilities: []
        devices:
          device-labels:
            - rtc
        memory: 1GiB
        cpus: 0.5
        cpu-shares: 1024
        container-log-size: 100 MiB
        container-log-max-days: 14
        container-log-archive: false
        image: popcorn-systems/mydb:3.2
        entrypoint:
          - /bin/start-mydb
        cmd:
          - "-s"
        user: 1000:1000
        container-layer-size: 10 MiB
        env:
          FOO: "42"
          BAZ: ${MY_SECRET}
          APPROLE_SECRET_ID: ${SYS_APPROLE_SECRET_ID}
          API_CA_CERT: ${SYS_API_CA_CERT}
        approle: name
        security:
          selinux:
            disabled: true
          apparmor:
            disabled: true
        gpu:
          labels:
            - gpu-all
          number-gpus: 1
          gpu-patterns:
            - vendor == "NVIDIA", display-mode == "Enabled"
        delayed-shutdown-cmd:
          - /bin/xctrl
          - "--shutdown"
        on-mounted-file-change:
          cmd:
            - touch
            - /tmp/cfg-chg
        probes:
          startup:
            exec:
              cmd:
                - nc
                - "-l"
                - "-p"
                - "9001"
                - "-e"
                - echo
                - probe-started
            initial-delay: 0s
            timeout: 3s
            period: 10s
            success-threshold: 1
            failure-threshold: 3
          readiness:
            tcp:
              port: 443
            initial-delay: 0s
            timeout: 1s
            period: 10s
            success-threshold: 1
            failure-threshold: 3
          liveness:
            http:
              scheme: https
              host: foo.com
              port: 443
              path: /healthz
              request-headers:
                Accept: application/yaml
            initial-delay: 0s
            timeout: 1s
            period: 10s
            success-threshold: 1
            failure-threshold: 3
    network:
      ingress-ip-per-instance:
        protocols:
          - name: tcp
            port-ranges: "9000"
        match-interface-labels: movie-theater-owner.com/external
        match-ipv4-range-labels: movie-theater-owner.com/private
        dns-records:
          domains:
            - domain: default
              srv:
                - name: _http._tcp
                  priority: 0
                  port: 80
      outbound-access:
        default-action: allow
        rules:
          192.0.2.0/24: deny
    site-dns-records:
      domains:
        - domain: default
          srv:
            - name: _http._tcp
              priority: 1
              port: 80
              weight: 100
              target: nginx.web.acme.foo.bar.com
          cname:
            - name: www
              cname: nginx.web.acme.foo.bar.com
          naptr:
            - name: mailer
              order: 102
              preference: 10
              flags: U
              services: E2U+email
              regexp: "!^.*$!mailto:information@example.com!"
              replacement: _http._tcp.nginx.web.acme.foo.bar.com
resources:
  network:
    upstream-bandwidth-per-host: 100Mbit/s
    downstream-bandwidth-per-host: 1Gbit/s
network:
  shared-application-network: mynetwork
on-mutable-variable-change: restart-service-instance
upgrade-from:
  - version-regexp: "2\\.4\\..*"
    method: per-service
    services:
      - name: mysvc
        instances-in-parallel: 1
        healthy-time: 1m
  - version-regexp: "2\\.3\\..*"
    method: per-service
    services:
      - name: mysvc
        instances-in-parallel: 2
        healthy-time: 10m
  - version-regexp: "2\\..*"
    method: stop-and-restart

Retrieve the configuration of an application

SecurityaccessToken
Request
path Parameters
tenant-name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

name of tenant

application-name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

The name of the application.

query Parameters
fields
string

Retrieve only requested fields from the resource

See section fields

validate
string <enumeration>

Validate the request but do not actually perform the requested operation

Value: "true"
version-list
string <enumeration>

Retrieve list of old versions

Value: "true"
version
string

Retrieve requested old version of the resource

Responses
200

OK

400

Bad Request

401

Unauthorized

403

Forbidden

404

Not Found

412

Precondition Failed

503

Service Unavailable (strongbox sealed)

get/v1/config/tenants/{tenant-name}/applications/{application-name}
Response samples
name: myapp
version: 2.4.2
labels:
  color: green
services:
  - name: mysvc
    delayed-shutdown:
      timeout: 30m
      max-number-of-instances: 3
    mode: replicated
    replicas: 2
    placement:
      preferred-affinity:
        services: []
      preferred-anti-affinity:
        services:
          - mydb
      match-host-labels: movie-theater-owner.com/host_size = medium
    volumes:
      - name: fast-storage
        ephemeral-volume:
          size: 1GB
          file-mode: "770"
          file-ownership: 1000:1000
          match-volume-labels: movie-theater-owner.com/speed = fast
      - name: persistent-storage
        persistent-volume:
          size: 1GB
          file-mode: "770"
          file-ownership: 1000:1000
          match-volume-labels: movie-theater-owner.com/speed = fast
      - name: my-config
        config-map:
          items:
            - name: api-cacert.pem
              data: ${SYS_API_CA_CERT}
              file-mode: "444"
              file-ownership: 0:0
            - name: test0.conf
              data: |
                foo: bar
                secret: ${MY_SECRET}
              file-mode: "400"
              file-ownership: 100:0
      - name: my-secrets
        vault-secret:
          vault: foo
          secret: for-alpine
          file-mode: "440"
          file-ownership: 0:100
    share-pid-namespace: false
    variables:
      - name: MY_SECRET
        value-from-vault-secret:
          vault: foo
          secret: for-all
          key: cax
    init-containers:
      - name: setup
        mounts:
          - volume-name: my-config
            files:
              - name: api-cacert.pem
                mount-path: /certs/api-cacert.pem
            mode: read-only
        additional-capabilities: []
        devices:
          device-labels:
            - rtc
        memory: 10MiB
        cpus: 0.5
        cpu-shares: 1024
        container-log-size: 0B
        container-log-max-days: 100
        container-log-archive: false
        image: popcorn-systems/mydb:3.2
        entrypoint:
          - do-setup.sh
        cmd: []
        user: 100
        container-layer-size: 10 MiB
        env:
          APPROLE_SECRET_ID: ${SYS_APPROLE_SECRET_ID}
        approle: name
        security:
          selinux:
            disabled: true
          apparmor:
            disabled: true
        gpu:
          labels:
            - gpu-all
          number-gpus: 1
          gpu-patterns:
            - vendor == "NVIDIA", display-mode == "Enabled"
    containers:
      - name: mydb
        mounts:
          - volume-name: fast-storage
            mount-path: /cache
            mode: read-write
          - volume-name: my-config
            files:
              - name: api-cacert.pem
                mount-path: /certs/api-cacert.pem
              - name: test0.conf
                mount-path: /etc/t.conf
            mode: read-only
          - volume-name: my-secrets
            mount-path: /etc/secrets
            mode: read-only
        additional-capabilities: []
        devices:
          device-labels:
            - rtc
        memory: 1GiB
        cpus: 0.5
        cpu-shares: 1024
        container-log-size: 100 MiB
        container-log-max-days: 14
        container-log-archive: false
        image: popcorn-systems/mydb:3.2
        entrypoint:
          - /bin/start-mydb
        cmd:
          - "-s"
        user: 1000:1000
        container-layer-size: 10 MiB
        env:
          FOO: "42"
          BAZ: ${MY_SECRET}
          APPROLE_SECRET_ID: ${SYS_APPROLE_SECRET_ID}
          API_CA_CERT: ${SYS_API_CA_CERT}
        approle: name
        security:
          selinux:
            disabled: true
          apparmor:
            disabled: true
        gpu:
          labels:
            - gpu-all
          number-gpus: 1
          gpu-patterns:
            - vendor == "NVIDIA", display-mode == "Enabled"
        delayed-shutdown-cmd:
          - /bin/xctrl
          - "--shutdown"
        on-mounted-file-change:
          cmd:
            - touch
            - /tmp/cfg-chg
        probes:
          startup:
            exec:
              cmd:
                - nc
                - "-l"
                - "-p"
                - "9001"
                - "-e"
                - echo
                - probe-started
            initial-delay: 0s
            timeout: 3s
            period: 10s
            success-threshold: 1
            failure-threshold: 3
          readiness:
            tcp:
              port: 443
            initial-delay: 0s
            timeout: 1s
            period: 10s
            success-threshold: 1
            failure-threshold: 3
          liveness:
            http:
              scheme: https
              host: foo.com
              port: 443
              path: /healthz
              request-headers:
                Accept: application/yaml
            initial-delay: 0s
            timeout: 1s
            period: 10s
            success-threshold: 1
            failure-threshold: 3
    network:
      ingress-ip-per-instance:
        protocols:
          - name: tcp
            port-ranges: "9000"
        match-interface-labels: movie-theater-owner.com/external
        match-ipv4-range-labels: movie-theater-owner.com/private
        dns-records:
          domains:
            - domain: default
              srv:
                - name: _http._tcp
                  priority: 0
                  port: 80
      outbound-access:
        default-action: allow
        rules:
          192.0.2.0/24: deny
    site-dns-records:
      domains:
        - domain: default
          srv:
            - name: _http._tcp
              priority: 1
              port: 80
              weight: 100
              target: nginx.web.acme.foo.bar.com
          cname:
            - name: www
              cname: nginx.web.acme.foo.bar.com
          naptr:
            - name: mailer
              order: 102
              preference: 10
              flags: U
              services: E2U+email
              regexp: "!^.*$!mailto:information@example.com!"
              replacement: _http._tcp.nginx.web.acme.foo.bar.com
resources:
  network:
    upstream-bandwidth-per-host: 100Mbit/s
    downstream-bandwidth-per-host: 1Gbit/s
network:
  shared-application-network: mynetwork
on-mutable-variable-change: restart-service-instance
upgrade-from:
  - version-regexp: "2\\.4\\..*"
    method: per-service
    services:
      - name: mysvc
        instances-in-parallel: 1
        healthy-time: 1m
  - version-regexp: "2\\.3\\..*"
    method: per-service
    services:
      - name: mysvc
        instances-in-parallel: 2
        healthy-time: 10m
  - version-regexp: "2\\..*"
    method: stop-and-restart

Retrieve the state of all applications

SecurityaccessToken
Request
path Parameters
tenant-name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

name of tenant

query Parameters
fields
string

Retrieve only requested fields from the resource

See section fields

site
string

Send the request to the specfifed site

content
string <enumeration>

Filter descendant nodes in the response

Enum: "config" "nonconfig"
keys
string <enumeration>

Retrieve only the keys for the list

Value: "true"
count
string <enumeration>

Retrieve only the number of elements in the list

Value: "true"
Responses
200

OK

400

Bad Request

401

Unauthorized

403

Forbidden

404

Not Found

503

Service Unavailable (strongbox sealed)

get/v1/state/tenants/{tenant-name}/applications
Response samples
- name: myapp
  version: 2.4.2
  labels:
    color: green
  services:
    - name: mysvc
      delayed-shutdown:
        timeout: 30m
        max-number-of-instances: 3
      mode: replicated
      replicas: 2
      placement:
        preferred-affinity:
          services: []
        preferred-anti-affinity:
          services:
            - mydb
        match-host-labels: movie-theater-owner.com/host_size = medium
      volumes:
        - name: fast-storage
          ephemeral-volume:
            size: 1GB
            file-mode: "770"
            file-ownership: 1000:1000
            match-volume-labels: movie-theater-owner.com/speed = fast
        - name: persistent-storage
          persistent-volume:
            size: 1GB
            file-mode: "770"
            file-ownership: 1000:1000
            match-volume-labels: movie-theater-owner.com/speed = fast
        - name: my-config
          config-map:
            items:
              - name: api-cacert.pem
                data: ${SYS_API_CA_CERT}
                file-mode: "444"
                file-ownership: 0:0
              - name: test0.conf
                data: |
                  foo: bar
                  secret: ${MY_SECRET}
                file-mode: "400"
                file-ownership: 100:0
        - name: my-secrets
          vault-secret:
            vault: foo
            secret: for-alpine
            file-mode: "440"
            file-ownership: 0:100
      share-pid-namespace: false
      variables:
        - name: MY_SECRET
          value-from-vault-secret:
            vault: foo
            secret: for-all
            key: cax
      init-containers:
        - name: setup
          mounts:
            - volume-name: my-config
              files:
                - name: api-cacert.pem
                  mount-path: /certs/api-cacert.pem
              mode: read-only
          additional-capabilities: []
          devices:
            device-labels:
              - rtc
          memory: 10MiB
          cpus: 0.5
          cpu-shares: 1024
          container-log-size: 0B
          container-log-max-days: 100
          container-log-archive: false
          image: popcorn-systems/mydb:3.2
          image-status:
            status: present
            digest: sha256:4266485e304a825d82c3
            last-pull: 2022-06-28T12:44:15.885Z
            pull-time: 2s
          entrypoint:
            - do-setup.sh
          cmd: []
          user: 100
          container-layer-size: 10 MiB
          env:
            APPROLE_SECRET_ID: ${SYS_APPROLE_SECRET_ID}
          approle: name
          security:
            selinux:
              disabled: true
            apparmor:
              disabled: true
          gpu:
            labels:
              - gpu-all
            number-gpus: 1
            gpu-patterns:
              - vendor == "NVIDIA", display-mode == "Enabled"
      containers:
        - name: mydb
          mounts:
            - volume-name: fast-storage
              mount-path: /cache
              mode: read-write
            - volume-name: my-config
              files:
                - name: api-cacert.pem
                  mount-path: /certs/api-cacert.pem
                - name: test0.conf
                  mount-path: /etc/t.conf
              mode: read-only
            - volume-name: my-secrets
              mount-path: /etc/secrets
              mode: read-only
          additional-capabilities: []
          devices:
            device-labels:
              - rtc
          memory: 1GiB
          cpus: 0.5
          cpu-shares: 1024
          container-log-size: 100 MiB
          container-log-max-days: 14
          container-log-archive: false
          image: popcorn-systems/mydb:3.2
          image-status:
            status: present
            digest: sha256:4266485e304a825d82c3
            last-pull: 2022-06-28T12:44:15.885Z
            pull-time: 2s
          entrypoint:
            - /bin/start-mydb
          cmd:
            - "-s"
          user: 1000:1000
          container-layer-size: 10 MiB
          env:
            FOO: "42"
            BAZ: ${MY_SECRET}
            APPROLE_SECRET_ID: ${SYS_APPROLE_SECRET_ID}
            API_CA_CERT: ${SYS_API_CA_CERT}
          approle: name
          security:
            selinux:
              disabled: true
            apparmor:
              disabled: true
          gpu:
            labels:
              - gpu-all
            number-gpus: 1
            gpu-patterns:
              - vendor == "NVIDIA", display-mode == "Enabled"
          delayed-shutdown-cmd:
            - /bin/xctrl
            - "--shutdown"
          on-mounted-file-change:
            cmd:
              - touch
              - /tmp/cfg-chg
          probes:
            startup:
              exec:
                cmd:
                  - nc
                  - "-l"
                  - "-p"
                  - "9001"
                  - "-e"
                  - echo
                  - probe-started
              initial-delay: 0s
              timeout: 3s
              period: 10s
              success-threshold: 1
              failure-threshold: 3
            readiness:
              tcp:
                port: 443
              initial-delay: 0s
              timeout: 1s
              period: 10s
              success-threshold: 1
              failure-threshold: 3
            liveness:
              http:
                scheme: https
                host: foo.com
                port: 443
                path: /healthz
                request-headers:
                  Accept: application/yaml
              initial-delay: 0s
              timeout: 1s
              period: 10s
              success-threshold: 1
              failure-threshold: 3
      network:
        ingress-ip-per-instance:
          protocols:
            - name: tcp
              port-ranges: "9000"
          match-interface-labels: movie-theater-owner.com/external
          match-ipv4-range-labels: movie-theater-owner.com/private
          dns-records:
            domains:
              - domain: default
                srv:
                  - name: _http._tcp
                    priority: 0
                    port: 80
        outbound-access:
          default-action: allow
          rules:
            192.0.2.0/24: deny
      site-dns-records:
        domains:
          - domain: default
            srv:
              - name: _http._tcp
                priority: 1
                port: 80
                weight: 100
                target: nginx.web.acme.foo.bar.com
            cname:
              - name: www
                cname: nginx.web.acme.foo.bar.com
            naptr:
              - name: mailer
                order: 102
                preference: 10
                flags: U
                services: E2U+email
                regexp: "!^.*$!mailto:information@example.com!"
                replacement: _http._tcp.nginx.web.acme.foo.bar.com
  resources:
    network:
      upstream-bandwidth-per-host: 100Mbit/s
      downstream-bandwidth-per-host: 1Gbit/s
  network:
    shared-application-network: mynetwork
  on-mutable-variable-change: restart-service-instance
  upgrade-from:
    - version-regexp: "2\\.4\\..*"
      method: per-service
      services:
        - name: mysvc
          instances-in-parallel: 1
          healthy-time: 1m
    - version-regexp: "2\\.3\\..*"
      method: per-service
      services:
        - name: mysvc
          instances-in-parallel: 2
          healthy-time: 10m
    - version-regexp: "2\\..*"
      method: stop-and-restart
  config-modified-time: 2021-12-13T09:50:21Z
  locally-deployed: true
  application-deployment: myapp-deployment
  oper-status: running
  application-queue:
    - 2.5.0
  service-instances:
    - name: mysvc-1
      application-version: 2.4.2
      oper-status: running
      ready: true
      host: host-001
      application-network:
        shared-application-network: mynetwork
        ips:
          - 172.19.0.1/16
        dns-records:
          - cr-1.myapp.internal. 15 IN A 172.19.0.1
          - cr.myapp.internal. 15 IN A 172.19.0.1
      gateway-network:
        ips:
          - 172.23.255.2/24
      ingress:
        interface: eth0
        ips:
          - 192.168.100.97
        dns-records:
          - cr-1.myapp.stockholm-sergel.trial.avassa.net. 15 IN A 192.168.100.97
          - cr.myapp.stockholm-sergel.trial.avassa.net. 15 IN A 192.168.100.97
      ephemeral-volumes:
        - name: fast-storage
          size: 1GB
          host-volume: fast-host-storage
      persistent-volumes:
        - name: persistent-storage
          size: 1GB
          host-volume: fast-host-storage
      init-containers:
        - name: setup
          id: 189d9234f12c
          oper-status: completed
          start-time: 2021-02-17T12:08:39.100Z
          current-restarts: 0
          total-restarts: 0
          devices:
            - /dev/rtc0
          gpus:
            - id: GPU-de663f3f-856c-4e48-9269-c2269169bfda
      containers:
        - name: mydb
          id: 75be6d60d41f
          oper-status: running
          ready: true
          start-time: 2021-02-17T12:08:39.202Z
          current-restarts: 0
          total-restarts: 0
          probes:
            startup:
              status: success
            readiness:
              status: success
            liveness:
              status: success
          devices:
            - /dev/rtc0
          gpus:
            - id: GPU-de663f3f-856c-4e48-9269-c2269169bfda
  

Retrieve the state of an application

SecurityaccessToken
Request
path Parameters
tenant-name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

name of tenant

application-name
required
string <name> ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$

The name of the application.

query Parameters
fields
string

Retrieve only requested fields from the resource

See section fields

site
string

Send the request to the specfifed site

content
string <enumeration>

Filter descendant nodes in the response

Enum: "config" "nonconfig"
Responses
200

OK

400

Bad Request

401

Unauthorized

403

Forbidden

404

Not Found

503

Service Unavailable (strongbox sealed)

get/v1/state/tenants/{tenant-name}/applications/{application-name}
Response samples
name: myapp
version: 2.4.2
labels:
  color: green
services:
  - name: mysvc
    delayed-shutdown:
      timeout: 30m
      max-number-of-instances: 3
    mode: replicated
    replicas: 2
    placement:
      preferred-affinity:
        services: []
      preferred-anti-affinity:
        services:
          - mydb
      match-host-labels: movie-theater-owner.com/host_size = medium
    volumes:
      - name: fast-storage
        ephemeral-volume:
          size: 1GB
          file-mode: "770"
          file-ownership: 1000:1000
          match-volume-labels: movie-theater-owner.com/speed = fast
      - name: persistent-storage
        persistent-volume:
          size: 1GB
          file-mode: "770"
          file-ownership: 1000:1000
          match-volume-labels: movie-theater-owner.com/speed = fast
      - name: my-config
        config-map:
          items:
            - name: api-cacert.pem
              data: ${SYS_API_CA_CERT}
              file-mode: "444"
              file-ownership: 0:0
            - name: test0.conf
              data: |
                foo: bar
                secret: ${MY_SECRET}
              file-mode: "400"
              file-ownership: 100:0
      - name: my-secrets
        vault-secret:
          vault: foo
          secret: for-alpine
          file-mode: "440"
          file-ownership: 0:100
    share-pid-namespace: false
    variables:
      - name: MY_SECRET
        value-from-vault-secret:
          vault: foo
          secret: for-all
          key: cax
    init-containers:
      - name: setup
        mounts:
          - volume-name: my-config
            files:
              - name: api-cacert.pem
                mount-path: /certs/api-cacert.pem
            mode: read-only
        additional-capabilities: []
        devices:
          device-labels:
            - rtc
        memory: 10MiB
        cpus: 0.5
        cpu-shares: 1024
        container-log-size: 0B
        container-log-max-days: 100
        container-log-archive: false
        image: popcorn-systems/mydb:3.2
        image-status:
          status: present
          digest: sha256:4266485e304a825d82c3
          last-pull: 2022-06-28T12:44:15.885Z
          pull-time: 2s
        entrypoint:
          - do-setup.sh
        cmd: []
        user: 100
        container-layer-size: 10 MiB
        env:
          APPROLE_SECRET_ID: ${SYS_APPROLE_SECRET_ID}
        approle: name
        security:
          selinux:
            disabled: true
          apparmor:
            disabled: true
        gpu:
          labels:
            - gpu-all
          number-gpus: 1
          gpu-patterns:
            - vendor == "NVIDIA", display-mode == "Enabled"
    containers:
      - name: mydb
        mounts:
          - volume-name: fast-storage
            mount-path: /cache
            mode: read-write
          - volume-name: my-config
            files:
              - name: api-cacert.pem
                mount-path: /certs/api-cacert.pem
              - name: test0.conf
                mount-path: /etc/t.conf
            mode: read-only
          - volume-name: my-secrets
            mount-path: /etc/secrets
            mode: read-only
        additional-capabilities: []
        devices:
          device-labels:
            - rtc
        memory: 1GiB
        cpus: 0.5
        cpu-shares: 1024
        container-log-size: 100 MiB
        container-log-max-days: 14
        container-log-archive: false
        image: popcorn-systems/mydb:3.2
        image-status:
          status: present
          digest: sha256:4266485e304a825d82c3
          last-pull: 2022-06-28T12:44:15.885Z
          pull-time: 2s
        entrypoint:
          - /bin/start-mydb
        cmd:
          - "-s"
        user: 1000:1000
        container-layer-size: 10 MiB
        env:
          FOO: "42"
          BAZ: ${MY_SECRET}
          APPROLE_SECRET_ID: ${SYS_APPROLE_SECRET_ID}
          API_CA_CERT: ${SYS_API_CA_CERT}
        approle: name
        security:
          selinux:
            disabled: true
          apparmor:
            disabled: true
        gpu:
          labels:
            - gpu-all
          number-gpus: 1
          gpu-patterns:
            - vendor == "NVIDIA", display-mode == "Enabled"
        delayed-shutdown-cmd:
          - /bin/xctrl
          - "--shutdown"
        on-mounted-file-change:
          cmd:
            - touch
            - /tmp/cfg-chg
        probes:
          startup:
            exec:
              cmd:
                - nc
                - "-l"
                - "-p"
                - "9001"
                - "-e"
                - echo
                - probe-started
            initial-delay: 0s
            timeout: 3s
            period: 10s
            success-threshold: 1
            failure-threshold: 3
          readiness:
            tcp:
              port: 443
            initial-delay: 0s
            timeout: 1s
            period: 10s
            success-threshold: 1
            failure-threshold: 3
          liveness:
            http:
              scheme: https
              host: foo.com
              port: 443
              path: /healthz
              request-headers:
                Accept: application/yaml
            initial-delay: 0s
            timeout: 1s
            period: 10s
            success-threshold: 1
            failure-threshold: 3
    network:
      ingress-ip-per-instance:
        protocols:
          - name: tcp
            port-ranges: "9000"
        match-interface-labels: movie-theater-owner.com/external
        match-ipv4-range-labels: movie-theater-owner.com/private
        dns-records:
          domains:
            - domain: default
              srv:
                - name: _http._tcp
                  priority: 0
                  port: 80
      outbound-access:
        default-action: allow
        rules:
          192.0.2.0/24: deny
    site-dns-records:
      domains:
        - domain: default
          srv:
            - name: _http._tcp
              priority: 1
              port: 80
              weight: 100
              target: nginx.web.acme.foo.bar.com
          cname:
            - name: www
              cname: nginx.web.acme.foo.bar.com
          naptr:
            - name: mailer
              order: 102
              preference: 10
              flags: U
              services: E2U+email
              regexp: "!^.*$!mailto:information@example.com!"
              replacement: _http._tcp.nginx.web.acme.foo.bar.com
resources:
  network:
    upstream-bandwidth-per-host: 100Mbit/s
    downstream-bandwidth-per-host: 1Gbit/s
network:
  shared-application-network: mynetwork
on-mutable-variable-change: restart-service-instance
upgrade-from:
  - version-regexp: "2\\.4\\..*"
    method: per-service
    services:
      - name: mysvc
        instances-in-parallel: 1
        healthy-time: 1m
  - version-regexp: "2\\.3\\..*"
    method: per-service
    services:
      - name: mysvc
        instances-in-parallel: 2
        healthy-time: 10m
  - version-regexp: "2\\..*"
    method: stop-and-restart
config-modified-time: 2021-12-13T09:50:21Z
locally-deployed: true
application-deployment: myapp-deployment
oper-status: running
application-queue:
  - 2.5.0
service-instances:
  - name: mysvc-1
    application-version: 2.4.2
    oper-status: running
    ready: true
    host: host-001
    application-network:
      shared-application-network: mynetwork
      ips:
        - 172.19.0.1/16
      dns-records:
        - cr-1.myapp.internal. 15 IN A 172.19.0.1
        - cr.myapp.internal. 15 IN A 172.19.0.1
    gateway-network:
      ips:
        - 172.23.255.2/24
    ingress:
      interface: eth0
      ips:
        - 192.168.100.97
      dns-records:
        - cr-1.myapp.stockholm-sergel.trial.avassa.net. 15 IN A 192.168.100.97
        - cr.myapp.stockholm-sergel.trial.avassa.net. 15 IN A 192.168.100.97
    ephemeral-volumes:
      - name: fast-storage
        size: 1GB
        host-volume: fast-host-storage
    persistent-volumes:
      - name: persistent-storage
        size: 1GB
        host-volume: fast-host-storage
    init-containers:
      - name: setup
        id: 189d9234f12c
        oper-status: completed
        start-time: 2021-02-17T12:08:39.100Z
        current-restarts: 0
        total-restarts: 0
        devices:
          - /dev/rtc0
        gpus:
          - id: GPU-de663f3f-856c-4e48-9269-c2269169bfda
    containers:
      - name: mydb
        id: 75be6d60d41f
        oper-status: running
        ready: true
        start-time: 2021-02-17T12:08:39.202Z
        current-restarts: 0
        total-restarts: 0
        probes:
          startup:
            status: success
          readiness:
            status: success
          liveness:
            status: success
        devices:
          - /dev/rtc0
        gpus:
          - id: GPU-de663f3f-856c-4e48-9269-c2269169bfda