Maven Plugin POST but with Gradle

I am looking at using Gradle instead of Maven for module development, and I have been looking around but haven't found anything obvious.

Is there a way to do the post goal provided by the Maven plugin from Gradle?

As of ignition-maven-plugin v1.0.8, there is also the post goal. The post goal takes the modl goal one step further and acts as helper goal to "post" your packaged modl file to your running developer gateway. Note: You'll need to specify a <gatewayAddress> in the plugin configurations if you are not using the default (localhost:8088).:

If I had to guess I am sure that its just an http POST of the modl file to a web endpoint, but I can't seem to find that endpoint in any documentation.

I don’t think the Gradle plugin has an equivalent, we don’t use that functionality.

You can see the URL built here: ignition-maven-plugin/PostModuleMojo.java at 71f4d87649edf7f97e0e16fa373a41b1987680df · inductiveautomation/ignition-maven-plugin · GitHub

Ah, I was wrong, it does have an equivalent. See the Tasks section for deployModl: ignition-module-tools/gradle-module-plugin at master · inductiveautomation/ignition-module-tools · GitHub

Woohoo! I was about to go out of my way to create a pull request for this. Thanks Kevin

In the same vein as this, trying to use the module generator to setup everything so that I don't have to figure out how to add that task to my gradle wrapper.

I noticed that in order to download the Module Generator CLI it says:

Download the latest release for your platform from the releases tab, and simply run it. Follow the prompts to customize the module's initial setup.

However when I go to the releases tab I see nothing, any ideas on where to download the CLI?

EDIT: My guess based off this issue I just found that this was never done :slightly_frowning_face: So separate question, how does one build the generator?

Gotta ask @PerryAJ about any of the new tooling.

1 Like

In parallel to this (maybe @PerryAJ will know this as well) it looks like the current Gradle plugin does not support deployModl as mentioned above.

When listing out the tasks it supports a post task, but it posts it to system/DeveloperModuleServlet instead of main/system/DeveloperModuleServlet and fails. Upon trying to change/build/use a copy of the plugin from Github it looks like it’s potentially a completely different plugin than the one currently on the nexus repo (v0.1.0 vs v1.2.0-SNAPSHOT on nexus)

I am curious if there is a public repo location for the version 1.2.0-SNAPSHOT that is currently published, that I could create a request to change the servlet endpoint to.

The /main/ prefix went out the window with v7.9. If you are trying to post to a v7.9 gateway, you’ll need to maintain a local patch.

Interesting. When we try to post to a dev gateway with the existing one we get a java io file exception that a file does not exist at http://localhost/system/DeveloperModuleServlet. We did change the gatewayPort to 80 (what it is on our system). Any ideas?

Huh. Nope.

It’s mounted as DeveloperModuleLoadingServlet, not DeveloperModuleServlet.

If the gradle version of the plugin is posting to the latter then it’s probably just a bug.

I just was typing it off memory, it is doing DeveloperModuleLoadingServlet, my bad

You have -Dia.developer.moduleupload=true in your ignition.conf, right? and it’s not an Edge gateway?

This thread just came to my attention. Getting caught up a bit, but some quick clarifications:

The plugin you are using with the 1.2.0-SNAPSHOT version is the old (and not-open sourced) plugin - it's not available as open source, unfortunately. That plugin is something we host on nexus only to avoid breaking builds that people have established with it, but that plugin is EoL (internally it is using APIs that have since been deprecated and will go away in gradle v8).

