Search code examples
gitmysqlbitbucketlaunchd

Git Push doesn't work when script runs through Launchd


I made a script to make a mysqldump, commit this dump to my local Git and then push this Git to my bitbucket account. The script runs fine when I run it through terminal (sh script.sh). I made a Plist file and added it so Launchd runs it.

Launchd runs it promptly every night at 3am as planned, and executes all commands well, except for pushing the local Git commit to bitbucket. What am I doing wrong?

As you can see from my script I tried to add lots of logging, but the logging I am getting is still not telling me why the push is not working, just that it is not working.

So my question is two-fold:

  1. How can I push my local Git to bitbucket in a script running through launchd?
  2. What can I add to my script (or somewhere else) so I can have logging from launchd or this script so I can diagnose what is going wrong?

My script:

#!/bin/sh

exec 1> /Library/WebServer/Documents/backup/fulllog

# echo start message
echo $(date) "- Backup Script Processing" >> /Library/WebServer/Documents/backup/log

# navigate to backup dir
if
    cd /Library/WebServer/Documents/backup/
then
    echo $(date) "- Successfully navigated to backup dir" >> /Library/WebServer/Documents/backup/log
else
    echo $(date) "- Could not locate backup directory" >>     /Library/WebServer/Documents/backup/log
    exit 0
fi

# echo message
echo $(date) "- Exporting SQL dump" >> /Library/WebServer/Documents/backup/log

if
    #dump the db into a .sql file
    /usr/local/mysql/bin/mysqldump --user=root --password=password --skip-extended-insert library > /Library/WebServer/Documents/backup/library.sql;
then
    #echo success message
    echo $(date) "- SQL dump successful" >> /Library/WebServer/Documents/backup/log
else
    #echo error message
    echo $(date) "- Mysqldump error" >> /Library/WebServer/Documents/backup/log
    exit 0
fi

#add just created mysqldump to git
if
    /usr/local/git/bin/git add library.sql
then
    echo $(date) "- Backup successfully added to local Git staging" >> /Library/WebServer/Documents/backup/log
else
    echo $(date) "- Error adding backup to local Git staging" >> /Library/WebServer/Documents/backup/log
    exit 0
fi

if
    /usr/local/git/bin/git add log
then
    echo $(date) "- Log successfully added to local Git staging" >> /Library/WebServer/Documents/backup/log
else
    echo $(date) "- Error adding log to local Git staging" >> /Library/WebServer/Documents/backup/log
    exit 0
fi

if
    /usr/local/git/bin/git commit -m 'Nightly SQL dump'
then
    echo $(date) "- Backup successfully committed to local Git" >> /Library/WebServer/Documents/backup/log
else
    echo $(date) "- Error committing backup to local Git" >> /Library/WebServer/Documents/backup/log
    exit 0
fi

if
    /usr/local/git/bin/git push origin master
then
    echo $(date) "- Backup Git Commit successfully pushed to origin master" >> /Library/WebServer/Documents/backup/log
else
    echo $(date) "- Backup Git Commit not pushed to origin master" >> /Library/WebServer/Documents/backup/log
fi

Edited to add: Thank you for your answer. I have added the environment variable GIT_TRACE=1.

You are right that there was no authentication towards Bitbucket in the scripts, I was pushing over https using my username/pw combo in my Keychain.

I have set up SSH using the Bitbucket instructions. I have made an ssh.sh script that looks like this (and chmod +x'd it):

#!/bin/sh
exec ssh -i "Users/sara/.ssh" "$@"

I have added this script as an variable using export GIT_SSH = /Library/WebServer/Documents/scripts/ssh.sh.

When I tested this set up to push to Bitbucket (using terminal) it works, but with an error that my SSH directory or file does not exist. I am assuming it only works now because the ssh-agent was already running, and that it will fail because of the 'does not exist' error when running through launchd. I have tried referring to the location with "~/.ssh", and including the file name, all options give the same error.

What do I do next? How can I refer to my key location so it will be found?

Solution: In the end I didn't use the environment variables.

The solution to get it working for me was to enable SSH (I was using HTTPS before). In the end I added

Host bitbucket.org
StrictHostKeyChecking no
IdentityFile /Users/sara/.ssh/id_rsa

To my ~/.ssh/config file, because it kept asking me for my passphrase. I didn't want to remove my passphrase entirely, but this enabled the script to work. After clearing up a double entry in Launchd (my plist was in both the System and User folders) it finally ran correctly last night.


Solution

  • You can set the environment variable GIT_TRACE=1 to make git show what commands it's executing and where it goes wrong.

    That said, there's no authentication in this script, so I'm going to go ahead and guess that's the problem. Most likely when you run the script from your shell you have your ssh-agent running which contains your key. When running through launchd, the agent is not setup, and the key is not in one of the default files (or is password protected).

    You can fix this by pointing the environment variable GIT_SSH to a shell script wrapper containing something like this:

    #!/bin/sh
    exec ssh -i "path/to/my/unencrypted/ssh/key" "$@"
    

    Don't forget to chmod +x it.