Capistrano recipe to automatically run deploy:cleanup only when needed
We do over 20 deployments a day using capistrano (actually webistrano) and we have a problem where the disk space on our servers get full of old deployment folders.
Every now and again I run the deploy:cleanup
task to clean out all deployments (it keeps the last :keep_releases
, currently set to 30). I would like to automate the cleanup.
One solution would be to add the following to the recipe to automatically run the cleanup after every deployment:
after "deploy", "deploy:cleanup"
But, I don't want to do this after every deployment, I'd like to limit it to only when the number of previous deployments gets to a threash开发者_StackOverflow中文版old, e.g. 70. Does anyone know how I can do this?
Thoughts:
- Does Capistrano provide a variable that holds the number of previous deployments?
- If not, does anyone know a way to calculate it. i.e.
set :num_releases, <what-can-I-put-here-to-count-previous-deployments>
- If not, does anyone know a way to calculate it. i.e.
- Is there a way to pimp
deploy:cleanup
so it uses a minimum threshold, i.e. exit if< :max_releases
previous deployments (where:max_releases
is different from:keep_releases
). - Could the
except
keyword be used? i.e. something like:except => { :num_releases < 70}
.
Does Capistrano provide a variable that holds the number of previous deployments?
Yes, releases.length
Is there a way to pimp deploy:cleanup so it uses a minimum threshold?
Yes, here is a privately namespaced task that will trigger the normal cleanup task ONLY if a certain number of release folders have built up:
namespace :mystuff do
task :mycleanup, :except => { :no_release => true } do
thresh = fetch(:cleanup_threshold, 70).to_i
if releases.length > thresh
logger.info "Threshold of #{thresh} releases reached, runing deploy:cleanup."
deploy.cleanup
end
end
end
To have this run automatically after a deploy, put this at the top of the recipe:
after "deploy", "mystuff:mycleanup"
The good thing about this is that, before
and after
directives set on deploy:cleanup
are executed as normal. For example we require the following:
before 'deploy:cleanup', 'mystuff:prepare_cleanup_permissions'
after 'deploy:cleanup', 'mystuff:restore_cleanup_permissions'
A quick and dirty approach using the current capistrano code:
Change the cleanup task in https://github.com/capistrano/capistrano/blob/master/lib/capistrano/recipes/deploy.rb#L405 into this:
task :cleanup, :except => { :no_release => true } do
thresh = fetch(:cleanup_threshold, 70).to_i
count = fetch(:keep_releases, 5).to_i
if thresh >= releases.length
logger.important "no old releases to clean up"
else
logger.info "threshold of #{thresh} releases reached, keeping #{count} of #{releases.length} deployed releases"
directories = (releases - releases.last(count)).map { |release|
File.join(releases_path, release) }.join(" ")
try_sudo "rm -rf #{directories}"
end
end
and then you will be able to add
set :cleanup_threshold, 70
to your deployment recipe.
精彩评论