diff --git a/README.textile b/README.textile index 4f1e739..611814e 100644 --- a/README.textile +++ b/README.textile @@ -11,20 +11,63 @@ for common issues which can then be used by the community. Feel free to improve upon this recipe collection by adding your own! Currently included recipes in this gem: - - * Ruby Setup - * Rubygems Management * Apache Server - * Phusion Passenger + * Apparmor + * Aptitude + * Autossh + * Backgroundrb + * Bprobe + * Bundler Setup + * Cassandra + * Chef Client + * Chef Server + * Csgo_ds + * DelayedJob + * Datadog + * Denyhosts + * Dovecot + * Dphys_swapfile + * Erlang + * Gitosis Git Repository Hosting + * God + * Graphite + * Haproxy + * Hids + * Juggernaut Daemon + * Leap_second + * Logrotat * Memcached Management + * MongoDB Management + * Munin + * Mysql + * Mysql_master + * newrelic_rpm + * newrelic_sysmond + * nginx + * nginx_passenger + * nginx_unicorn + * Postgresql + * Phusion Passenger + * Provision + * Rails + * Redis + * Ree + * Resque + * Ruby Setup + * Rubygems Management + * s3cmd + * s3fs + * s3sync + * sdagent + * ssh + * ssmtp + * statsd + * teelogger * ThinkingSphinx Daemon - * Juggernaut Daemon - * Backgroundrb Server - * DelayedJob Worker + * Ufw + * Unicorn * Whenever Cron Scheduling - * MongoDB Management - * Aptitude Package Management - * Gitosis Git Repository Hosting + * Xtrabackup Check out the USAGE section below for specific tasks included in the recipes. @@ -34,6 +77,8 @@ To install the gem, execute: @$ sudo gem install cap-recipes --source http://gemcutter.org@ +gem install cap-recipes gives a smaller collection of recipes, so make sure you fork from the gem you want + Then, include into your @deploy.rb@ configuration file for Capistrano:

@@ -515,4 +560,4 @@ 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.
\ No newline at end of file
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/lib/cap_recipes/tasks/monit/hooks.rb b/lib/cap_recipes/tasks/monit/hooks.rb
index a6ee7a0..b406e8e 100644
--- a/lib/cap_recipes/tasks/monit/hooks.rb
+++ b/lib/cap_recipes/tasks/monit/hooks.rb
@@ -1,4 +1,4 @@
 Capistrano::Configuration.instance(true).load do
   after "deploy:provision", "monit:install"
   after "deploy:restart", "monit:enable", "monit:restart"
