From b690656e623994d4939f183de71eb18ea42945b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A8r=20Kessels?= Date: Sun, 18 Jan 2015 16:32:47 +0100 Subject: [PATCH 1/7] Add boilerplate for new cron cookbook. --- vendor/cookbooks/cron/CHANGELOG.md | 2 + vendor/cookbooks/cron/README.md | 51 +++++++++++++++++++++ vendor/cookbooks/cron/attributes/default.rb | 0 vendor/cookbooks/cron/metadata.rb | 7 +++ vendor/cookbooks/cron/recipes/default.rb | 23 ++++++++++ 5 files changed, 83 insertions(+) create mode 100644 vendor/cookbooks/cron/CHANGELOG.md create mode 100644 vendor/cookbooks/cron/README.md create mode 100644 vendor/cookbooks/cron/attributes/default.rb create mode 100644 vendor/cookbooks/cron/metadata.rb create mode 100644 vendor/cookbooks/cron/recipes/default.rb diff --git a/vendor/cookbooks/cron/CHANGELOG.md b/vendor/cookbooks/cron/CHANGELOG.md new file mode 100644 index 00000000..8c8605e9 --- /dev/null +++ b/vendor/cookbooks/cron/CHANGELOG.md @@ -0,0 +1,2 @@ +See https://github.com/intercity/chef-repo/blob/master/CHANGELOG.md for full +changelog diff --git a/vendor/cookbooks/cron/README.md b/vendor/cookbooks/cron/README.md new file mode 100644 index 00000000..1de9e0e5 --- /dev/null +++ b/vendor/cookbooks/cron/README.md @@ -0,0 +1,51 @@ +Cron Cookbook +================== + +Schedules tasks for apps. It simply adds entries to the root crontab +with commands that will be ran within the context of the app. + +Attributes +---------- + +#### sysadmins::default + + + + + + + + + + + + + +
KeyTypeDescriptionDefault
['cron']>Hashkey: identifierempty, won't schedule tasks.
+ +Usage +----- + +Add cron to your node configuration: + +```@json +{ +"cron": { + "sitemap": { + "minute": 0, + "hour": 5, + "command": "rake -s sitemap:refresh" + } +} +``` +This runs the command `..... bundle exec rake -s sitemap:refresh` every +day at 5:00. + +See the full list of available attributes at [the cron resource +documentation](http://docs.chef.io/resource_cron.html). + +All attributes will be passed literarally from the node configuration +into the cron resource. With a few exceptions: + +* Command will be prefixed with code so it runs within the app current dir. +* User defaults to the deploy\_user for the app ("deploy"). Be carefull when overriding. diff --git a/vendor/cookbooks/cron/attributes/default.rb b/vendor/cookbooks/cron/attributes/default.rb new file mode 100644 index 00000000..e69de29b diff --git a/vendor/cookbooks/cron/metadata.rb b/vendor/cookbooks/cron/metadata.rb new file mode 100644 index 00000000..8311aa9d --- /dev/null +++ b/vendor/cookbooks/cron/metadata.rb @@ -0,0 +1,7 @@ +name "cron" +maintainer "Bèr `berkes` Kessels" +maintainer_email "ber@berk.es" +license "MIT" +description "Schedules tasks for apps" +long_description IO.read(File.join(File.dirname(__FILE__), "README.md")) +version "0.0.1" diff --git a/vendor/cookbooks/cron/recipes/default.rb b/vendor/cookbooks/cron/recipes/default.rb new file mode 100644 index 00000000..1c6bc1ee --- /dev/null +++ b/vendor/cookbooks/cron/recipes/default.rb @@ -0,0 +1,23 @@ +# +# Cookbook Name:: cron +# Recipe:: default +# +# Copyright 2014, Bèr `berkes` Kessels +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. From 5534dfdf1efa536a9688dfa53b3cc81905b6cf7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A8r=20Kessels?= Date: Sun, 18 Jan 2015 18:07:00 +0100 Subject: [PATCH 2/7] Add recipe to create per-app crontab entries. * Defers attributes as set in node config. * Adds crontab to deploy user's crontab unless provided in the node * Prefixes command so it runs within app, using rbenv and bundle exec --- vendor/cookbooks/cron/recipes/default.rb | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/vendor/cookbooks/cron/recipes/default.rb b/vendor/cookbooks/cron/recipes/default.rb index 1c6bc1ee..c7fa4fb7 100644 --- a/vendor/cookbooks/cron/recipes/default.rb +++ b/vendor/cookbooks/cron/recipes/default.rb @@ -21,3 +21,24 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. + +return unless node[:active_applications] + +node[:active_applications].map do |app, app_info| + app_info["cron"].each do |id, crontab| + attributes = crontab.dup + + unscoped_command = attributes.delete("command") + rails_env = app_info['rails_env'] || "production" + user = attributes.delete("user") || app_info['deploy_user'] || "deploy" + app_dir = "#{node[:rails][:applications_root]}/#{app}/current" + + command = "cd #{app_dir} && ( PATH=/opt/rbenv/shims:$PATH RAILS_ENV=#{rails_env} bundle exec #{unscoped_command} )" + + cron "#{app}_#{id}" do + command(command) + user(user) + attributes.each {|attribute, value| send(attribute, value) } + end + end +end From 57edd533276f5c181e41b579d18f01b126b0cb39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A8r=20Kessels?= Date: Sun, 18 Jan 2015 18:08:56 +0100 Subject: [PATCH 3/7] Add cron recipe to repo Cheffile. --- Cheffile | 1 + Cheffile.lock | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/Cheffile b/Cheffile index 56b4d5c7..aa010340 100644 --- a/Cheffile +++ b/Cheffile @@ -16,3 +16,4 @@ cookbook "rails", path: "vendor/cookbooks/rails" cookbook "ssh_deploy_keys", path: "vendor/cookbooks/ssh_deploy_keys" cookbook "backups", path: "vendor/cookbooks/backups" cookbook "sysadmins", path: "vendor/cookbooks/sysadmins" +cookbook "cron", path: "vendor/cookbooks/cron" diff --git a/Cheffile.lock b/Cheffile.lock index 58750d84..7bd6e6fd 100644 --- a/Cheffile.lock +++ b/Cheffile.lock @@ -69,6 +69,11 @@ PATH specs: backups (0.1.0) +PATH + remote: vendor/cookbooks/cron + specs: + cron (0.0.1) + PATH remote: vendor/cookbooks/packages specs: @@ -97,6 +102,7 @@ PATH DEPENDENCIES apt (~> 2.6.1) backups (>= 0) + cron (>= 0) mysql (~> 5.3.6) nginx (~> 2.7.4) packages (>= 0) From 65d2bb982de9bd9a864063a139abb805ec7fcd2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A8r=20Kessels?= Date: Sun, 18 Jan 2015 18:09:28 +0100 Subject: [PATCH 4/7] Add a crontab example to VagrantFile for debugging. --- Vagrantfile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Vagrantfile b/Vagrantfile index eeb27e63..27da44c7 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -110,6 +110,13 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| server_name www.localhost; return 301 $scheme://localhost:8081$request_uri; }" + }, + "cron" => { + "sitemap" => { + minute: 0, + hour: 5, + command: "rake -s sitemap:refresh" + } } } }, @@ -127,6 +134,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| chef.add_role "postgresql" chef.add_role "rails_passenger" + chef.add_recipe "cron" chef.log_level = :info From 245cd5f3a79fc809fc73411d3c802b440e5ea6f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A8r=20Kessels?= Date: Sun, 18 Jan 2015 18:17:27 +0100 Subject: [PATCH 5/7] Implement HoundCI suggestions. --- vendor/cookbooks/cron/recipes/default.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vendor/cookbooks/cron/recipes/default.rb b/vendor/cookbooks/cron/recipes/default.rb index c7fa4fb7..0ea7f9ea 100644 --- a/vendor/cookbooks/cron/recipes/default.rb +++ b/vendor/cookbooks/cron/recipes/default.rb @@ -29,8 +29,8 @@ attributes = crontab.dup unscoped_command = attributes.delete("command") - rails_env = app_info['rails_env'] || "production" - user = attributes.delete("user") || app_info['deploy_user'] || "deploy" + rails_env = app_info["rails_env"] || "production" + user = attributes.delete("user") || app_info["deploy_user"] || "deploy" app_dir = "#{node[:rails][:applications_root]}/#{app}/current" command = "cd #{app_dir} && ( PATH=/opt/rbenv/shims:$PATH RAILS_ENV=#{rails_env} bundle exec #{unscoped_command} )" @@ -38,7 +38,7 @@ cron "#{app}_#{id}" do command(command) user(user) - attributes.each {|attribute, value| send(attribute, value) } + attributes.each { |attribute, value| send(attribute, value) } end end end From 6885e91d826d7accb59141536178bd9a98251f49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A8r=20Kessels?= Date: Sun, 18 Jan 2015 18:19:43 +0100 Subject: [PATCH 6/7] Typofix in the documentation: leftover copy-paste errorf from sysadmins. --- vendor/cookbooks/cron/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/cookbooks/cron/README.md b/vendor/cookbooks/cron/README.md index 1de9e0e5..3b534395 100644 --- a/vendor/cookbooks/cron/README.md +++ b/vendor/cookbooks/cron/README.md @@ -7,7 +7,7 @@ with commands that will be ran within the context of the app. Attributes ---------- -#### sysadmins::default +#### cron::default From 5a502736cc6d01fe8b4913737f0b000d48bb8625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A8r=20Kessels?= Date: Fri, 30 Jan 2015 09:04:15 +0100 Subject: [PATCH 7/7] Add an example crontab entry to the sample_host --- nodes/sample_host.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/nodes/sample_host.json b/nodes/sample_host.json index 1525a285..1f865f7a 100644 --- a/nodes/sample_host.json +++ b/nodes/sample_host.json @@ -53,6 +53,13 @@ "username": "", "password": "", "database": "_" + }, + "cron": { + "sitemap": { + "minute": 0, + "hour": 5, + "command": "rake -s sitemap:refresh" + } } } }
Key