voxpupuli / puppet-jira

Atlassian JIRA Puppet Module
https://forge.puppet.com/puppet/jira
Apache License 2.0
62 stars 143 forks source link

jira::java_opts defined as YAML multiline block string generates incorrect JAVA_OPTS string in setenv.sh #333

Closed wolfaba closed 3 years ago

wolfaba commented 3 years ago

Affected Puppet, Ruby, OS and module versions/distributions

How to reproduce (e.g Puppet code you use)

Define jira::java_opts as multiline string in YAML (Hiera) as described in Hiera examples in README.md, e.g.

jira::java_opts: >
  -Datlassian.mail.senddisabled=true
  -Datlassian.mail.fetchdisabled=true
  -Datlassian.mail.popdisabled=true

And install Jira version newer that 8.9.1.

What are you seeing

This Hiera code will be used in templates/setenv.sh.erb file:

JAVA_OPTS="<%= scope.lookupvar('jira::java_opts') %> $JAVA_OPTS"

which generates final shell code as

JAVA_OPTS="-Datlassian.mail.senddisabled=true -Datlassian.mail.fetchdisabled=true -Datlassian.mail.popdisabled=true'
 $JAVA_OPTS"

with this code, jira could not be started becase catalina.sh use this quoted shell variable JAVA_OPTS in eval:

eval $_NOHUP "\"$_RUNJAVA\"" "\"$CATALINA_LOGGING_CONFIG\"" $LOGGING_MANAGER "$JAVA_OPTS" "$CATALINA_OPTS" \
  -D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
  -classpath "\"$CLASSPATH\"" \
  -Dcatalina.base="\"$CATALINA_BASE\"" \
  -Dcatalina.home="\"$CATALINA_HOME\"" \
  -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
  org.apache.catalina.startup.Bootstrap "$@" start \
  >> "$CATALINA_OUT" 2>&1 "&"

There is error following error in log journal:

/opt/jira/atlassian-jira-software-8.13.0-standalone/bin/catalina.sh: line 572: -Djava.awt.headless=true: command not found

Atlassian has changed this eval code in newer versions, in older versions the $JAVA_OPTS variable was unquoted, in newer version the variable is quoted. You can see the quoting of JAVA_OPTS in different Jira versions below:

catalina.sh.7.13.18:    eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
catalina.sh.8.0.3:    eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
catalina.sh.8.1.3:    eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
catalina.sh.8.2.6:    eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
catalina.sh.8.3.5:    eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
catalina.sh.8.4.3:    eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
catalina.sh.8.5.9:    eval $_NOHUP "\"$_RUNJAVA\"" "\"$CATALINA_LOGGING_CONFIG\"" $LOGGING_MANAGER "$JAVA_OPTS" "$CATALINA_OPTS" \
catalina.sh.8.6.1:    eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
catalina.sh.8.7.1:    eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
catalina.sh.8.8.1:    eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
catalina.sh.8.9.1:    eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER "$JAVA_OPTS" "$CATALINA_OPTS" \
catalina.sh.8.10.1:    eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER "$JAVA_OPTS" "$CATALINA_OPTS" \
catalina.sh.8.11.1:    eval $_NOHUP "\"$_RUNJAVA\"" "\"$CATALINA_LOGGING_CONFIG\"" $LOGGING_MANAGER "$JAVA_OPTS" "$CATALINA_OPTS" \
catalina.sh.8.12.3:    eval $_NOHUP "\"$_RUNJAVA\"" "\"$CATALINA_LOGGING_CONFIG\"" $LOGGING_MANAGER "$JAVA_OPTS" "$CATALINA_OPTS" \

If the eval is run with unquoted JAVA_OPTS, then the catalina.sh starts java as one command:

