3

So, I have a Java program that runs Ansible. I'd like to run this program as a service. I've written a service script in /etc/init.d that uses start-stop-daemon to run/stop the Java program. I've run into a problem where Ansible fails with this error:

GATHERING FACTS *************************************************************** 
fatal: [i-0f55b6a4] => Could not make dir /$HOME/.ansible/cp: [Errno 13] Permission denied: '/$HOME'

Ansible is trying to create a temporary work directory under /$HOME but for some reason, $HOME does not evaluate to /home/ubuntu (even though I used --user ubuntu --chuid ubuntu when starting the service), so it looks like Ansible tries to create a directory with the literal name /$HOME. And then it fails, because it lacks the permission to do this.

This is not a configurable option, so I did some digging and I think I found exactly where Ansible is trying to do this: https://github.com/ansible/ansible/blob/5ce3988d8693357f671f3fbec43b2d3b862db5f6/v1/ansible/runner/connection_plugins/ssh.py#L56

The python snippet, in case that link ever goes bad is:

def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs):
  ...
  fcntl.lockf(self.runner.process_lockfile, fcntl.LOCK_EX)
  self.cp_dir = utils.prepare_writeable_dir('$HOME/.ansible/cp',mode=0700)
  fcntl.lockf(self.runner.process_lockfile, fcntl.LOCK_UN)

I've tried a couple of things to resolve this, but so far nothing has worked.

Some of the things I've tried include:

Using /usr/bin/env to set HOME (since my version of start-stop-daemon does not appear to support --env):

CMD="/usr/bin/java"
CMD_ARGS=#...not really relevant here
case "$1" in
  start)
    start-stop-daemon --start -b -m --no-close --pidfile $PID_FILE --user ubuntu --chuid ubuntu --exec /usr/bin/env HOME=/home/ubuntu -- $CMD $CMD_ARGS >> $LOG_FILE 2>&1

Alas, this did not work.

I tried generating a wrapper script that will set the variable and then execute the main program:

case "$1" in
  start)
     sudo cat << PROCESS_RUNNER > /tmp/runMyProcess.sh
#! /bin/bash
HOME=/home/ubuntu
env
$CMD $CMD_ARGS >> $LOG_FILE 2>&1
PROCESS_RUNNER
     sudo chmod a+x /tmp/runMyProcess.sh
     start-stop-daemon --start -b -m --no-close --pidfile $PID_FILE --user ubuntu --chuid ubuntu --exec /tmp/runMyProcess.sh

The wrapper script looks like this:

#! /bin/bash
HOME=/home/ubuntu
env
/usr/bin/java -cp /home/ubuntu/arch3/pancancer.jar com.mypackage.MyClass --some --arguments  >> /var/log/myApplication/MyClass.log 2>&1

This also did not work.

When the Java program is called directly from the command line, everything works fine.

Ansible is being called from a Java program that is being called from start-stop-daemon that is being called from service. I'm not sure how I can propagate an environment variable named $HOME to ansible, and I'm kinda stumped right now.

  • 1
    I think you need to write export HOME=/home/ubuntu in the wrapper script. And what does env actually say? You might as well redirect it like env >/tmp/environ.log. – yaegashi Aug 8 '15 at 3:59
  • That snippet is building a command to run over SSH. It's using the value of HOME on the remote machine. You're setting HOME on the client but that's irrelevant. The error message is strange, are you sure you've found the right spot? That has $HOME, not /$HOME, and it seems to be coming from the Python script itself, not from a command executed over SSH (which would not include $HOME in the text, the variable would be expanded by the shell, possibly to an empty string if it was unset). How are you running Ansible? What does i-0f55b6a4 represent? – Gilles Aug 8 '15 at 8:00
  • @Gilles: i-0f55b6a4 is the remote machine name. No, I'm not completely certain I've found where the message was being generated from, though that seemed the most likely spot based on searching the ansible code on github. Ansible is being called from a Java program that is called from my service init script. I assumed that this error was not occurring on the remote machine because this behaviour only appeared when I started calling the Java program as a service - previously, having the Java program call the ansible playbook worked just fine. – FrustratedWithFormsDesigner Aug 10 '15 at 13:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.