Customizing disable_web for multiple sites
On Measure Map, we have two separate applications: the frontend that users log into and see their stats, and the tracker, where things about your blog are recorded. Links to tracker are sourced in users' blogs as Javascript, so they had better return valid Javascript code at all times, even when we take the application offline for maintenance.
Ok, so how do we override Switchtower's disable_web task to use a custom page? Here's one way. It assumes a custom page lives at config/templates/maintenance.rhtml.
task :disable_web do # Get the current path dir = `pwd`.chomp # Copy the template to the current path (this is where 'render' looks) `cp #{dir}/config/templates/maintenance.rhtml #{dir}/maintenance.rhtml` # Read in file with replacements maintenance = render("maintenance", :deadline => ENV['UNTIL'], :reason => ENV['REASON']) # Copy to the server put maintenance, "#{shared_path}/system/maintenance.html", :mode => 0644 # Remove local copy `rm #{dir}/maintenance.rhtml` # Just in case something goes wrong, clean up on_rollback do `rm #{dir}/maintenance.rhtml` delete "#{shared_path}/system/maintenance.html" end end
Remember when using the default mod_rewrite rules to support the maintenance page, you will redirect everything to this file, so you can't use any external stylesheet or image files unless you get tricky with mod_rewrite.
Cool, so now we have our own maintenance page. Next problem; how to use separate files for our two applications? Here's a nice DRY version that's easy to extend to as many roles as you need.
# Stay DRY by configuring the task def move_maintenance_file(name) Proc.new do dir = `pwd`.chomp `cp #{dir}/config/templates/#{name}.rhtml #{dir}/#{name}.rhtml` maintenance = render(name, :deadline => ENV['UNTIL'], :reason => ENV['REASON']) put maintenance, "#{shared_path}/system/maintenance.html", :mode => 0644 `rm #{dir}/#{name}.rhtml` on_rollback do `rm #{dir}/#{name}.rhtml` delete "#{shared_path}/system/maintenance.html" end end end # Define two new tasks for disabling web on our different applications task :disable_web_frontend, :roles => :web_frontend, &move_maintenance_file('maintenance') task :disable_web_tracker, :roles => :web_tracker, &move_maintenance_file('maintenance-tracker') # Override disable_web to send different files to web_frontend and web_tracker task :disable_web do disable_web_frontend disable_web_tracker end
With this in place, we simply create two files, config/templates/maintenance.rhtml for the frontend, and config/templates/maintenance-tracker.rhtml for the tracker, and we're all set.