Tomcat startup.sh script works from shell but not with ansible

Hi!

I wrote a simple playbook that downloads, extracts and starts Tomcat. Here are the relevant parts of it:

  • name: Download Tomcat 7.0.42
    get_url: url=http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.42/bin/apache-tomcat-7.0.42.tar.gz dest=/home/tomcat/apache-tomcat-7.0.42.tar.gz

  • name: Extract Tomcat
    command: chdir=/home/tomcat tar -xvzf apache-tomcat-7.0.42.tar.gz creates=/home/tomcat/apache-tomcat-7.0.42

  • name: Change ownership of Tomcat installation
    file: path=/home/tomcat/apache-tomcat-7.0.42 owner=tomcat group=tomcat state=directory recurse=yes

  • name: Configure Tomcat server
    template: src=tomcat-users.xml dest=/home/tomcat/apache-tomcat-7.0.42/conf/
    notify: restart tomcat

  • name: Set JAVA_HOME for tomcat
    lineinfile: dest=/home/tomcat/apache-tomcat-7.0.42/bin/setenv.sh line=‘export JAVA_HOME=/opt/java/jdk1.7.0_51’ create=yes state=present mode=0555

  • name: Start Tomcat
    command: /home/tomcat/apache-tomcat-7.0.42/bin/startup.sh
    sudo: true
    sudo_user: tomcat

  • name: wait for tomcat to start
    wait_for: port=8080

The wait step always times out because Tomcat doesn’t start. The strange thing is that when I execute the startup.sh script on the vm’s shell it works. And Ansible doesn’t complain it says that the step was executed successfully. Here’s the output with ‘vvvv’:

TASK: [tomcat | Start Tomcat] *************************************************

<127.0.0.1> ESTABLISH CONNECTION FOR USER: vagrant

<127.0.0.1> EXEC [‘ssh’, ‘-tt’, ‘-vvv’, ‘-o’, ‘ControlMaster=auto’, ‘-o’, ‘ControlPersist=60s’, ‘-o’, ‘ControlPath=/Users/asahli/.ansible/cp/ansible-ssh-%h-%p-%r’, ‘-o’, ‘Port=2222’, ‘-o’, ‘IdentityFile=/Users/asahli/.vagrant.d/insecure_private_key’, ‘-o’, ‘KbdInteractiveAuthentication=no’, ‘-o’, ‘PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey’, ‘-o’, ‘PasswordAuthentication=no’, ‘-o’, ‘User=vagrant’, ‘-o’, ‘ConnectTimeout=10’, ‘127.0.0.1’, “/bin/sh -c ‘mkdir -p /tmp/ansible-1391975068.22-50068957235035 && chmod a+rx /tmp/ansible-1391975068.22-50068957235035 && echo /tmp/ansible-1391975068.22-50068957235035’”]

<127.0.0.1> REMOTE_MODULE command /home/tomcat/apache-tomcat-7.0.42/bin/startup.sh

<127.0.0.1> PUT /var/folders/vj/fw7zgzj93j371115rb1mtvv00000gn/T/tmpcOMgD0 TO /tmp/ansible-1391975068.22-50068957235035/command

<127.0.0.1> EXEC [‘ssh’, ‘-tt’, ‘-vvv’, ‘-o’, ‘ControlMaster=auto’, ‘-o’, ‘ControlPersist=60s’, ‘-o’, ‘ControlPath=/Users/asahli/.ansible/cp/ansible-ssh-%h-%p-%r’, ‘-o’, ‘Port=2222’, ‘-o’, ‘IdentityFile=/Users/asahli/.vagrant.d/insecure_private_key’, ‘-o’, ‘KbdInteractiveAuthentication=no’, ‘-o’, ‘PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey’, ‘-o’, ‘PasswordAuthentication=no’, ‘-o’, ‘User=vagrant’, ‘-o’, ‘ConnectTimeout=10’, ‘127.0.0.1’, “/bin/sh -c ‘chmod a+r /tmp/ansible-1391975068.22-50068957235035/command’”]