-end
\ No newline at end of file
+end
diff --git a/lib/cap_recipes/tasks/postgresql.rb b/lib/cap_recipes/tasks/postgresql.rb
new file mode 100644
index 0000000..10617e2
--- /dev/null
+++ b/lib/cap_recipes/tasks/postgresql.rb
@@ -0,0 +1,149 @@
+# @author Donovan Bray 
+require File.expand_path(File.dirname(__FILE__) + '/utilities')
+
+# This Nginx is targeted for the :app role meant to be acting as a front end
+# to a unicorn based application
+
+# Additions
+# https://github.com/newobj/nginx-x-rid-header
+# https://github.com/yaoweibin/nginx_syslog_patch
+
+# Possible Future Additions
+# https://support.newrelic.com/kb/features/tracking-front-end-time
+
+  
+Capistrano::Configuration.instance(true).load do
+  
+  
+  set :postgresql_host, "localhost"
+  set :postgresql_user, application
+  set(:postgresql_password) {Capistrano::CLI.password_prompt "PostgreSQL Password: "}
+  set(:postgresql_database) {"#{application}_production"}
+  set(:postgresql_dump_path) {"#{current_path}/tmp"}
+  set(:postgresql_dump_file) {"#{application}_dump.sql"}
+  set(:postgresql_local_dump_path) {File.expand_path("../../../tmp", __FILE__) }
+  set(:postgresql_pid) {"/var/run/postgresql/9.2-main.pid"}
+  
+  namespace :postgresql do
+  desc "Install the latest stable release of PostgreSQL."
+  task :install, roles: :db, only: {primary: true} do
+    run "#{sudo} add-apt-repository -y ppa:pitti/postgresql"
+    run "#{sudo} apt-get -y update"
+    run "#{sudo} apt-get -y install postgresql libpq-dev"
+  end
+  after "postgresql:install", "postgresql:create_database"
+
+  desc "Create a database for this application."
+  task :create_database, roles: :db, only: {primary: true} do
+    run %Q{#{sudo} -u postgres psql -c "create user #{postgresql_user} with password '#{postgresql_password}';"}
+    run %Q{#{sudo} -u postgres psql -c "create database #{postgresql_database} owner #{postgresql_user};"}
+  end
+  after "deploy:provision", "postgresql:install"
+
+  desc "Generate the database.yml configuration file."
+  task :setup, roles: :app do
+    run "mkdir -p #{shared_path}/config"
+    template "postgresql.yml.erb", "#{shared_path}/config/database.yml"
+  end
+  after "postgresql:create_database", "postgresql:setup"
+
+  desc "Symlink the database.yml file into latest release"
+  task :symlink, roles: :app do
+    puts "Symlinking database yml file"
+    run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
+  end
+  after "deploy:finalize_update", "postgresql:symlink"
+
+  desc "database console"
+  task :console do
+    auth = capture "cat #{shared_path}/config/database.yml"
+    puts "PASSWORD::: #{auth.match(/password: (.*$)/).captures.first}"
+    hostname = find_servers_for_task(current_task).first
+    exec "ssh #{hostname} -t 'source ~/.zshrc && psql -U #{application} #{postgresql_database}'"
+  end
+
+
+  namespace :local do
+    desc "Download remote database to tmp/"
+    task :download do
+      dumpfile = "#{postgresql_local_dump_path}/#{postgresql_dump_file}.gz"
+      get "#{postgresql_dump_path}/#{postgresql_dump_file}.gz", dumpfile
+    end
+
+    desc "Restores local database from temp file"
+    task :restore do
+      auth = YAML.load_file(File.expand_path('../../database.yml', __FILE__))
+      dev  = auth['development']
+      user, pass, database, host = dev['username'], dev['password'], dev['database'], dev['host']
+      dumpfile = "#{postgresql_local_dump_path}/#{postgresql_dump_file}"
+      system "gzip -cd #{dumpfile}.gz > #{dumpfile} && cat #{dumpfile} | psql -U #{user} -h #{host} #{database}"
+    end
+
+    desc "Dump remote database and download it locally"
+    task :localize do
+      remote.dump
+      download
+    end
+
+    desc "Dump remote database, download it locally and restore local database"
+    task :sync do
+      localize
+      restore
+    end
+  end
+
+  namespace :remote do
+    desc "Dump remote database"
+    task :dump do
+      dbyml = capture "cat #{shared_path}/config/database.yml"
+      info  = YAML.load dbyml
+      db    = info[stage.to_s]
+      user, pass, database, host = db['username'], db['password'], db['database'], db['host']
+      commands = <<-CMD
+        pg_dump -U #{user} -h #{host} #{database} | \
+        gzip > #{postgresql_dump_path}/#{postgresql_dump_file}.gz
+      CMD
+      run commands do |ch, stream, data|
+        if data =~ /Password/
+          ch.send_data("#{pass}\n")
+        end
+      end
+    end
+
+    desc "Uploads local sql.gz file to remote server"
+    task :upload do
+      dumpfile = "#{postgresql_local_dump_path}/#{postgresql_dump_file}.gz"
+      upfile   = "#{postgresql_dump_path}/#{postgresql_dump_file}.gz"
+      put File.read(dumpfile), upfile
+    end
+
+    desc "Restores remote database"
+    task :restore do
+      dumpfile = "#{postgresql_dump_path}/#{postgresql_dump_file}"
+      gzfile   = "#{dumpfile}.gz"
+      dbyml    = capture "cat #{shared_path}/config/database.yml"
+      info     = YAML.load dbyml
+      db       = info['production']
+      user, pass, database, host = db['username'], db['password'], db['database'], db['host']
+
+      commands = <<-CMD
+        gzip -cd #{gzfile} > #{dumpfile} && \
+        cat #{dumpfile} | \
+        psql -U #{user} -h #{host} #{database}
+      CMD
+
+      run commands do |ch, stream, data|
+        if data =~ /Password/
+          ch.send_data("#{pass}\n")
+        end
+      end
+    end
+
+    desc "Uploads and restores remote database"
+    task :sync do
+      upload
+      restore
+    end
+  end
+  end
+end
diff --git a/lib/cap_recipes/tasks/rails/hooks.rb b/lib/cap_recipes/tasks/rails/hooks.rb
index 9f122dd..4d8332a 100644
--- a/lib/cap_recipes/tasks/rails/hooks.rb
+++ b/lib/cap_recipes/tasks/rails/hooks.rb
@@ -1,6 +1,6 @@
 Capistrano::Configuration.instance(true).load do
-  after "deploy:update_code", "rails:symlink_db_config" # copy database.yml file to release path
-  after "deploy:update_code", "rails:sweep:cache" # clear cache after updating code
-  after "deploy:restart"    , "rails:repair_permissions" # fix the permissions to work properly
-  after "deploy:restart"    , "rails:ping" # ping passenger to start the rails instance
-end
\ No newline at end of file
+  #after "deploy:update_code", "rails:symlink_db_config" # copy database.yml file to release path
+  #after "deploy:update_code", "rails:sweep:cache" # clear cache after updating code
+  #after "deploy:restart"    , "rails:repair_permissions" # fix the permissions to work properly
+  #after "deploy:restart"    , "rails:ping" # ping passenger to start the rails instance
+end
diff --git a/lib/cap_recipes/tasks/rails/manage.rb b/lib/cap_recipes/tasks/rails/manage.rb
index 1d699ce..2209634 100644
--- a/lib/cap_recipes/tasks/rails/manage.rb
+++ b/lib/cap_recipes/tasks/rails/manage.rb
@@ -47,6 +47,28 @@
         run "cd #{release_path} && #{try_sudo} bundle exec rake tmp:cache:clear RAILS_ENV=#{stage_or_production}"
       end
     end
+    namespace :rollback do
+      desc "Moves the repo back to the previous version of HEAD"
+      task :repo, :except => { :no_release => true } do
+        set :branch, "HEAD@{1}"
+        deploy.default
+      end
+
+      desc "Rewrite reflog so HEAD@{1} will continue to point to at the next previous release."
+      task :cleanup, :except => { :no_release => true } do
+        run "cd #{current_path}; git reflog delete --rewrite HEAD@{1}; git reflog delete --rewrite HEAD@{1}"
+      end
+
+      desc "Rolls back to the previously deployed version."
+      task :default do
+        rollback.repo
+        rollback.cleanup
+      end
+    end
+
+  end
+  def run_rake(cmd)
+    run "cd #{current_path}; #{rake} #{cmd}"
   end
 
   # ===============================================================
diff --git a/lib/cap_recipes/tasks/redis/install.rb b/lib/cap_recipes/tasks/redis/install.rb
index f5b9dc0..c28cd7f 100755
--- a/lib/cap_recipes/tasks/redis/install.rb
+++ b/lib/cap_recipes/tasks/redis/install.rb
@@ -57,7 +57,7 @@ def ipaddress(eth)
     desc "install redis-server"
     task :install, :roles => [:redis,:redis_slave] do
       utilities.apt_install %w[build-essential wget]
-      utilities.addgroup "redis", :system => true
+      utilities.addgroup "redis", :system => true # needs sudo
       utilities.adduser "redis" , :nohome => true, :group => "redis", :system => true, :disabled_login => true
       sudo "mkdir -p #{redis_base_path}/bin #{redis_base_path}/src /var/log/redis"
       run "cd #{redis_base_path}/src && #{sudo} wget --tries=2 -c --progress=bar:force #{redis_src} && #{sudo} tar xzf #{redis_ver}.tar.gz"
diff --git a/lib/cap_recipes/tasks/utilities.rb b/lib/cap_recipes/tasks/utilities.rb
index 52890ee..faa52f2 100755
--- a/lib/cap_recipes/tasks/utilities.rb
+++ b/lib/cap_recipes/tasks/utilities.rb
@@ -161,7 +161,7 @@ def addgroup(group,options={})
     switches = ''
     switches += " --system" if options[:system]
     switches += " --gid #{options[:gid]} " if options[:gid]
-    invoke_command "/usr/sbin/addgroup  #{switches} #{group}", :via => run_method
+    invoke_command "sudo /usr/sbin/addgroup  #{switches} #{group}", :via => run_method
   end
 
   #utilities.delgroup('deploy')
@@ -339,6 +339,10 @@ def handle_command_with_input(local_run_method, shell_command, input_query, resp
   def deprecated(name,replacement=nil)
     raise Capistrano::Error, "#{name} is deprecated, #{replacement ? "see: #{replacment}" : "no replacement" }."
   end
+  
+  def set_default(name, *args, &block)
+    set(name, *args, &block) unless exists?(name)
+  end