Disable devices in Gateway Startup Script (v8.3.0)

I have glanced through many Gateway startup script questions, some of which don't even have answers, so I'm guessing the community is tired of looking at them, but here's mine. I recently upgraded to v8.3, but I doubt that is the cause of my issue.

I would like to disable the device connections to my PLC's on startup if Ignition is NOT running on my production server. This is for when I restore a backup to a test machine or clone the production server VM for testing. I have some datalogging that does handshaking with the Ignition server, and when other machines start sending the handshakes, madness ensues (among other issues).

I created a separate project just for Gateway events so I don't lose track of where I put the events.

Here is my Gateway startup script. When testing on the weekends, I replace the != with == to verify it works.

def onStartup():
	srvr= system.net.getHostName()
	lgr = system.util.getLogger("GatewayStartupCheck")
	lgr.info("Server name was found to be " + srvr + " BEFORE disabling devices")
	if srvr != 'PAS-OT-IGN':
		lgr.info("Server name matched 'PAS-OT-IGN' so disabling devices")
		deviceDataset = system.device.listDevices()
		lgr.info("Fetched device dataset")
		for rw in deviceDataset:
			lgr.info("Processing " + rw["Name"])
			system.device.setDeviceEnabled(rw["Name"], 0)

The script works because every time I save the project with the change, my devices end up disabled and I see all of the log entries. However, when I actually restart the gateway I only get

"Server name was found to be PAS-OT-IGN BEFORE disabling devices"

and

"Server name matched 'PAS-OT-IGN' so disabling devices"

Since I don't get

"Fetched device dataset"

I conclude that the command

system.device.listDevices()

is stopping execution while other services are starting up. I was thinking that something like

system.util.invokeLater

would be handy, but that is gone in v8.3 and only worked in the Vision client context anyway.

I could put the code in a timer script I guess, but it seems messy to be running it every X milliseconds, and if I run it infrequently enough, then some of the damage will get done before it executes for the first time.

Can anyone see something I missed or have a better idea?

An obvious answer is to restore a backup to a machine that can't reach the PLCs first and then disable everything. That's quite a bit of work when I'm doing frequent restores and will often require the help of our IT department, which has limited resources (meaning I have to wait when I really need to keep iterating when I am catching bugs).

The right answer is to use deployment modes. Such configs would stay in your gateway backup and would be triggered by local configuration in each gateway. So that the same gateway backup will simply handle both cases for you.

Thank you very much Phil. At first glance, I’m finding the phrase

Deployment modes are created and edited on the Gateway, but you will need to modify the Gateway Configuration File to change the deployment mode your Gateway is running in.

concerning - I don’t want to have to modify the gateway config file on a clone for example - but I will dig in a bit more and see if I can get this work.

This looks very powerful.

Hmmm. I thought deployment mode could be set via an environment variable. Perhaps @Kevin.Collins knows?

Currently deployment modes work best in a containerized environment, because they allow you to "merge" argument overrides in to the base definition without actually modifying any files:

On our short list are some improvements to the deployment mode experience for folks who are not all in on containerization/orchestration.

Setting the deployment mode via an environment variable is not yet supported, you've got to supply the Java system property via a JVM argument, -Dignition.config.mode=yourdeploymentmode. As @paul-griffith mentions, we're going to be doing additional refinements in this area. However, I've got some guidance that might be useful in the meantime.

Currently, at time of writing w/ 8.3.0, if you add the deployment mode arg explicitly to your data/ignition.conf, it will be within any gateway backup (GWBK) that you collect. Thus, if you restore it to a given gateway, the gateway will assume that deployment mode. This isn't going to be what you want, so we've got to define that arg in a different scope.

This is where you can use wrapper.java.additional_file and wrapper.java.additional_file.required to your advantage.

Below are some steps to configure the deployment mode in a way that will be excluded from the gateway backup:

  1. Create a hidden folder called data/.custom under your Ignition installation.

  2. Add the following lines to your data/ignition.conf (ideally, place after the other "Java Additional Parameters" section):

    # Java Additional Parameters via file
    wrapper.java.additional_file=data/.custom/jvm-args.txt
    wrapper.java.additional_file.required=FALSE
    
  3. Place a file data/.custom/jvm-args.txt with the following contents:

    #encoding=UTF-8
    -Dignition.config.mode=mydeploymentmode
    

You can then customize the contents of data/.custom/jvm-args.txt on a given Ignition Gateway to set the target deployment mode. You can also omit the file altogether to stay in the core deployment mode. This definition will not be collected in a gateway backup (GWBK) nor will it be disturbed by a gateway restore.

Hope this helps!

2 Likes

Perfect!

Thank you both @kcollins1 and @paul-griffith for taking the time to help.