<127.0.0.1> EXEC [‘ssh’, ‘-tt’, ‘-vvv’, ‘-o’, ‘ControlMaster=auto’, ‘-o’, ‘ControlPersist=60s’, ‘-o’, ‘ControlPath=/Users/asahli/.ansible/cp/ansible-ssh-%h-%p-%r’, ‘-o’, ‘Port=2222’, ‘-o’, ‘IdentityFile=/Users/asahli/.vagrant.d/insecure_private_key’, ‘-o’, ‘KbdInteractiveAuthentication=no’, ‘-o’, ‘PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey’, ‘-o’, ‘PasswordAuthentication=no’, ‘-o’, ‘User=vagrant’, ‘-o’, ‘ConnectTimeout=10’, ‘127.0.0.1’, ‘/bin/sh -c 'sudo -k && sudo -H -S -p “[sudo via ansible, key=pqvlljvxxezlskhjkospaalznznwlzdy] password: " -u tomcat /bin/sh -c '”'“'echo SUDO-SUCCESS-pqvlljvxxezlskhjkospaalznznwlzdy; /usr/bin/python /tmp/ansible-1391975068.22-50068957235035/command'”'"''’]

<127.0.0.1> EXEC [‘ssh’, ‘-tt’, ‘-vvv’, ‘-o’, ‘ControlMaster=auto’, ‘-o’, ‘ControlPersist=60s’, ‘-o’, ‘ControlPath=/Users/asahli/.ansible/cp/ansible-ssh-%h-%p-%r’, ‘-o’, ‘Port=2222’, ‘-o’, ‘IdentityFile=/Users/asahli/.vagrant.d/insecure_private_key’, ‘-o’, ‘KbdInteractiveAuthentication=no’, ‘-o’, ‘PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey’, ‘-o’, ‘PasswordAuthentication=no’, ‘-o’, ‘User=vagrant’, ‘-o’, ‘ConnectTimeout=10’, ‘127.0.0.1’, “/bin/sh -c ‘rm -rf /tmp/ansible-1391975068.22-50068957235035/ >/dev/null 2>&1’”]

changed: [tp-web-proxy] => {“changed”: true, “cmd”: [“/home/tomcat/apache-tomcat-7.0.42/bin/startup.sh”], “delta”: “0:00:00.006908”, “end”: “2014-02-09 19:44:28.235406”, “item”: “”, “rc”: 0, “start”: “2014-02-09 19:44:28.228498”, “stderr”: “”, “stdout”: “Using CATALINA_BASE: /home/tomcat/apache-tomcat-7.0.42\nUsing CATALINA_HOME: /home/tomcat/apache-tomcat-7.0.42\nUsing CATALINA_TMPDIR: /home/tomcat/apache-tomcat-7.0.42/temp\nUsing JRE_HOME: /opt/java/jdk1.7.0_51\nUsing CLASSPATH: /home/tomcat/apache-tomcat-7.0.42/bin/bootstrap.jar:/home/tomcat/apache-tomcat-7.0.42/bin/tomcat-juli.jar”}

On IRC somebody gave me that hint: “something that tomcat wants (from your shell env) seems like it’s missing from running the command without a terminal started”. But I can’t find out what’s missing.

Does somebody know this problem?

Thanks for your help!

I can’t say off the top of my head what the problem is but here’s a way to troubleshoot it:

Add to setenv.sh: “env > /home/tomcat/env.out.$(date +%H%M%S)”

Then run the ansible playbook, and start tomcat from the shell, and you’ll have two env.out.* files in /home/tomcat. Compare them with diff (you might need to sort them first? I don’t know how predictable the order of env’s output is) or by sight. That should point you to what’s missing (most likely something in PATH or LD_LIBRARY_PATH).

-dave

I did it but it didn’t help me much. The following environment variables are different:

ansible: USERNAME=tomcat
shell: USERNAME=root

ansible: LANG=C
shell: LANG=en_US

ansible:
shell: LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:.tar=01;31:.tgz=01;31:.arj=01;31:.taz=01;31:.lzh=01;31:.lzma=01;31:.tlz=01;31:.txz=01;31:.zip=01;31:.z=01;31:.Z=01;31:.dz=01;31:.gz=01;31:.lz=01;31:.xz=01;31:.bz2=01;31:.bz=01;31:.tbz=01;31:.tbz2=01;31:.tz=01;31:.deb=01;31:.rpm=01;31:.jar=01;31:.war=01;31:.ear=01;31:.sar=01;31:.rar=01;31:.ace=01;31:.zoo=01;31:.cpio=01;31:.7z=01;31:.rz=01;31:.jpg=01;35:.jpeg=01;35:.gif=01;35:.bmp=01;35:.pbm=01;35:.pgm=01;35:.ppm=01;35:.tga=01;35:.xbm=01;35:.xpm=01;35:.tif=01;35:.tiff=01;35:.png=01;35:.svg=01;35:.svgz=01;35:.mng=01;35:.pcx=01;35:.mov=01;35:.mpg=01;35:.mpeg=01;35:.m2v=01;35:.mkv=01;35:.webm=01;35:.ogm=01;35:.mp4=01;35:.m4v=01;35:.mp4v=01;35:.vob=01;35:.qt=01;35:.nuv=01;35:.wmv=01;35:.asf=01;35:.rm=01;35:.rmvb=01;35:.flc=01;35:.avi=01;35:.fli=01;35:.flv=01;35:.gl=01;35:.dl=01;35:.xcf=01;35:.xwd=01;35:.yuv=01;35:.cgm=01;35:.emf=01;35:.axv=01;35:.anx=01;35:.ogv=01;35:.ogx=01;35:.aac=00;36:.au=00;36:.flac=00;36:.mid=00;36:.midi=00;36:.mka=00;36:.mp3=00;36:.mpc=00;36:.ogg=00;36:.ra=00;36:.wav=00;36:.axa=00;36:.oga=00;36:.spx=00;36:.xspf=00;36:

ansible: SUDO_COMMAND=/bin/sh -c echo SUDO-SUCCESS-ztvhjxfxdqkjmmjigsawnrwhamjttxvl; /usr/bin/python /tmp/ansible-1392065810.04-265771362994182/command

shell: SUDO_COMMAND=/bin/su -c /home/tomcat/apache-tomcat-7.0.42/bin/startup.sh tomcat

ansible: SHELL=/bin/sh
shell: SHELL=/bin/bash

ansible:
shell: LC_CTYPE=UTF-8

After that I tried to change the SHELL to /bin/bash for ansible but it didn’t help.

Any other hint? I’m really blocked by this problem :frowning:

I just remembered that I had so many problems with tomcat 7 start/stop that I ended up writing my own init script (will need to look for it). This was sans ansible, I was using puppet at the time.

We modified the tomcat script so it killed the process group, that resolved some of the issues as I recall.

The other thing is that you may want to have unpackWAR set to false on the context, otherwise when you update the war file tomcat will continue to use the previously unpacked war vs. the new one by default.

Hi

This is a good point. Tomcat does NOT detach, so running startup.sh directly from an Ansible ssh session may well immediately shut down. You’ve got to wrap it in something that will detach correctly. The easiest would be nohup. startup.sh is also kind of pointless. You can just call catalina.sh directly. From my Tomcat app’s init script:

nohup $CATALINA_HOME/bin/catalina.sh start

-dave

I have created a couple of tomcat init scripts that actually ‘work’ to avoid these issues.

Let me look and see if i can publish one for general usage.

Thank you very much! Your solution works.

This came up for me in the past. I found setsid pretty helpful too

https://github.com/ansible/ansible/pull/4800

(note that #4800 never amounted to much as it caused too many other problems, but the workaround still applies!)

Will

I finally solved it by using the script from the ansible examples: https://github.com/ansible/ansible-examples/blob/master/tomcat-standalone/roles/tomcat/files/tomcat-initscript.sh

Hi Will,

I’m confused a bit about what you are referring to in the ticket.

As I recall we got the async math bugfix completed in the end. Is there a chance you linked a different ticket by mistake possibly?

I meant the workaround details at the bottom of the issue description

You’re right though, it was #4807 that never amounted to much. Mainly because I couldn’t get the fix right and wasn’t motivated enough to need to get the fix right!

Will

iam also struck in tomcat8 to run .sh script can you share your playbook.

In which file i have to add this line.(nohup $CATALINA_HOME/bin/catalina.sh start)

Folks, please don't use nohup.

Any linux will have systemd or upstart which makes it easy to run
foreground tasks as services if you write a small file to tell it what
to do.

Hi,

Below rule working fine for me .

  • name: start tomcat7 service
    command: “nohup /usr/local/apache-tomcat-7.0.54/bin/startup.sh”
    tags: starttom
  • name: stop tomcat7 service
    command: “nohup /usr/local/apache-tomcat-7.0.54/bin/shutdown.sh”
    tags: stoptom

#ansible-playbook main.yml -i hosts --tags starttom

Thanks:
Dinesh Kumar

thanks its working

Below worked for me to . Thanks a ton .