Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I version control my projects' cron jobs?

I have a bunch of projects that I push to a server with git and fab. They're a load of Django sites. Some of these sites have cron jobs.

I would like to be in a situation where I can:

  • Manage the site's cron jobs by editing a file locally and running a fab command (eg fab save deploy as I currently do)

  • Have new jobs get installed remotely (only) and replace any old jobs (I don't want clone jobs each time)

  • Keep the same highly customisable time settings. Not all my issues can be solved by @hourly.

What's the best way to approach this?


I am aware of How do you deploy cron jobs to production? but the focus there seems to be about hacking the cronning into the fabric script and (at least in the answers) there's no consideration that there might be more than one project that needs cron jobs per user.

I'm after something that is stored in the VCS (I don't push my fabfile to git - and it's shared between all my projects) that will work alongside other jobs in crontab. It's no good if ProjectA and ProjectB overwrite each other's jobs each time I deploy.

like image 634
Oli Avatar asked Sep 20 '12 09:09

Oli


People also ask

What is the use of * * * * * In cron?

It is a wildcard for every part of the cron schedule expression. So * * * * * means every minute of every hour of every day of every month and every day of the week . 0 1 * * * - this means the cron will run always at 1 o'clock. * 1 * * * - this means the cron will run each minute when the hour is 1.

What is the alternative for cron job?

Anacron. Anacron is a periodic command scheduler just like cron. The only difference is that it does not need your computer to be always running. You can schedule your task to run at any time.


2 Answers

I'm not a fan of editing the crontab or per-user cron jobs; anyone editing the crontab can mess up your deployment. Instead, I create scripts that go into /etc/cron.$interval which allows me to deploy them with Puppet (see the cron type) or a simple cp command.

So if I need a script that runs once per day, I either put that into $project/cron/cron.daily/$project if I install without Puppet.

Alternatively, if you really need to merge crontabs, you should add a header and footer to each script, so it's easy to see where some part of the crontab comes from. The header/footer also allows you do automatically add/remove each script.

You should never replace the whole crontab because one day, someone will manually edit it. The edit will work until you deploy again at which time it will suddenly fail silently.

like image 51
Aaron Digulla Avatar answered Sep 18 '22 12:09

Aaron Digulla


So here's my best idea so far:

  • All my projects live in /web/project_name/
  • Any project that needs cronjobs sticks them in /web/project_name/cron
  • On deploy, fab runs the following on the server:

    find /web/ -maxdepth 2 -name cron | xargs cat | crontab
    

This munges any cron files it finds in /web/ and stuffs them in the crontab for my user. Better yet, if I have project independent jobs I want running, I can stick them in /web/cron and they'll go at the top of the resulting crontab.

like image 31
Oli Avatar answered Sep 18 '22 12:09

Oli