Pyro-gateway - a TypeScript library for starting Ignition Docker containers

pyro-gateway

pyro-gateway provides an API for starting Ignition Docker containers from within JavaScript. This library is intended for use in testing environments where you need a short-lived, programmatically configured, ephemeral gateway.

Usage

Start a new Gateway

import { IgnitionContainer } from '@mussonindustrial/pyro-gateway'

const gateway = await new IgnitionContainer('8.1.33')
    .withModules(['perspective'])
    .withGatewayName('My New Gateway')
    .start()

Start a Gateway from a Backup

import { IgnitionContainer } from '@mussonindustrial/pyro-gateway'

const gateway = await new IgnitionContainer('8.1.33')
    .withGatewayBackup('/path/to/gateway.gwbk')
    .start()

Setting Gateway Properties

Gateway properties can be set before startup through the various .with~ methods.

// Current available setter methods
.withEdition(edition: GatewayEdition)
.withHTTPPort(port: number)
.withHTTPSPort(port: number)
.withModules(modules: ModuleIdentifier[])
.withGatewayName(name: string)
.withGatewayBackup(path: string)

The eventual goal is to provide a complete set of setter methods.
In the meantime, if you wish the directly set environment or runtime variables, they can be accessed through gateway.env and gateway.runtime respectively.

See the GitHub page for full details.

8 Likes

Okay, this is not the most exciting example to sit through, but it's a solid proof of concept of what I've been building towards.

20231205_222416

Demonstrated in the GIF is an example workflow for editing Perspective themes:

  1. A development Ignition container is started and a special "bootstrap-able" gateway backup is loaded.

    • This gateway backup is configured with WebDev endpoints for uploading fonts, themes, and project resource (8.3-light :wink:).
  2. After the gateway is started, a Perspective theme is sent to the gateway.

  3. A change is made to the theme (turning the background red).

  4. Using a file watcher, the change to the theme is detected. The theme is re-compiled (plugins applied, minified, etc.) and uploaded to the gateway.

  5. A project scan is requested and all open Perspective sessions are refreshed.

  6. The new theme is now visible on the development gateway.

  7. (Not shown) After closing the command prompt, the gateway is shutdown and discarded.

Work needs to be done to speed up the iteration time, but all the pieces are here :tada:.

2 Likes

While I salute the work done and the contribution to the ecosystem, I'm not sure I understand the use case for the example above. Does this allow to update files on a remote gateway ?
I guess my question is: What's the advantage of this over a bind mount ? Except for the obvious fact that it's not a bind mount ;p

Yup. Any gateway with the setup/boot-strapping endpoints can be updated. So you could develop your theme on a local gateway with live reloading, then push to production gateway once changes are finalized (or have a CI/CD pipeline do it for you, for multiple gateways).

You’re right, for this example of updating a theme a bind mount would work fine. But, the goal is to allow configuration of more than can be set via bind mounts (database and device connections, etc.).

Then when 8.3 releases, we can drop the WebDev functions and use the native capabilities.

1 Like

v0.3.0 now allows you to perform project/resource imports on the running gateway.

The implementation is pretty naïve at the moment; if you import resources into a project that doesn't exist you'll end up with orphaned files. More work is coming to make it impossible to mess up, but at least it does work.

import { IgnitionContainer } from '@mussonindustrial/pyro-gateway'

const gateway = await new IgnitionContainer('inductiveautomation/ignition:latest')
    .withGatewayBackup('/path/to/gateway.gwbk')
    .start()

gateway.importProject('new-project', '/path/to/project.zip')
gateway.importProjectResources('existing-project', '/path/to/resources.zip')

Edit: Also, moved this post to the Automated Testing category since that is the intended use case.

1 Like