production_chain 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *swp
2
+ .idea*
3
+ *.gem
data/README CHANGED
@@ -1 +1,6 @@
1
- A rails plugin that incorporate various libs, recipes and tasks
1
+ A rails gem that incorporate various libs, recipes and tasks
2
+
3
+ To add the recipes to capistrano, you have to add these two lines to `config/deploy.rb` :
4
+
5
+ require 'bundler/setup'
6
+ require 'production_chain'
@@ -0,0 +1,6 @@
1
+ class Numeric
2
+ # Rounds to the given decimal position.
3
+ def round_at(d)
4
+ (self * (10.0 ** d)).round.to_f / (10.0 ** d)
5
+ end
6
+ end
@@ -0,0 +1,16 @@
1
+ if defined?(Rails)
2
+ # Core Ext
3
+ require "core_ext/numeric"
4
+
5
+ # Rails
6
+ require "rails/action_controller/abstract_request"
7
+ require "rails/action_view/text_helper"
8
+
9
+ # Rake Tasks
10
+ require "tasks"
11
+ end
12
+
13
+ if defined?(Capistrano)
14
+ # Recipes
15
+ Dir[File.join(File.dirname(__FILE__), 'recipes/**/*.rb')].each { |file| load file }
16
+ end
@@ -0,0 +1,6 @@
1
+ class ActionController::AbstractRequest
2
+ # Test if request seems to come from a bot
3
+ def bot?
4
+ user_agent =~ /\b(Baidu|Gigabot|Googlebot|libwww-perl|lwp-trivial|msnbot|SiteUptime|Slurp|WordPress|ZIBB|ZyBorg)\b/i
5
+ end
6
+ end
@@ -0,0 +1,43 @@
1
+ module ActionView::Helpers::TextHelper
2
+ def truncate(text, *args)
3
+ options = args.extract_options!
4
+
5
+ # support either old or Rails 2.2 calling convention:
6
+ unless args.empty?
7
+ options[:length] = args[0] || 30
8
+ options[:omission] = args[1] || "..."
9
+ end
10
+ options.reverse_merge!(:length => 30, :omission => "...")
11
+
12
+ # support any of:
13
+ # * ruby 1.9 sane utf8 support
14
+ # * rails 2.1 workaround for crappy ruby 1.8 utf8 support
15
+ # * rails 2.2 workaround for crappy ruby 1.8 utf8 support
16
+ # hooray!
17
+ if text
18
+ chars = if text.respond_to?(:mb_chars)
19
+ text.mb_chars
20
+ elsif RUBY_VERSION < '1.9'
21
+ text.chars
22
+ else
23
+ text
24
+ end
25
+
26
+ omission = if options[:omission].respond_to?(:mb_chars)
27
+ options[:omission].mb_chars
28
+ elsif RUBY_VERSION < '1.9'
29
+ options[:omission].chars
30
+ else
31
+ options[:omission]
32
+ end
33
+
34
+ l = options[:length] - omission.length
35
+ if chars.length > options[:length]
36
+ result = (chars[/\A.{#{l}}\w*\;?/m][/.*[\w\;]/m]).to_s
37
+ ((options[:avoid_orphans] && result =~ /\A(.*?)\n+\W*\w*\W*\Z/m) ? $1 : result) + options[:omission]
38
+ else
39
+ text
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+ Capistrano::Configuration.instance.load do
2
+ namespace :db do
3
+ # this recipe needs the "mysql tasks" plugin
4
+ desc "Make a dump on the remote production box and restore on the local dev box"
5
+ task :dump_and_restore, :roles => :db, :only => {:primary => true} do
6
+ rake = fetch(:rake, "rake")
7
+ rails_env = fetch(:rails_env, "production")
8
+ file_env = ENV['FILE'] || "database"
9
+ run "cd #{current_release} && RAILS_ENV=#{rails_env} FILE=#{file_env} #{rake} db:backup"
10
+ get "#{current_release}/db/dump.tar.gz", "db/dump.tar.gz"
11
+ cmd = "RAILS_ENV=#{ ENV['RAILS_ENV'] || "development" } FILE=#{file_env} #{rake} db:restore"
12
+ puts cmd
13
+ system cmd
14
+ end
15
+ end
16
+
17
+ namespace :assets do
18
+ desc "Make a dump on the remote production box and restore on the local dev box"
19
+ task :dump_and_restore, :roles => :db, :only => {:primary => true} do
20
+ assets_backup_path = "#{current_path}/system.tar.gz"
21
+ run "cd #{current_path}/ && tar czfh #{assets_backup_path} public/system/"
22
+ get "#{assets_backup_path}", "system.tar.gz"
23
+ run "cd #{current_path}/ && rm #{assets_backup_path}"
24
+ `rm -rf public/system/*`
25
+ `tar xvzf system.tar.gz`
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,51 @@
1
+ Capistrano::Configuration.instance.load do
2
+ namespace :thinking_sphinx do
3
+ desc "Generate the Sphinx configuration file"
4
+ task :configure do
5
+ rake "thinking_sphinx:configure"
6
+ end
7
+
8
+ desc "Index data"
9
+ task :index do
10
+ rake "thinking_sphinx:index"
11
+ end
12
+
13
+ desc "Start the Sphinx daemon"
14
+ task :start do
15
+ configure
16
+ rake "thinking_sphinx:start"
17
+ end
18
+
19
+ desc "Stop the Sphinx daemon"
20
+ task :stop do
21
+ configure
22
+ rake "thinking_sphinx:stop"
23
+ end
24
+
25
+ desc "Stop and then start the Sphinx daemon"
26
+ task :restart do
27
+ stop
28
+ start
29
+ end
30
+
31
+ desc "Stop, re-index and then start the Sphinx daemon"
32
+ task :rebuild do
33
+ stop
34
+ index
35
+ start
36
+ end
37
+
38
+ desc "Add the shared folder for sphinx files for the production environment"
39
+ task :shared_sphinx_folder, :roles => :web do
40
+ run "mkdir -p #{shared_path}/db/sphinx/production"
41
+ end
42
+
43
+ def rake(*tasks)
44
+ rails_env = fetch(:rails_env, "production")
45
+ rake = fetch(:rake, "rake")
46
+ tasks.each do |t|
47
+ run "if [ -d #{release_path} ]; then cd #{release_path}; else cd #{current_path}; fi; #{rake} RAILS_ENV=#{rails_env} #{t}"
48
+ end
49
+ end
50
+ end
51
+ end
data/lib/tasks.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'rails'
2
+
3
+ module ProductionChain
4
+ class Railtie < Rails::Railtie
5
+ rake_tasks do
6
+ Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each { |file| load file }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,56 @@
1
+ require 's3'
2
+
3
+ namespace :s3 do
4
+
5
+ desc "Backup code, database, and scm to S3"
6
+ task :backup => ["s3:backup:db", "s3:backup:shared"]
7
+
8
+ namespace :backup do
9
+ desc "Backup the database to S3"
10
+ task :db do
11
+ db_tmp_path = "#{Rails.root}/db/dump.tar.gz"
12
+ Rake::Task['db:backup'].invoke
13
+ send_to_s3(db_tmp_path)
14
+ end
15
+
16
+ desc "Backup the shared folder to S3"
17
+ task :shared do
18
+ cmd = " cd .. && tar czfh /tmp/shared.tar.gz shared/ --exclude=shared/log/* --exclude=shared/sphinx/*"
19
+ system(cmd)
20
+ shared_tmp_path = "/tmp/shared.tar.gz"
21
+ send_to_s3(shared_tmp_path)
22
+ end
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def conn
29
+ @s3_config ||= YAML.load_file("#{Rails.root}/config/backup_s3.yml")[Rails.env]
30
+ @conn ||= S3::Service.new(:access_key_id => @s3_config['access_key_id'],
31
+ :secret_access_key => @s3_config['secret_access_key'],
32
+ :use_ssl => true)
33
+ end
34
+
35
+ def bucket_name
36
+ @s3_config['bucket_name']
37
+ end
38
+
39
+ def backup_bucket
40
+ begin
41
+ bucket ||= conn.buckets.find(bucket_name)
42
+ rescue S3::Error::ResponseError
43
+ bucket = conn.buckets.build(bucket_name)
44
+ bucket.save
45
+ end
46
+ bucket
47
+ end
48
+
49
+ def send_to_s3 local_file_path
50
+ bucket = backup_bucket
51
+ s3_file_path = Time.now.strftime("%Y%m%d") + '/' + local_file_path.split('/').last
52
+
53
+ upload = bucket.objects.build(s3_file_path)
54
+ upload.content = File.open(local_file_path)
55
+ upload.save
56
+ end
data/lib/tasks/db.rake ADDED
@@ -0,0 +1,133 @@
1
+ namespace :db do
2
+ desc "Dump schema and data to a bzip file"
3
+ task :backup => :environment do
4
+ type, database, user, password, host = retrieve_db_info ENV['FILE']
5
+ type = "mysql" if type == "mysql2"
6
+ send("backup_#{type}_database", database, user, password, host)
7
+ end
8
+
9
+ desc "Load schema and data from a bzip file"
10
+ task :restore => :environment do
11
+ type, database, user, password, host = retrieve_db_info ENV['FILE']
12
+ type = "mysql" if type == "mysql2"
13
+ if type == "mongodb"
14
+ send("restore_#{type}_database", database, user, password, host)
15
+ else
16
+ send("drop_#{type}_database", database, user, password, host)
17
+ send("create_#{type}_database", database, user, password, host)
18
+ send("restore_#{type}_database", database, user, password, host)
19
+
20
+ #Rake::Task['db:migrate'].invoke
21
+ end
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def retrieve_db_info(filename)
28
+ filename ||= "database"
29
+ result = File.read "#{Rails.root}/config/#{filename}.yml"
30
+ # result.strip!
31
+ config_file = YAML::load(ERB.new(result).result)
32
+ type = filename == "mongoid" ? "mongodb" : config_file[Rails.env]['adapter']
33
+ return [
34
+ type,
35
+ config_file[Rails.env]['database'],
36
+ config_file[Rails.env]['username'],
37
+ config_file[Rails.env]['password'],
38
+ config_file[Rails.env]['host'] || "127.0.0.1"
39
+ ]
40
+ end
41
+
42
+ def archive_name
43
+ archive = "#{Rails.root}/db/dump.tar.gz"
44
+ end
45
+
46
+ def backup_mysql_database database, user, password, host
47
+ cmd = "/usr/bin/env mysqldump --opt --skip-add-locks -h #{host} -u #{user} "
48
+ puts cmd + "... [password filtered]"
49
+ cmd << " -p'#{password}' " unless password.nil?
50
+ cmd << " #{database} > dump.sql && tar czfh #{archive_name} dump.sql"
51
+
52
+ system(cmd)
53
+ end
54
+
55
+ def restore_mysql_database database, user, password, host
56
+ cmd = "tar xvzf #{archive_name} && "
57
+ cmd << "/usr/bin/env mysql -h #{host} -u #{user} #{database}"
58
+ puts cmd + "... [password filtered]"
59
+ cmd << " -p'#{password}'" unless password.nil?
60
+ cmd << " < dump.sql"
61
+
62
+ system(cmd)
63
+ end
64
+
65
+ # pg_dump does not allow to pass the password in the command line for security reasons.
66
+ # You need to define the password for your user in ~/.pgpass
67
+ # See : http://www.postgresql.org/docs/8.1/interactive/libpq-pgpass.html
68
+ #
69
+ # pg_dump -Fc option outputs a custom dump file which is compressed by default.
70
+ # See man pg_dump for more information.
71
+ #
72
+ def backup_postgresql_database database, user, password, host
73
+ cmd = "/usr/bin/env pg_dump -Fc -h #{host} -U #{user} #{database} -f db.dump"
74
+ cmd << " && tar czfh #{archive_name} db.dump"
75
+ puts cmd
76
+
77
+ system(cmd)
78
+ end
79
+
80
+ def restore_postgresql_database database, user, password, host
81
+ cmd = "tar xvzf #{archive_name}"
82
+ cmd << " && /usr/bin/env pg_restore -h #{host} -U #{user} -O -d #{database} db.dump"
83
+ puts cmd
84
+
85
+ system(cmd)
86
+ end
87
+
88
+ def backup_mongodb_database database, user, password, host
89
+ cmd = "rm -rf dump/ 2>/dev/null && /usr/bin/env mongodump -h #{host} -d #{database}"
90
+ cmd << " && tar czfh #{archive_name} dump/"
91
+
92
+ system(cmd)
93
+ end
94
+
95
+ def restore_mongodb_database database, user, password, host
96
+ cmd = "rm -rf dump/ 2>/dev/null && tar xvzf #{archive_name}"
97
+ cmd += " && /usr/bin/env mongorestore --drop -h #{host} -d #{database} --dir dump/*_*"
98
+ puts cmd
99
+
100
+ system(cmd)
101
+ end
102
+
103
+ def drop_mysql_database database, user, password, host
104
+ cmd = "/usr/bin/env mysql -h #{host} -u #{user}"
105
+ cmd << " -e \"DROP DATABASE #{database}\""
106
+ puts cmd + "... [password filtered]"
107
+ cmd << " -p'#{password}'" unless password.nil?
108
+
109
+ system(cmd)
110
+ end
111
+
112
+ # We cannot use dropdb command as the rake task seems to lock the database...
113
+ #
114
+ def drop_postgresql_database database, user, password, host
115
+ Rake::Task['db:drop'].invoke
116
+ end
117
+
118
+ def create_postgresql_database database, user, password, host
119
+ cmd = "/usr/bin/env createdb -h #{host} -U #{user} #{database}"
120
+ puts cmd
121
+
122
+ system(cmd)
123
+ end
124
+
125
+ def create_mysql_database database, user, password, host
126
+ cmd = "/usr/bin/env mysql -h #{host} -u #{user}"
127
+ cmd << " -e \"CREATE DATABASE #{database}\""
128
+ puts cmd + "... [password filtered]"
129
+ cmd << " -p'#{password}'" unless password.nil?
130
+
131
+ system(cmd)
132
+ end
133
+
@@ -0,0 +1,13 @@
1
+ namespace :doc do
2
+ namespace :diagram do
3
+ task :models do
4
+ sh "railroad -i -l -a -m -M | dot -Tsvg | sed 's/font-size:14.00/font-size:11.00/g' > doc/models.svg"
5
+ end
6
+
7
+ task :controllers do
8
+ sh "railroad -i -l -C | neato -Tsvg | sed 's/font-size:14.00/font-size:11.00/g' > doc/controllers.svg"
9
+ end
10
+ end
11
+
12
+ task :diagrams => %w(diagram:models diagram:controllers)
13
+ end
@@ -0,0 +1,22 @@
1
+ namespace :env do
2
+ desc "reset your dev environment with default reference datas"
3
+ task :reset => :environment do
4
+ Rake::Task['db:drop'].invoke
5
+ Rake::Task['db:create'].invoke
6
+ Rake::Task['db:migrate'].invoke
7
+ Rake::Task['spec:db:fixtures:load'].invoke
8
+ end
9
+
10
+ desc "Rebuild with production data"
11
+ task :rebuild_with_production_data => :environment do
12
+ env = Rails.env
13
+ # Recreate database
14
+ `RAILS_ENV=#{env} rake db:drop db:create`
15
+ # Fetch database data
16
+ `RAILS_ENV=#{env} cap production db:dump_and_restore`
17
+ # Play migrations
18
+ `RAILS_ENV=#{env} rake db:migrate`
19
+ # Fetch assets
20
+ `RAILS_ENV=#{env} cap production assets:dump_and_restore`
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ namespace :mongo do
2
+ desc "Drops the database for the current RAILS_ENV"
3
+ task :drop => :environment do
4
+ MongoMapper.connection.drop_database(MongoMapper.database.name)
5
+ end
6
+
7
+ desc "Create the database defined in config/database.yml for the current RAILS_ENV"
8
+ task :seed => :environment do
9
+ Rake::Task["db:seed"].invoke
10
+ end
11
+
12
+ desc "Drops and recreates the database"
13
+ task :reset => :environment do
14
+ Rake::Task["mongo:drop"].invoke
15
+ Rake::Task["mongo:seed"].invoke
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ namespace :revision do
2
+ desc "print revision number in admin template"
3
+ task :print do
4
+ svn_revision = ENV['SVN_REVISION'] || IO.popen("svn info").readlines[4].split(" ").last
5
+ release_number = ENV['RELEASE_NUMBER'] || Dir.pwd.split("/").last
6
+ revision = RAILS_ENV
7
+ revision += "-r#{svn_revision}"
8
+ revision += "-#{release_number}" if release_number.to_i != 0
9
+
10
+ path = "app/views/shared/_revision.html.haml"
11
+ `echo "#{revision}" > #{path}`
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "production_chain"
3
+ s.version = "0.0.2"
4
+ s.platform = Gem::Platform::RUBY
5
+ s.authors = ["Novelys"]
6
+ s.email = ["contact@novelys.com"]
7
+ s.homepage = "http://github.com/novelys/production_chain"
8
+ s.summary = "Production Chain"
9
+ s.description = "A rails plugin that incorporate various libs, recipes and tasks"
10
+ s.rubyforge_project = s.name
11
+
12
+ s.required_rubygems_version = ">= 1.3.6"
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ # s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
16
+ # s.extensions = `git ls-files ext/extconf.rb`.split("\n")
17
+
18
+ s.require_path = 'lib'
19
+
20
+ # For C extensions
21
+ # s.extensions = "ext/extconf.rb"
22
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ Dir[File.join(File.dirname(__FILE__), '../lib/*.rb')].each { |file| load file }
2
+ require "core_ext/numeric"
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: production_chain
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
7
  - 0
9
- - 1
10
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
11
10
  platform: ruby
12
11
  authors:
13
12
  - Novelys
@@ -15,27 +14,13 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-08-19 00:00:00 +02:00
17
+ date: 2012-05-31 00:00:00 +02:00
19
18
  default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- name: aws
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 25
30
- segments:
31
- - 2
32
- - 3
33
- - 13
34
- version: 2.3.13
35
- type: :runtime
36
- version_requirements: *id001
37
- description: A rails plugin to setup a basic production chain (it also includes various libs, recipes and tasks)
38
- email: contact@novelys.com
19
+ dependencies: []
20
+
21
+ description: A rails plugin that incorporate various libs, recipes and tasks
22
+ email:
23
+ - contact@novelys.com
39
24
  executables: []
40
25
 
41
26
  extensions: []
@@ -43,7 +28,23 @@ extensions: []
43
28
  extra_rdoc_files: []
44
29
 
45
30
  files:
31
+ - .gitignore
46
32
  - README
33
+ - lib/core_ext/numeric.rb
34
+ - lib/production_chain.rb
35
+ - lib/rails/action_controller/abstract_request.rb
36
+ - lib/rails/action_view/text_helper.rb
37
+ - lib/recipes/dump_and_restore.rb
38
+ - lib/recipes/sphinx.rb
39
+ - lib/tasks.rb
40
+ - lib/tasks/backup.rake
41
+ - lib/tasks/db.rake
42
+ - lib/tasks/diagrams.rake
43
+ - lib/tasks/env.rake
44
+ - lib/tasks/mongo.rake
45
+ - lib/tasks/revision.rake
46
+ - production_chain.gemspec
47
+ - rails/init.rb
47
48
  has_rdoc: true
48
49
  homepage: http://github.com/novelys/production_chain
49
50
  licenses: []
@@ -54,29 +55,27 @@ rdoc_options: []
54
55
  require_paths:
55
56
  - lib
56
57
  required_ruby_version: !ruby/object:Gem::Requirement
57
- none: false
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- hash: 3
62
61
  segments:
63
62
  - 0
64
63
  version: "0"
65
64
  required_rubygems_version: !ruby/object:Gem::Requirement
66
- none: false
67
65
  requirements:
68
66
  - - ">="
69
67
  - !ruby/object:Gem::Version
70
- hash: 3
71
68
  segments:
72
- - 0
73
- version: "0"
69
+ - 1
70
+ - 3
71
+ - 6
72
+ version: 1.3.6
74
73
  requirements: []
75
74
 
76
- rubyforge_project:
77
- rubygems_version: 1.3.7
75
+ rubyforge_project: production_chain
76
+ rubygems_version: 1.3.6
78
77
  signing_key:
79
78
  specification_version: 3
80
- summary: Setup a basic production chain
79
+ summary: Production Chain
81
80
  test_files: []
82
81