Oct 29 17:36:31 xxxxxxxxxxxxxxxx start-jira.sh[100232]: + eval '"/usr/lib/jvm/java-8-openjdk-amd64/bin/java"' '"-Djava.util.logging.config.file=/opt/jira/atlassian-jira-software-8.13.0-standalone/conf/logging.properties"' -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Xms512m -Xmx2048m -Datlassian.mail.senddisabled=true -Datlassian.mail.fetchdisabled=true -Datlassian.mail.popdisabled=true -Djava.awt.headless=true -Datlassian.standalone=JIRA -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true -Dmail.mime.decodeparameters=true -XX:-HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -Djira.home=/srv/jira-data -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 '-Xloggc:/opt/jira/atlassian-jira-software-8.13.0-standalone/logs/atlassian-jira-gc-%t.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintGCCause    ' '-Dignore.endorsed.dirs=""' -classpath '"/opt/jira/atlassian-jira-software-8.13.0-standalone/bin/bootstrap.jar:/opt/jira/atlassian-jira-software-8.13.0-standalone/bin/tomcat-juli.jar"' '-Dcatalina.base="/opt/jira/atlassian-jira-software-8.13.0-standalone"' '-Dcatalina.home="/opt/jira/atlassian-jira-software-8.13.0-standalone"' '-Djava.io.tmpdir="/opt/jira/atlassian-jira-software-8.13.0-standalone/temp"' org.apache.catalina.startup.Bootstrap start '&'

If there is quoted JAVA_OPTS in catalina.sh, then it will run two commands:

Oct 29 17:35:39 xxxxxxxxxxxxxxxx start-jira.sh[100118]: + eval '"/usr/lib/jvm/java-8-openjdk-amd64/bin/java"' '"-Djava.util.logging.config.file=/opt/jira/atlassian-jira-software-8.13.0-standalone/conf/logging.properties"' -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager '-Xms512m -Xmx2048m -Datlassian.mail.senddisabled=true -Datlassian.mail.fetchdisabled=true -Datlassian.mail.popdisabled=true

Oct 29 17:35:39 xxxxxxxxxxxxxxxx start-jira.sh[100118]:   -Djava.awt.headless=true -Datlassian.standalone=JIRA -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true -Dmail.mime.decodeparameters=true  -XX:-HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -Djira.home=/srv/jira-data -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027' '-Xloggc:/opt/jira/atlassian-jira-software-8.13.0-standalone/logs/atlassian-jira-gc-%t.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintGCCause    ' '-Dignore.endorsed.dirs=""' -classpath '"/opt/jira/atlassian-jira-software-8.13.0-standalone/bin/bootstrap.jar:/opt/jira/atlassian-jira-software-8.13.0-standalone/bin/tomcat-juli.jar"' '-Dcatalina.base="/opt/jira/atlassian-jira-software-8.13.0-standalone"' '-Dcatalina.home="/opt/jira/atlassian-jira-software-8.13.0-standalone"' '-Djava.io.tmpdir="/opt/jira/atlassian-jira-software-8.13.0-standalone/temp"' org.apache.catalina.startup.Bootstrap start '&'

Here you can see, there is first (incomplete) command with eval '"/usr/lib/jvm/java-8-openjdk-amd64/bin/java"' and the second command -Djava.awt.headless=true -Datlassian.standalone=JIRA -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true, which generates the error /opt/jira/atlassian-jira-software-8.13.0-standalone/bin/catalina.sh: line 572: -Djava.awt.headless=true: command not found

The eval shell command evaluates quoted newline as end of the command and the other text interprets as new command. Until Atlassian has started to quote JAVA_OPTS the code has worked flawless. Now, it does not work.

As workaround, the jira::java_opts must be defined as simple string in yaml hiera:

jira::java_opts: '-Datlassian.mail.senddisabled=true -Datlassian.mail.fetchdisabled=true -Datlassian.mail.popdisabled=true'

Then there will be no newline in JAVA_OPTS and eval works correctly even with quoted $JAVA_OPTS

What behaviour did you expect instead

I expect that jira::java_opts multiline block string definition is possible to enter java options and will not store newline character as last character in JAVA_OPTS variable.

Is it somehow possible in puppet to remove newline from jira::java_opts string defined as multiline block so the code JAVA_OPTS="<%= scope.lookupvar('jira::java_opts') %> $JAVA_OPTS" does not keep newline as a part of value of $JAVA_OPTS?

Thank you very much for the fix.

Regards

Robert Wolf

kenyon commented 3 years ago

Try the YAML syntax for stripping the final newline, note the minus sign after the greater-than sign:

jira::java_opts: >-
  -Datlassian.mail.senddisabled=true
  -Datlassian.mail.fetchdisabled=true
  -Datlassian.mail.popdisabled=true
wolfaba commented 3 years ago

Oh, I have not read the page with multiline string description https://yaml-multiline.info/ very sharp! It's really described there too. Thank you for your hint!