Strategy to keep Tomcat updated?

Viewed 783

I maintain a number of RedHat Enterprise Linux (both 7 and 8) servers (>100) with different applications. To keep my sanity, I'm of course using tools such as Ansible, and more to the point of this questions, locally mirrored copies of public RPM repositories (using Satellite Server for the purpose).

Updates are applied regularly from these repositories to keep the servers secure.

A few of these servers need Apache Tomcat installed. This is one of the few applications that is, to my knowledge, not available from any RPM-based repository; it must be installed manually from a tarball. Updates are also manual (aided by an Ansible role, but I still have to be aware of the new version and manually change it).

Are there any strategies to keep Tomcat up-to-date with little or no constant attention?

Update:

I found half of a solution to my problem. By default, Tomcat keeps the installation and the instance configuration mixed together in a single directory tree identified by CATALINA_HOME. That makes updating Tomcat without clobbering your configuration complicated.

To solve that, you can put the instance-specific files in a separate directory tree identified with the CATALINA_BASE variable. Upgrading Tomcat then becomes as easy as:

  • Download the new tarball.
  • Untar it to a new location
  • Review the readme and changelog for any breaking changes.
  • Update the CATALINA_HOME variable to point to the new location, while keeping the CATALINA_BASE variable unchanged.
  • Restart Tomcat, using the scripts in the new CATALINA_HOME bin directory.

I am not providing code here because where and how you set CATALINA_HOME and CATALINA_BASE will vary. I set both variables in the service unit file that also starts Tomcat.

Still open: finding a way to automatically find out when a new release of Tomcat is published.

2 Answers

After a lot of digging, I found the answers I needed. There are fundamentally two parts to my question:

  • How to update Tomcat without breaking existing site configurations.
  • How to find the current Tomcat version automatically.

How to update Tomcat without breaking existing site configurations

The answer lies in using the CATALINA_HOME directory only for the actual Tomcat binary, and put the configuration into a separate directory specified with CATALINA_BASE.

The CATALINA_HOME directory should simply contain the content of the Tomcat tarball without modifications. You may delete certain files according to the Tomcat documentation, and you may want to add certain shared files, such as the tomcat-native libraries.

The CATALINA_BASE directory will contain the /conf, /webapp, /logs and a few other directories.

Before starting Tomcat, set and export both environment variables.

As an example, this is the systemd service unit template I use. I put it into /etc/system/systems/tomcat@.service

[Unit]
Description=Apache Tomcat Web Application Container for %I
After=syslog.target network.target

[Service]
Type=forking
Environment="CATALINA_HOME={{ usd_tomcat_catalina_home }}" "CATALINA_BASE={{ usd_tomcat_catalina_base }}/%i"
ExecStart=/bin/bash {{ usd_tomcat_catalina_home }}/bin/catalina.sh start
ExecStop=/bin/bash {{ usd_tomcat_catalina_home }}/bin/catalina.sh stop
SuccessExitStatus=126 143
User=tomcat
Group=tomcat

[Install]
WantedBy=multi-user.target

The detailed instructions for using CATALINA_BASE are on the Tomcat documentation site.

https://tomcat.apache.org/tomcat-9.0-doc/introduction.html

How to find the current Tomcat version automatically

The second problem is how to find the correct version of the Tomcat tarball to download. The Apache foundation will delete the tarball for one minor release when the next minor release is published.

Therefore, the following broke with a 404 error as soon as 9.0.45 was published.

wget https://mirrors.sonic.net/apache/tomcat/tomcat-9/v9.0.44/bin/apache-tomcat-9.0.44.tar.gz

This has been answered before on Stackoverflow here: How to get always latest link to download tomcat server using shell

TOMCAT_VER=`curl --silent http://mirror.sonic.net/apache/tomcat/tomcat-9/ | grep v9 | awk '{split($5,c,">v") ; split(c[2],d,"/") ; print d[1]}'`
wget https://mirrors.sonic.net/apache/tomcat/tomcat-9/v$TOMCAT_VER/bin/apache-tomcat-${TOMCAT_VER}.tar.gz

I found that the awk solution is somewhat brittle as the field numbers may move around. Doing the same thing with sed:

curl --silent http://mirror.sonic.net/apache/tomcat/tomcat-9/ | grep v9 | sed 's/.*v\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/'

The regular expression is looking for a sequence of v + digits + . + digits + . + digits. It then throws away everything except the digits and periods.

[rohtash@172 blockinfile]$ cat cron.yml 
- hosts: remote1
  gather_facts: no 
  tasks:
  - name: create file in a min
    cron:
       name: "task"
       minute: "*/1"
       job: "/usr/bin/sh -c 'ansible-playbook update_pkgs.yml'"

on remote server you can check

[root@scp ~]# crontab -l
#Ansible: task
*/1 * * * * /usr/bin/sh -c 'ansible-playbook update_pkgs.yml'

what cron module does, it will run this playbook every minute. Inside this playbook you can use when module like this

- include_tasks: yum_install.yml
  when: version != {{ what_you_earlier_saved }}

You can increase or decrease your cron job running timing minutes,day,hour,week whatever.

what_you_earlier_saved this variable you have to create and save in file like this

- shell: rpm -qa|grep python3-pip-wheel > lastversion
- shell: cat lastversion
  register: what_you_earlier_saved

after package updatation, everytime your ansible playbook will update this last version file.

Related