aosaginohi / ulyaoth

Ulyaoth
https://www.ulyaoth.net
18 stars 26 forks source link

tomcat init script does not support multi-instance setup #6

Closed antoineco closed 9 years ago

antoineco commented 9 years ago

RedHat packages include init scripts which support multi-instance tomcat setups. Unfortunately the Ulyaoth package do not support this. This allows having a single init script, and then symlinks to this one script for starting other instances.

Usually it's enough to set:

NAME="$(basename $0)"

and then

# Get instance specific config file
if [ -r "/etc/sysconfig/${NAME}" ]; then
    . /etc/sysconfig/${NAME}
fi

to load a different configuration per instance (assuming that configurations are stored inside /etc/sysconfig as they should be on RHEL)

Would that be an option to support this in your packages as well? It's probably as easy as using the official scripts from CentOS repos and playing a bit with paths. I'd be happy to help if that sounds good to you.

We were discussing about it in antoineco/aco-tomcat#23

joshuabaird commented 9 years ago

I'm taking a stab at this, but for some reason Tomcat isn't using the CATALINA_BASE and CATALINA_HOME variables that are provided by /etc/sysconfig/$NAME:

NAME="$(basename $0)"

# For SELinux we need to use 'runuser' not 'su'
if [ -x "/sbin/runuser" ]; then
    SU="/sbin/runuser -s /bin/sh"
else
    SU="/bin/su -s /bin/sh"
fi

# Get instance specific config file
if [ -r "/etc/sysconfig/${NAME}" ]; then
    echo "SOURCING /etc/sysconfig/${NAME}"
    . /etc/sysconfig/${NAME}
fi

tomcat_pid() {
    echo `ps aux | grep org.apache.catalina.startup.Bootstrap | grep -v grep | awk '{ print $2 }'`
}

start() {
    pid=$(tomcat_pid)
    if [ -n "$pid" ]
    then
        echo "Tomcat is already running (pid: $pid)"
    else
        # Start tomcat
        echo "Starting tomcat"
        $SU - $TOMCAT_USER -c "cd $CATALINA_HOME/bin && $CATALINA_HOME/bin/startup.sh"
    fi
    return 0
}

The result is:

root@aspdv-d1-ap01:/etc/init.d# service tomcat_default start
DEBUG: SOURCING /etc/sysconfig/tomcat_default
Starting tomcat
DEBUG: CATALINA_BASE: /srv/tomcat/default
DEBUG: CATALINA_HOME: /opt/tomcat
Using CATALINA_BASE:   /opt/tomcat
Using CATALINA_HOME:   /opt/tomcat
Using CATALINA_TMPDIR: /opt/tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /opt/tomcat/bin/bootstrap.jar

I thought it may be because I was sourcing /etc/sysconfig/$NAME before the SU, but this is also how the native RHEL init script handle this as far as I can tell.

My /etc/sysconfig/$NAME looks like this:

JAVA_HOME="/usr/lib/jvm/jre-1.7.0"
CATALINA_BASE="/srv/tomcat/default"
CATALINA_HOME="/opt/tomcat"
JASPER_HOME="/opt/tomcat"
CATALINA_TMPDIR="/srv/tomcat/default/temp"
CATALINA_PID="/var/run/tomcat_default.pid"
JAVA_OPTS="-server"
TOMCAT_USER="tomcat"
TOMCAT_GROUP="tomcat"
SECURITY_MANAGER="false"
SHUTDOWN_WAIT="30"
SHUTDOWN_VERBOSE="false"
aosaginohi commented 9 years ago

Any improvement is welcome to add to the packages I was actually looking into this also since i need it on my rhel7 machine. I can have a look this weekend if you guys not resolve it yet.

antoineco commented 9 years ago

Great, I'll send you a pull request sometime this week, unless you've fixed it in the meantime. Cheers @sbagmeijer!

@joshuabaird I'll answer there: antoineco/aco-tomcat#23

antoineco commented 9 years ago

So, from my first experiments I see 3 things missing:

  1. Set NAME="$(basename $0)" and then source /config/path/${NAME}
  2. Export $CATALINA_BASE before calling startup.sh
  3. Check process with Dcatalina.base=${CATALINA_BASE} instead of org.apache.catalina.startup.Bootstrap to get process status

-> Reference script

joshuabaird commented 9 years ago

Ok - so here is what we have came up with (thanks to @antoineco for the help!). It could probably use some improvements in logic around log messages displayed, but it seems to work.

https://gist.github.com/joshuabaird/560e59f5f63c748c7630

Things that were modified:

aosaginohi commented 9 years ago

Sorry I not had the time yet to go trough all this, I was busy renewing my website. I have more time this Saturday :+1:

aosaginohi commented 9 years ago

So been looking at this and technically I could just take the scripts from "Fedora" and "RHEL" to make this work and just change some locations.

But what do you think about perhaps placing this in a separate rpm? perhaps "tomcat8-multi", this way people that want a clean minimal tomcat do not have to add the additional files.

tomcat8-multi could just contain: /usr/libexec/tomcat/server /usr/libexec/tomcat/preamble /usr/libexec/tomcat/functions /usr/lib/systemd/system/tomcat@.service /etc/sysconfig/tomcat (and the init.d script)

Would that be an acceptable solution or do you feel it should all go into the main rpm directly?

antoineco commented 9 years ago

I think it would make things confusing, rhel scripts are relatively complex to understand and to debug, while the small additions suggested earlier in the conversations proved to work in a reliable manner.

I can push a PR in 4 hours, what do you think?

aosaginohi commented 9 years ago

problem with the above is that it is made for init.d, what about systemd? Going to use init.d on a systemd server is kind of going backwards.

antoineco commented 9 years ago

You're right. But I suppose we can use a tomcat@.service unit, set Environment=NAME=%i and call your script as ExecStart command without changing anything, right?

The only difference is that tomcat.sh would be in /usr/... instead of of /etc/init.d on systemd OS.

aosaginohi commented 9 years ago

Moved to new github repository: https://github.com/ulyaoth/repository/issues/29

aosaginohi commented 8 years ago

Creating multiple tomcat instances is now possible by simply installing: ulyaoth-tomcat-multi.

For more information see: https://www.ulyaoth.net/threads/how-to-configure-multiple-tomcat-instances.82312/#post-82567