*** This version of Confluence is for testing only and contains a copy of content from June 29th 2026. No changes will be preserved. ***
...
| Code Block |
|---|
require 'capistrano/ext/multistage' default_run_options[:shell] = '/bin/bash' set :application, "features.library.cornell.edu" # TODO - name your application default_run_options[:shell] = '/bin/bash' # based on: # http://guides.beanstalkapp.com/deployments/deploy-with-capistrano.html # http://www.58bits.com/blog/2013/03/23/deploying-drupal-with-capistrano # https://github.com/antistatique/capdrupal #SSH and PTY Options default_run_options[:pty] = true ssh_options[:forward_agent] = true set :use_sudo, false #set :port, 5144 #On Mac OS X ssh_options[:compression] = "none" #Application settings set :user, ENV['USER'] # can also come from ~/.caprc set :runner, ENV['USER'] # when sudo-ing use this user set :runner_group, "lib_web_dev_role" set :admin_runner, ENV['USER'] # when sudo-ing during :setup use this set :php_user, "apache" # user php runs as set :stages, ["staging", "production"] # TODO - define different stages set :default_stage, "staging" set :keep_releases, 5 set :drush_cmd, "drush" set :scm, :git set :repository, "git@git.library.cornell.edu:features_test_library_cornell_edu.git" # TODO - your git repo here set :branch, "master" # prevent errors from missing javascripts,stylesheets,images directories set :normalize_asset_timestamps, false # now use the regular cap deploy instead of drupal #before 'deploy', 'deploy:drush:site_offline', 'drupal:db:backup', 'git:push_deploy_tag' before 'deploy' do git.push_deploy_tag drupal.drush.site_offline drupal.db.backup drupal.drush.site_online end #after 'deploy', 'drupal:link_filesystem', 'drupal:drush:set_files_paths', 'drupal:drush:updatedb', 'deploy:drush:site_online' after 'deploy' do drupal.link_filesystem drupal.drush.site_offline drupal.drush.set_files_paths drupal.drush.updatedb drupal.drush.revert_features drupal.drush.site_online end after 'deploy:rollback' do drupal.link_filesystem drupal.drush.clear_all_caches drupal.drush.site_offline drupal.db.reload_previous# TODO: list of modules to enable # drush pm-list | grep Enabled | grep -o '(.\+)' | grep -o '[^()]\+' | tr '\n' ' ' && echo "" set :enabled_modules, File.open("drupal_config/enabled_modules.txt", "r") { |file| file.read.split(" ") } # override these in production set :disabled_modules, File.open("drupal_config/disabled_modules.txt", "r") { |file| file.read.split(" ") } set :default_theme, File.open("drupal_config/default_theme.txt", "r") { |file| file.read.split(" ") } #SSH and PTY Options default_run_options[:pty] = true ssh_options[:forward_agent] = true set :use_sudo, false #set :port, 5144 #On Mac OS X ssh_options[:compression] = "none" #Application settings set :user, ENV['USER'] # can also come from ~/.caprc set :runner, ENV['USER'] # when sudo-ing use this user set :runner_group, "lib_web_dev_role" set :admin_runner, ENV['USER'] # when sudo-ing during :setup use this set :php_user, "apache" # user php runs as set :stages, ["local", "staging", "production"] # TODO - define different stages set :default_stage, "staging" set :keep_releases, 5 set :drush_cmd, "drush" set :scm, :git set :repository, "git@git.library.cornell.edu:features_test_library_cornell_edu.git" # TODO - your git repo here set :branch, "master" # prevent errors from missing javascripts,stylesheets,images directories set :normalize_asset_timestamps, false # now use the regular cap deploy instead of drupal #before 'deploy', 'deploy:drush:site_offline', 'drupal:db:backup', 'git:push_deploy_tag' before 'deploy' do git.push_deploy_tag drupal.drush.site_offline drupal.db.backup drupal.drush.site_online end before#after 'drupal:db:grabdeploy', 'drupal:drush:sitelink_offlinefilesystem', 'drupal:drush:clearset_allfiles_cachespaths' after, 'drupal:dbdrush:grabupdatedb', 'drupaldeploy:drush:site_online' before 'drupal:db:install', 'drupal:drush:site_offline' after 'drupal:db:install', 'drupal:drush:after 'deploy' do drupal.link_filesystem drupal.drush.site_offline drupal.drush.set_files_paths', 'drupal:drush:clear_all_caches', 'drupal:drush:site_online' before 'drupal:db:install_latest', 'drupal:drush:site_offline' after 'drupal:db:install_latest', 'drupal:drush:set_files_paths', 'drupal:drush:clear_all_caches', 'drupal:drush:site_online'.drush.enabler(enabled_modules) drupal.drush.updatedb drupal.drush.disabler(disabled_modules) drupal.drush.revert_features drupal.drush.set_theme(default_theme) drupal.drush.clear_all_caches drupal.drush.site_online end after 'deploy:setup', 'drupal:site_setup', 'deploy:update', 'drupal:link_filesystem', 'drupal:site_setup_permissions' after 'drupal:post_install_configurationrollback' do drupal.link_filesystem drupal.drush.clear_all_caches drupal.drush.site_offline drupal.db.reload_previous drupal.drush.site_online end before 'drupal:db:grab', 'drupal:drush:setsite_files_pathsoffline', 'drupal:drush:updatedbclear_all_caches' after 'drupal:fix_undefined_index:db:grab', 'drupal:drush:site_online' before 'drupal:db:install', 'drupal:drush:site_offline' after 'drupal:db:install', 'drupal:drush:set_files_paths', 'drupal:drush:clear_all_caches', ' namespace :deploy do task :start do ; end task :stop do ; end task :restart, :roles => :app, :except => { :no_release => true } do #Place holder for app restart - in Ruby apps this would touch restart.txt. end end #Drupal application and project specific tasks. namespace :drupal do #desc "Perform a Drupal application deploy." # see before/after deploy above task :defaultdrupal:drush:site_online' before 'drupal:db:install_latest', 'drupal:drush:site_offline' after 'drupal:db:install_latest', 'drupal:drush:set_files_paths', 'drupal:drush:clear_all_caches', 'drupal:drush:site_online' after 'deploy:setup', 'drupal:site_setup', 'deploy:update', 'drupal:link_filesystem', 'drupal:site_setup_permissions' after 'drupal:post_install_configuration' do drupal.drush.set_files_paths drupal.drush.enabler(enabled_modules) drupal.drush.updatedb drupal.drush.disabler(disabled_modules) drupal.drush.set_theme(default_theme) end after 'drupal:fix_undefined_index', 'drupal:drush:clear_all_caches' namespace :deploy do task :start do ; end task :stop do ; end task :restart, :roles => :app, :except => { :no_release => true } do #Place holder for app restart - in Ruby apps this would touch restart.txt. end end #Drupal application and project specific tasks. namespace :drupal do desc "Real list of modules to enable" task :read_enabled_modules do contents = File.open("config/enabled_modules.txt", "r") { |file| file.read } return contents end #desc "Perform a Drupal application deploy." # see before/after deploy above task :default, :roles => :app, :except => { :no_release => true } do site_offline clear_all_caches backupdb deploy.default link_filesystem set_files_paths updatedb site_online end desc "Initial remote setup for Drupal" task :site_setup, :roles => :app do commands = [] commands << "mkdir -p #{deploy_to}/backup" commands << "mkdir -p #{deploy_to}/cache" commands << "mkdir -p #{deploy_to}/files" commands << "mkdir -p #{deploy_to}/log" commands << "mkdir -p #{deploy_to}/private_files" commands << "mkdir -p #{deploy_to}/subsites" commands << "mkdir -p #{deploy_to}/tmp" run commands.join(' && ') if commands.any? end #desc "Set permissions for php to write to some directories" task :site_setup_permissions, :roles => :app, :except => { :no_release => true } do site_offline clear_all_caches backupdbsudo "chown #{php_user} #{deploy_to}/backup" deploy.default link_filesystem set_files_pathssudo "chown #{php_user} #{deploy_to}/cache" updatedb sudo "chown site_online#{php_user} #{deploy_to}/files" end descsudo "Initial remote setup for Drupalchown #{php_user} #{deploy_to}/private_files" task :site_setup, :roles => :app do sudo "chown #{php_user} #{deploy_to}/tmp" commands = [] commands << "mkdir -psudo "chown #{php_user} #{deploy_to}/backup" commands << "chmod g+w #{deploy_to}/backupsettings.php" end desc "Get the user to run the Drupal install, then do final configuration" task commands << "mkdir -p #{deploy_to}/cache":post_install_configuration, :roles => :app do commandsservers << "mkdir -p #{deploy_to}/files" commands << "mkdir -p #{deploy_to}/log" commands << "mkdir -p #{deploy_to}/private_files" commands << "mkdir -p #{deploy_to}/subsites= find_servers_for_task(current_task) server = servers.first default_ans = 'yes' ans = Capistrano::CLI.ui.ask "Have you run http://#{server}/install.php? [#{default_ans}]" commandsans << "mkdir -p #{deploy_to}/tmp" = default_ans if ans.empty? abort run commands.join(' && ') if commands.any?"Please install Drupal first" if ans != default_ans end #desc "SetThis permissionsshould fornot phpbe torun writeon to some directories" task :site_setup_permissions, :roles => :app do sudo "chown #{php_user} #{deploy_to}/backup" sudo "chown #{php_user} #{deploy_to}/cache" sudo "chown #{php_user} #{deploy_to}/files" sudo "chown #{php_user} #{deploy_to}/private_files" sudo "chown #{php_user}its own - so comment out the description. # "Recreate the required Drupal symlinks to static directories and clear all caches." task :link_filesystem, :roles => :app, :except => { :no_release => true } do commands = [] commands << "if [ ! -f #{deploy_to}/tmp" sudo "chown #{php_user}settings.php ]; then cp #{app_path}/sites/default/default.settings.php #{deploy_to}/settings.php" end desc "Get the user to run the Drupal install, then do final configuration" task :post_install_configuration, :roles => :app do servers = find_servers_for_task(current_task); fi" commands << "cat /dev/null > #{app_path}/.htaccess" commands << "mkdir -p #{app_path}/sites/default" servercommands = servers.first default_ans = 'yes'<< "ln -nfs #{share_path}/settings.php #{app_path}/sites/default/settings.php" anscommands = Capistrano::CLI.ui.ask "Have you run http://#{server}/install.php? [#{default_ans}]<< "ln -nfs #{share_path}/files #{app_path}/sites/default/files" ans = default_ans if ans.empty?commands << "ln -nfs #{share_path}/tmp #{app_path}/sites/default/tmp" abortcommands "Please install Drupal first" if ans != default_ans end #desc "This should not be run on its own - so comment out the description. # "Recreate the required Drupal symlinks to static directories and clear all caches." task :link_filesystem, :roles => :app, :except => { :no_release => true } do commands = [] commands << "if [ ! -f #{deploy_to}/settings.php ]; then cp #{app_path}/sites/default/default.settings.php #{deploy_to}/settings.php; fi" commands << "cat /dev/null > #{app_path}/.htaccess" commands << "mkdir -p #{app_path}/sites/default" commands << "ln -nfs #{share_path}/settings.php #{app_path}/sites/default/settings.php" commands << "ln -nfs #{share_path}/files #{app_path}/sites/default/files" commands << "ln -nfs #{share_path}/tmp #{app_path}/sites/default/tmp" commands << "ln -nfs #{share_path}/cache #{app_path}/cache" commands << "find #{app_path} -type d -print0 | xargs -0 chmod 755" commands << "find #{app_path} -type f -print0 | xargs -0 chmod 644" run commands.join(' && ') if commands.any? end namespace :db do desc "returns a stage and time stamped backup file name" def backup_file_name(stage) backup_time = release_name # use capistrano's variable %Y%m%d%H%M%S return make_backup_file_name(stage, backup_time) end def make_backup_file_name(stage, backup_time) filename = "backup/#{stage}-snapshot-#{backup_time}.sql" return filename<< "ln -nfs #{share_path}/cache #{app_path}/cache" commands << "find #{app_path} -type d -print0 | xargs -0 chmod 755" commands << "find #{app_path} -type f -print0 | xargs -0 chmod 644" run commands.join(' && ') if commands.any? end namespace :db do desc "returns a stage and time stamped backup file name" def backup_file_name(stage) backup_time = release_name # use capistrano's variable %Y%m%d%H%M%S return make_backup_file_name(stage, backup_time) end def make_backup_file_name(stage, backup_time) filename = "backup/#{stage}-snapshot-#{backup_time}.sql" return filename end desc "gets the most recent database backup file with a given prefix" def latest_backup(backup_prefix) tmax = Time.at 0 latestfile = nil Dir.glob("backup/#{backup_prefix}-snapshot-*") do |filename| mt = File.mtime(filename) if mt > tmax tmax = mt latestfile = filename end end return latestfile end desc "upload and install database" def upload_install(filename) puts "uploading #{filename}" top.upload("#{filename}", "#{deploy_to}/#{filename}") puts "loading drupal with database" drush.load_drupal("#{deploy_to}/#{filename}") end desc "getsbackup the most recent database backup file with a given prefix" deftask latest_backup(backup_prefix) tmax = Time.at 0 latestfile = nil Dir.glob("backup/#{backup_prefix}-snapshot-*") do |filename|:backup, :roles => :app, :except => { :no_release => true } do mtbackup_file = File.mtime(filenamebackup_file_name(stage) if mt > tmaxdrush.dump_drupal(backup_file) puts "#{backup_file}" tmax = mtend desc "Grab local copy of latestfile = filenameremote database" # cap endproduction drupal:db:grab task end return latestfile end :grab, :roles => :app, :except => { :no_release => true } do desc "upload andbackup_file install database"= backup_file_name(stage) def uploaddrush.dump_installdrupal(filenamebackup_file) puts "uploading #{filenamebackup_file}" top.upload("#{filenamedownload "#{deploy_to}/#{backup_file}", "#{deploy_to}/#{filenamebackup_file}") puts "loading drupal with database"end drush.load_drupal("#{deploy_to}/#{filename}") end desc "backup the database"desc "Install latest local database snapshot" # cap staging drupal:db:install_latest -s from=production task :backupinstall_latest, :roles => :app, :except => { :no_release => true } do backup_file = backup_file_name(stage) drush.dump_drupal(backup_fileset :source_stage, fetch(:from, '') puts "#{backup_file}"if source_stage.empty? end descputs "Grabuseage:" local copy of remote database" abort # "cap productionstaging drupal:db:grab task :grab, :roles => :app, :except => { :no_release => true } do install_latest -s from=production" else backup_filefilename = latest_backup(source_file_name(stage) if drush.dump_drupal(backup_file) filename.nil? puts "#{backup_file}" download "#{deploy_to}/#{backup_file}", "#{backup_file}" end desc "Install latest local database snapshot" abort "first grab a copy of the datatbase: cap #{source_stage} drupal:db:grab" else # cap staging drupal:db:install_latest -s from=production puts "Moving database task :install_latest, :roles => :app, :except => { :no_release => true } dofrom #{source_stage} to #{stage}" upload_install(filename) set :source_stage, fetch(:from, '') end if source_stage.empty?end end putsdesc "useage:" Install a specific local database snapshot" abort# "cap staging drupal:db:install_latest -s from=production" elsefile=backup/staging-snapshot-2013-10-25-13-17-23.sql task :install, :roles => :app, :except => { :no_release => true } do set :filename, = latest_backup(source_stage) fetch(:file, '') if filename.nilempty? puts "useage:" abort "first grab a copyabort of"cap thestaging datatbasedrupal:db:install cap #{source_stage} drupal:db:grab" -s file=backup/production-snapshot-2013-10-25-13-17-23.sql" else puts "Moving database from #{source_stagefilename} to #{stage}" upload_install(filename) end end end desc "Install a specific local database snapshot" # cap staging drupal:db:install -s file=backup/staging-snapshot-2013-10-25-13-17-23.sqlreload database from previous release" task :installreload_previous, :roles => :app, :except => { :no_release => true } do set :filename, fetch(:file, '') if filename.empty? puts "useage:" abort "cap staging drupal:db:install -s file=backup/production-snapshot-2013-10-25-13-17-23.sql"previous_release_name = File.basename(previous_release) else filename = make_backup_file_name(stage, previous_release_name) puts "Movingreloading database from #{filename} to #{stage}" upload_install(filenamedrush.load_drupal("#{deploy_to}/#{filename}") end end namespace :drush enddo desc "reloadBackup the database from previous release." task :reload_previousbackupdb, :roleson_error => :app, :except => { :no_release => true } docontinue do run "#{drush_cmd} -r #{app_path} sql-dump --result-file=#{deploy_to}/backup/release-drupal-db.sql" end #desc previous_release_name = File.basename(previous_release) filename = make_backup_file_name(stage, previous_release_name)"Backup the database" # we don't want to require backup_migrate task puts "reloading database from #{filename}":backupdb_bam, :on_error => :continue do drush.load_drupal(run "#{deploydrush_to}/cmd} -r #{filename}") end app_path} bam-backup" end namespace :drush do desc "BackupClear theall database.caches" task :backupdb, :on_errorclear_all_caches, :roles => :app, :except => { :no_release => :continuetrue } do run "#{drush_cmd} -r #{app_path} sql-dump --result-file-uri=#{deploydrush_to}/backup/release-drupal-db.sql" end #desc "Backup the database" # we don't want to require backup_migrate task :backupdb_bam, :on_error => :continue douri} cc all" end desc "error message fix - undefined index: <name, version>" # see https://drupal.org/node/1170362 task :fix_undefined_index, :roles => :app, :except => { :no_release => true } do run "#{drush_cmd} -r #{app_path} vset --yes install_profile \"standard\"" run "#{drush_cmd} -r #{app_path} bam-backupsql-query \"UPDATE system SET status=1 WHERE name='standard';\"" end desc "ClearRevert all caches features to install the newest versions" task :clearrevert_all_cachesfeatures, :roles => :app, :except => { :no_releaseon_error => true }:continue do run "#{drush_cmd} -r #{app_path} features--uri=#{drush_uri} cc allrevert-all -y" end desc "errorset messagethe fixprivate_files -& undefinedtmp index:path <name, version>" # see https://drupal.org/node/1170362for the deploy environment" task :fixset_undefined_index, :roles => :app, :except => { :no_releasefiles_paths, :on_error => true:continue } do run "#{drush_cmd} -r #{app_path} vset --yes installfile_public_profile \"standard\""path sites/default/files" run "#{drush_cmd} -r #{app_path} vset sql-query \"UPDATE system SET status=1 WHERE name='standard';\""--yes file_private_path #{deploy_to}/private_files" run "#{drush_cmd} -r #{app_path} vset --yes file_temporary_path sites/default/tmp" end desc "Revert all features to install Set the newestsite versionsoffline" task :revertsite_featuresoffline, :on_error => :continue do do run "#{drush_cmd} -r #{app_path} vset site_offline 1 -y" run "#{drush_cmd} -r #{app_path} features-revert-all vset maintenance_mode 1 -y" end desc "setSet the private_files & tmp path for the deploy environment" task :set_files_paths, :on_error => :continue do run "#{drush_cmd} -r #{app_path} vset --yes file_public_path sites/default/files"site online" task :site_online, :on_error => :continue do run "#{drush_cmd} -r #{app_path} vset --yes file_private_path #{deploy_to}/private_filessite_offline 0 -y" run "#{drush_cmd} -r #{app_path} vset --yes file_temporary_path sites/default/tmpmaintenance_mode 0 -y" end desc "Set the site offline desc "Run Drupal database updates for new core/modules/themes if required." task :site_offlineupdatedb, :on_error => :continue do run "#{drush_cmd} -r #{app_path} vset site_offline 1 -y" run "#{drush_cmd} -r #{app_path} vset maintenance_mode 1 -updatedb -y" end desc "Setbackup the site online Drupal database to a timestamped file" taskdef :site_online, :on_error => :continue dodump_drupal(filename) run "#{drush_cmd} -r #{app_path} vset site_offline 0 -y"} sql-dump --result-file=#{deploy_to}/#{filename}" end desc "load the Drupal database from an sql dump" def load_drupal(filename) run "#`#{drush_cmd} -r #{app_path} vset maintenance_mode 0 -ysql-connect` < #{filename}" end desc "Runenable Drupalan databasearray updates for new core/modules/themes if required.of modules" task :updatedb, :on_error => :continue do def enabler(modules) run "#{drush_cmd} -r #{app_path} updatedb pm-enable -y #{modules.join(' ')}" end desc "backupdisable thean Drupalarray database to a timestamped fileof modules" def dump_drupaldisabler(filenamemodules) run "#{drush_cmd} -r #{app_path} sqlpm-dumpdisable --result-file=#{deploy_to}/#{filename}y #{modules.join(' ')}" end desc "loadset the Drupal database from an sql dumpdefault theme" def loadset_drupaltheme(filenametheme) run "`##{drush_cmd} -r #{app_path} sql-connect` <vset theme_default #{filenametheme}" end end end namespace :git do desc "Place release tag into Git and push it to origin server." task :push_deploy_tag do user = `git config --get user.name` email = `git config --get user.email` tag = "release_#{release_name}" if exists?(:stage) tag = "#{stage}_#{tag}" end puts `git tag #{tag} #{revision} -m "Deployed by #{user} <#{email}>"` puts `git push origin tag #{tag}` end end namespace :explore do desc "Local variables" task :locals, :on_error => :continue do local_variables.each {|var| puts "#{var} fetch(:#{var})"} puts "shared_path #{shared_path}" puts "stage #{stage}" puts "args #{args}" puts "release_name #{release_name}" puts "previous_revision #{previous_revision}" puts "current_revision #{current_revision}" # deploy.instance_variables.map do |var| # puts [var, deploy.instance_variable_get(var)].join(":") # end end desc "check paths for mysql and mysqldump" task :check_mysql, :on_error => :continue do puts "$PATH" run "echo $PATH" puts "Which mysql?" run "which mysql" puts "Which mysqldump?" run "which mysqldump" puts "connect statement:" run "#{drush_cmd} -r #{app_path} sql-connect" end desc "test du jour" task :testdujour, :on_error => :continue do mysqlcmd = %x[ echo `#{drush_cmd} -r #{app_path} sql-connect` ] puts "mysql command: #{mysqlcmd}" puts "current_path #{current_path}" puts "deploy_to #{deploy_to}" end desc "find code for a task" task :find, :on_error => :continue do # load all the tasks associated with the rails app Rails.application.load_tasks # get the source locations of actions called by a task task_name = 'deploy:cold' # fully scoped task name Rake.application[task_name].actions.map(&:source_location) end desc "try out enabler" task :tryout do modules = ['aaa', 'bbb', 'ccc', 'ploop'] drupal.drush.enabler(modules) end end |