I'd highly suggest migrating to the rewritten open source version found in the ignition-module-tools repo. That one is a full rewrite that was done using modern Gradle apis, and published to Gradle's central plugin repo (so you don't need any special repository configurations for it to resolve). We use it ourselves. We'll be continuing to develop/maintain that one as necessary, so feel free to open issues/PRs on github for that.

May have been a mistake to not go with v2.0 for the new one, but the two plugins have totally different plugin IDs and have effectively 0 in common aside from high-level behavior and similar configuration models (should be a few minutes to migrate old config to the new one though). See the Plugin Page for plugin ID information.

Last I tried, I was able to succeed with deployModl (and apparently didn't remove a //TODO comment when I finished the implementation), but it's not a normal part of our workflow so I haven't tried it for a couple months. I'm going to fire up 8.1.18 locally and see if I hit any issues trying to use the deployModl task, and will clarify what configuration was required (assuming it works).

Re the generator: it should still be functional if you run it locally, either via gradlew runCli in the generator project, or by building the binary for your local system via gradlew :generator-cli:nativeImage from that same directory. The generator is definitely ripe for some updates and release automation. I'm hoping to spend some time on that prior to ICC, but can't promise anything.

4 Likes

Just tested the current version of the open source plugin against Ignition 8.1.18 release and deployModl worked. Tested against Ignition standard edition on a Mac. There were two conditions required:

  1. add the additional java param to ignition conf: wrapper.java.additional.2=-Dia.developer.moduleupload=true
  2. First time you install the module, do it via the gateway UI and accept any license terms/certificate

After that, seems that running gradlew deployModl posts to the developer servlet as intended.

Admittedly, I tested using a very simple gateway scoped module, but it was loaded into the gateway as I’d expect.

All awesome info!

It looks like it’s trying to force signing the module and erroring out with no certs found, though I am never running the signModule task. Any idea why this is happening?

I just compiled the generator cli, and then used it to create a new module. I then added the missing section in pluginManagement listed on this forum post. Gradle plugin is missing module signer - #3 by Thomas_Mulcahy

Then In the new module folder, I ran the build and this is what happened:

 kgamble-mbp ➜ ./gradlew build
Starting a Gradle Daemon, 1 busy and 1 incompatible and 1 stopped Daemons could not be reused, use --status for details
Required keystore file location not found.  Specify via flag '--keystoreFile=<value>', or in gradle.properties file as 'ignition.signing.keystoreFile=<value>'
Required keystore file location not found.  Specify via flag '--keystoreFile=<value>', or in gradle.properties file as 'ignition.signing.keystoreFile=<value>'
Required certificate file location not found.  Specify via flag '--certFile=<value>', or in gradle.properties file as 'ignition.signing.certFile=<value>'
Required certificate file location not found.  Specify via flag '--certFile=<value>', or in gradle.properties file as 'ignition.signing.certFile=<value>'

> Task :signModule FAILED
Required certificate file location not found.  Specify via flag '--certFile=<value>', or in gradle.properties file as 'ignition.signing.certFile=<value>'
Required keystore file location not found.  Specify via flag '--keystoreFile=<value>', or in gradle.properties file as 'ignition.signing.keystoreFile=<value>'
Required certificate alias not found.  Specify via flag '--certAlias=<value>', or in gradle.properties file as 'ignition.signing.certAlias=<value>'
Required certificate file location not found.  Specify via flag '--certFile=<value>', or in gradle.properties file as 'ignition.signing.certFile=<value>'
Required certificate password not found.  Specify via flag '--certPassword=<value>', or in gradle.properties file as 'ignition.signing.certPassword=<value>'
Required keystore file location not found.  Specify via flag '--keystoreFile=<value>', or in gradle.properties file as 'ignition.signing.keystoreFile=<value>'
Required keystore password not found.  Specify via flag '--keystorePassword=<value>', or in gradle.properties file as 'ignition.signing.keystorePassword=<value>'

FAILURE: Build failed with an exception.

* What went wrong:
Some problems were found with the configuration of task ':signModule' (type 'SignModule').
> File '/Users/kgamble/Work/Ignition/Modules/test-module/test/null' specified for property 'certFile' does not exist.
> File '/Users/kgamble/Work/Ignition/Modules/test-module/test/null' specified for property 'keystore' does not exist.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.8.2/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 59s
16 actionable tasks: 16 executed

It looks like if I just execute the zipModule task directly it works. However even if I do provide it valid certificates for signing I end up with the following

gradle.properties

ignition.signing.keystoreFile=certs/keystore.jks
ignition.signing.keystorePassword=MyKeystorePassword
ignition.signing.certFile=certs/MyCertFile.crt
ignition.signing.certAlias="My Cert Alias"
ignition.signing.certPassword=MyCertPassword

build Output

 kgamble-mbp ➜ ./gradlew build

> Task :signModule FAILED
Required certificate password not found.  Specify via flag '--certPassword=<value>', or in gradle.properties file as 'ignition.signing.certPassword=<value>'

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':signModule'.
> null cannot be cast to non-null type java.security.interfaces.RSAPrivateKey

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.8.2/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 1s
16 actionable tasks: 1 executed, 15 up-to-date

zipModule Output

 kgamble-mbp ➜ ./gradlew zipModule

BUILD SUCCESSFUL in 1s
15 actionable tasks: 15 up-to-date

This however does not solve the problem of why the build automatically forces a signing. I am trying to dig around and find the answer to that in the plugin, but I am no gradle expert.

Github issue created to change this:

Once I can get the new plugin working I will probably create a PR to replace this with the new one!

This is just a bit of a naive design decision on my part to make signing a fundamental required step in the module assembly process. I figured one would always want a signed module as the end result, but can see how that might be inhibitive for people (especially if you're not familiar with the process of creating/getting a cert to sign with).

We're going to make that more flexible to ease adoption and make routine development/experimentation a bit simpler for folks. Not sure exactly when, but 'soonish' - it'll be part of the next released version of the plugin, and the changes are scheduled to get done in the next couple weeks.

1 Like

ignition.signing.keystoreFile=certs/keystore.jks
ignition.signing.keystorePassword=MyKeystorePassword
ignition.signing.certFile=certs/MyCertFile.crt
ignition.signing.certAlias="My Cert Alias"
ignition.signing.certPassword=MyCertPassword

I'd try using fully qualified paths (I personally drop certs in a user home directory). Also think that ignition.signing.certAlias="My Cert Alias" probably shouldn't have quotes. I'd also suggest adding --info or --debug to the gradle execution to get more logging output during cert file resolution.

1 Like