Hi all,
I'd like to write a bash-based entity that has different shell.env per
command (e.g. for install and customize).
_*Proposal*_
The entity configuration could look like the following:
services:
- type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
brooklyn.config:
install:
shell.env:
ENV1: myval1
command: |
echo ${ENV1}
customize:
shell.env:
ENV2: myval2
command: |
echo ${ENV2}
shell.env:
ENV_SHARED: mySharedVal
In this example, ENV1 would only be set for install, and ENV2 would only
be set for "customize". The values in the top-level shell.env would be
available for all commands (unless explicitly overwritten by that
command) - i.e. they would be merged with the command's own shell.env map.
The use of "install.command: echo example" would be treated as
short-hand for:
install:
command: echo example
but with "install" taking precedence over "install.command". I suggest
that we deprecate the use of "install.command" etc, in favour of this
more general approach.
_*My use-case*_
My use-case is fiddly, and perhaps niche!
I'm setting up TLS. I need one command to generate a private key and a
CSR (certificate signing request), and then the next command to use that
value as a parameter of an effector call to a CA (certificate
authority). The effector is done using the brooklyn DSL, which will
populate the shell.env with the effector result (i.e. equivalent of ENV2
above).
If all these commands share the same shell.env, then it hangs (because
the second command's inputs are not available until the first command
has executed).
_*Other use-cases*_
Doing per-command shell.env make the intent much more explicit, and will
clean up the code for some entities.
For example, we currently avoid setting (some of) shell.env for install
commands, so as to avoid doing dependency resolution too early [1].
For launching Tomcat, we want to pass Java system properties (e.g. to
pass in the URL of a database). This is passed as a shell.env named
CATALINA_OPTS. However, it is also passed to customize, etc, so those
commands block prematurely (even though it is only launch that needs
this particular shell.env).
This change will be backwards compatible, so users are free to continue
using the top-level shell.env where appropriate.
_*Future direction*_
This will put us in a good place for further enhancements. For example:
* Some people have asked about indicating that freemarker templating
is being used (rather than it being a literal string). We could add
support for that by including another entry in the map for that command.
* When we support JSR-223 scripts, we could use that, rather than just
bash commands (e.g. by supplying "code: ..." rather than "command:
...").
* We could give a script file to be uploaded and executed (rather than
having to use "files.preinstall", etc).
Later, we could make a similar change for things like
"files.preinstall": instead of it just taking the source and destination
path, it could take additional metadata. For example, the permissions
for the uploaded file, the owner for the file, etc.
Aled
[1]
https://github.com/apache/brooklyn-server/blob/0.9.0/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java#L546
[2] https://github.com/apache/brooklyn-server/pull/153