visionbundles 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +8 -0
  3. data/README.md +24 -229
  4. data/Rakefile +12 -0
  5. data/lib/generators/install_generator.rb +42 -0
  6. data/lib/generators/security_generator.rb +44 -0
  7. data/lib/generators/templates/Capfile +3 -0
  8. data/lib/generators/templates/database.yml +26 -0
  9. data/lib/generators/templates/deploy_multiple.rb +59 -0
  10. data/lib/generators/templates/deploy_single.rb +49 -0
  11. data/lib/visionbundles.rb +2 -1
  12. data/lib/visionbundles/asset_sync.rb +4 -0
  13. data/lib/visionbundles/helpers.rb +2 -0
  14. data/lib/visionbundles/helpers/configuration.rb +41 -0
  15. data/lib/visionbundles/helpers/git.rb +10 -0
  16. data/lib/visionbundles/helpers/logger.rb +27 -0
  17. data/lib/visionbundles/helpers/recipes.rb +17 -0
  18. data/lib/visionbundles/helpers/servers.rb +32 -0
  19. data/lib/visionbundles/helpers/templates.rb +19 -0
  20. data/lib/visionbundles/rails.rb +7 -0
  21. data/lib/visionbundles/recipes/db.rb +20 -34
  22. data/lib/visionbundles/recipes/dev.rb +0 -2
  23. data/lib/visionbundles/recipes/fast_assets.rb +25 -3
  24. data/lib/visionbundles/recipes/nginx.rb +3 -1
  25. data/lib/visionbundles/recipes/preconfig.rb +69 -0
  26. data/lib/visionbundles/recipes/preconfig/helpers.rb +28 -0
  27. data/lib/visionbundles/recipes/puma.rb +7 -8
  28. data/lib/visionbundles/recipes/secret.rb +14 -37
  29. data/lib/visionbundles/recipes/valid.rb +52 -0
  30. data/lib/visionbundles/templates/puma/config.erb +9 -7
  31. data/lib/visionbundles/version.rb +1 -1
  32. data/todo.md +15 -0
  33. data/visionbundles.gemspec +3 -2
  34. metadata +38 -5
  35. data/lib/visionbundles/base.rb +0 -100
@@ -5,26 +5,25 @@ Capistrano::Configuration.instance(:must_exist).load do
5
5
  set_default(:puma_thread_min, 1)
6
6
  set_default(:puma_thread_max, 16)
7
7
  set_default(:puma_workers, 0)
8
+ set_default(:puma_config_template) { "../templates/puma/config.erb" }
9
+ set_default(:puma_preload_app) { false }
10
+ set_default(:puma_prune_bundler) { false }
11
+ set_default(:puma_worker_timeout) { nil }
12
+ set_default(:puma_on_boot_connection_to_activerecord) { nil }
8
13
 
9
14
  namespace :puma do
10
15
  desc "Setup Puma Scripts"
11
16
  task :setup, roles: :app do
12
17
  info '[Puma] copying the config'
13
- template "templates/puma/config.erb", "#{shared_path}/puma", "config.rb"
18
+ template puma_config_template, "#{shared_path}/puma", "config.rb"
14
19
  end
15
20
  after 'deploy:setup', 'puma:setup'
16
21
 
17
- %w[start stop].each do |command|
22
+ %w[start stop restart stats status phased-restart].each do |command|
18
23
  desc "#{command} puma server"
19
24
  task command, roles: :app do
20
25
  run "cd #{current_path} && RAILS_ENV=#{rails_env} bundle exec pumactl -F #{shared_path}/puma/config.rb #{command}"
21
26
  end
22
27
  end
23
- desc "restart puma server"
24
- task "restart", roles: :app do
25
- %w(stop start).each do |command|
26
- run "cd #{current_path} && RAILS_ENV=#{rails_env} bundle exec pumactl -F #{shared_path}/puma/config.rb #{command}"
27
- end
28
- end
29
28
  end
30
29
  end
@@ -1,38 +1,15 @@
1
1
  Capistrano::Configuration.instance(:must_exist).load do
2
-
3
- set_default(:secret_template, 'initializers/secret_token.production.rb')
4
-
5
- namespace :secret do
6
- desc 'copy production secret file from local'
7
- task :copy_production_config, roles: :app do
8
- info '[Template] Copy Secret Template'
9
- copy_production_from_local(secret_template, 'secret_token.rb')
10
- end
11
-
12
- desc "Setup secret file"
13
- task :setup, roles: :app do
14
- mkdir("#{shared_path}/config")
15
- secret_file_path = "#{shared_path}/config/secret_token.rb"
16
- template_secret_path = production_config('secret_token.rb')
17
- run_if_file_not_exists?(secret_file_path, "cp #{template_secret_path} #{secret_file_path}")
18
- end
19
- after 'deploy:setup', 'secret:copy_production_config', 'secret:setup'
20
-
21
- desc "setup secret file symlink for every time deploy"
22
- task :symlink, roles: :app do
23
- run "ln -nfs #{shared_path}/config/secret_token.rb #{release_path}/config/initializers/secret_token.rb"
24
- end
25
- after "deploy:finalize_update", "secret:symlink"
26
-
27
- desc "remove secret config file"
28
- task :remove_config, roles: [:app, :web] do
29
- run "rm #{shared_path}/config/secret_token.rb"
30
- end
31
-
32
- desc 'reset secret config file from local'
33
- task :reset_config do
34
- copy_production_config
35
- overwrite_config!('secret_token.rb')
36
- end
37
- end
38
- end
2
+ begin
3
+ require 'rails'
4
+ major, minor = Rails.gem_version.split(',').map(&:to_i)
5
+ if major == 4 && [0, 1].include?(minor)
6
+ source, desc = case minor
7
+ when 0 then; ['secret_token.rb', 'config/initializers/secret_token.rb']
8
+ when 1 then; ['secrets.yml', 'config/config/secrets.yml']
9
+ end
10
+ preconfig_files(source => desc)
11
+ else
12
+ raise 'Only support rails 4.1.x and 4.0.x'
13
+ end
14
+ rescue; end
15
+ end
@@ -0,0 +1,52 @@
1
+ require 'net/ssh/simple'
2
+
3
+ Capistrano::Configuration.instance(:must_exist).load do
4
+ namespace :deploy do
5
+ desc "validate settings"
6
+ task :valid, on_error: :continue do; end
7
+ end
8
+
9
+ namespace :valid do
10
+ desc 'check if server connection ok'
11
+ task :remote_server_connection, on_error: :continue do
12
+ # Servers connection
13
+ servers = {}
14
+ find_servers.each do |server|
15
+ connection = Net::SSH::Simple.async do
16
+ begin
17
+ ssh server.to_s, 'echo "test_connection"', user: user
18
+ rescue; end
19
+ end
20
+ servers[server.to_s] = connection.value
21
+ end
22
+
23
+ servers.each do |host, data|
24
+ if servers[host].nil?
25
+ valid_faild "Server: #{host} connection faild. please check firewall, ssh service and make sure public is in right place on your server."
26
+ else
27
+ valid_pass "Server: #{host} connection successful."
28
+ end
29
+ end
30
+ end
31
+
32
+ desc "Check remote servers have permission to access git server"
33
+ task :git_deploy_key_checker, on_error: :continue do
34
+ if scm == :git
35
+ find_servers.map { |server|
36
+ Thread.new {
37
+ host = server.to_s
38
+ # TODO: have to change a way to check response with git ls-remote (branch may named `denied`)
39
+ if capture("echo `git ls-remote #{repository} 2>&1`", hosts: host).strip.include?('denied')
40
+ valid_faild "Server: #{host} cannot access git repo: #{repository}"
41
+ else
42
+ valid_pass "Server: #{host} have git repo permission access."
43
+ end
44
+ }
45
+ }.each { |task| task.join }
46
+ else
47
+ valid_skip "skip valid if remote servers have git pull permission."
48
+ end
49
+ end
50
+ end
51
+ after 'deploy:valid', 'valid:remote_server_connection', 'valid:git_deploy_key_checker'
52
+ end
@@ -123,9 +123,11 @@ workers <%= puma_workers %>
123
123
  #
124
124
 
125
125
  on_worker_boot do
126
- ActiveSupport.on_load(:active_record) do
127
- ActiveRecord::Base.establish_connection
128
- end
126
+ <% if puma_preload_app && puma_on_boot_connection_to_activerecord %>
127
+ ActiveSupport.on_load(:active_record) do
128
+ ActiveRecord::Base.establish_connection
129
+ end
130
+ <% end %>
129
131
  end
130
132
 
131
133
  # Code to run when a worker boots to setup the process after booting
@@ -142,20 +144,20 @@ end
142
144
  # is preserved across a phased-restart. (incompatible with preload_app)
143
145
  # (off by default)
144
146
 
145
- # prune_bundler
147
+ <%= if puma_prune_bundler then 'prune_bundler' end %>
146
148
 
147
149
  # Preload the application before starting the workers; this conflicts with
148
150
  # phased restart feature. (off by default)
149
151
 
150
- preload_app!
152
+ <%= if puma_preload_app then 'preload_app!' end %>
151
153
 
152
154
  # Additional text to display in process listing
153
155
  #
154
- # tag 'gambling'
156
+ tag '<%= application %>'
155
157
 
156
158
  # Change the default timeout of workers
157
159
  #
158
- # worker_timeout 60
160
+ <%= if puma_worker_timeout then "worker_timeout #{puma_worker_timeout}" end %>
159
161
 
160
162
  # === Puma control rack application ===
161
163
 
@@ -1,3 +1,3 @@
1
1
  module Visionbundles
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/todo.md ADDED
@@ -0,0 +1,15 @@
1
+ 0.3.0
2
+
3
+ validation tasks
4
+
5
+ * servers connection
6
+ * security
7
+ * db access
8
+ * fast_assets
9
+ * git pull access
10
+
11
+ 0.3.1
12
+
13
+ * database validation when use socket file situational
14
+ * fast_assets CDN validation
15
+ * scp validation (should find a easy way to implement it)
@@ -6,8 +6,8 @@ Gem::Specification.new do |s|
6
6
  s.name = "visionbundles"
7
7
  s.version = Visionbundles::VERSION
8
8
  s.platform = Gem::Platform::RUBY
9
- s.summary = %q{common deploy flow tasks for capistrano 2.x.x}
10
- s.description = %q{nginx, puma, sidekiq, deploy flow}
9
+ s.summary = %q{Deploy recipes for capistrano 2.15.5}
10
+ s.description = %q{In this gem, there's some deploy recipes includes: nginx, puma, db, secret, fast_assets, and it also provide cdn, compile assets locally function}
11
11
 
12
12
  s.required_ruby_version = ">= 1.8.7"
13
13
  s.required_rubygems_version = ">= 1.3.6"
@@ -25,4 +25,5 @@ Gem::Specification.new do |s|
25
25
  s.add_dependency 'asset_sync', '~> 1.1.0'
26
26
  s.add_dependency 'fog', '~> 1.23.0'
27
27
  s.add_dependency 'colorize', '~> 0'
28
+ s.add_dependency 'net-ssh-simple', '~> 1.6.6'
28
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: visionbundles
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eddie Li
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-26 00:00:00.000000000 Z
11
+ date: 2014-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asset_sync
@@ -52,7 +52,22 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- description: nginx, puma, sidekiq, deploy flow
55
+ - !ruby/object:Gem::Dependency
56
+ name: net-ssh-simple
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.6.6
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.6.6
69
+ description: 'In this gem, there''s some deploy recipes includes: nginx, puma, db,
70
+ secret, fast_assets, and it also provide cdn, compile assets locally function'
56
71
  email:
57
72
  - eddie@visionbundles.com
58
73
  executables: []
@@ -60,22 +75,40 @@ extensions: []
60
75
  extra_rdoc_files: []
61
76
  files:
62
77
  - ".gitignore"
78
+ - CHANGELOG
63
79
  - Gemfile
64
80
  - README.md
65
81
  - Rakefile
82
+ - lib/generators/install_generator.rb
83
+ - lib/generators/security_generator.rb
84
+ - lib/generators/templates/Capfile
85
+ - lib/generators/templates/database.yml
86
+ - lib/generators/templates/deploy_multiple.rb
87
+ - lib/generators/templates/deploy_single.rb
66
88
  - lib/visionbundles.rb
67
89
  - lib/visionbundles/asset_sync.rb
68
- - lib/visionbundles/base.rb
90
+ - lib/visionbundles/helpers.rb
91
+ - lib/visionbundles/helpers/configuration.rb
92
+ - lib/visionbundles/helpers/git.rb
93
+ - lib/visionbundles/helpers/logger.rb
94
+ - lib/visionbundles/helpers/recipes.rb
95
+ - lib/visionbundles/helpers/servers.rb
96
+ - lib/visionbundles/helpers/templates.rb
97
+ - lib/visionbundles/rails.rb
69
98
  - lib/visionbundles/recipes/db.rb
70
99
  - lib/visionbundles/recipes/dev.rb
71
100
  - lib/visionbundles/recipes/fast_assets.rb
72
101
  - lib/visionbundles/recipes/nginx.rb
102
+ - lib/visionbundles/recipes/preconfig.rb
103
+ - lib/visionbundles/recipes/preconfig/helpers.rb
73
104
  - lib/visionbundles/recipes/puma.rb
74
105
  - lib/visionbundles/recipes/secret.rb
75
106
  - lib/visionbundles/recipes/sidekiq.rb
107
+ - lib/visionbundles/recipes/valid.rb
76
108
  - lib/visionbundles/templates/nginx/nginx.conf.erb
77
109
  - lib/visionbundles/templates/puma/config.erb
78
110
  - lib/visionbundles/version.rb
111
+ - todo.md
79
112
  - visionbundles.gemspec
80
113
  homepage: https://github.com/afunction/visionbundles
81
114
  licenses:
@@ -100,6 +133,6 @@ rubyforge_project:
100
133
  rubygems_version: 2.2.2
101
134
  signing_key:
102
135
  specification_version: 4
103
- summary: common deploy flow tasks for capistrano 2.x.x
136
+ summary: Deploy recipes for capistrano 2.15.5
104
137
  test_files: []
105
138
  has_rdoc:
@@ -1,100 +0,0 @@
1
- require 'erb'
2
- require 'colorize'
3
- require 'yaml' # STEP ONE, REQUIRE YAML!
4
- if defined?(Capistrano)
5
- def from_template(file)
6
- abs_path = File.join(File.dirname(__FILE__), file)
7
- template = File.read(abs_path)
8
- ERB.new(template).result(binding)
9
- end
10
-
11
- def template(erb_source, to_dir, filename)
12
- mkdir(to_dir)
13
- compiled_file = "#{to_dir}/#{filename}"
14
- put from_template(erb_source), compiled_file
15
- end
16
-
17
- def remote_file_exists?(path)
18
- results = []
19
-
20
- invoke_command("if [ -f '#{path}' ]; then echo -n 'true'; fi") do |ch, stream, out|
21
- results << (out == 'true')
22
- end
23
-
24
- !results.empty?
25
- end
26
-
27
- def run_if_file_exists?(path, command)
28
- run "if [ -f '#{path}' ]; then #{command}; fi"
29
- end
30
-
31
- def run_if_file_not_exists?(path, command)
32
- run "if [ ! -f '#{path}' ]; then #{command}; fi"
33
- end
34
-
35
- def mkdir(remote_path)
36
- run "mkdir -p #{remote_path}"
37
- end
38
-
39
- def include_recipes(*recipes)
40
- recipes.each do |recipe|
41
- require "#{File.dirname(__FILE__)}/recipes/#{recipe}.rb"
42
- end
43
- end
44
-
45
- def set_default(name, *args, &block)
46
- set(name, *args, &block) unless exists?(name)
47
- end
48
-
49
- def current_server
50
- capture("echo $CAPISTRANO:HOST$").strip
51
- end
52
-
53
- def info(message)
54
- puts "#{current_server} -> #{message}".to_s.colorize(:light_cyan)
55
- end
56
-
57
- def warn(message)
58
- puts "#{current_server} -> #{message}".to_s.colorize(:red)
59
- end
60
-
61
- def copy_production_from_local(local_file, remote_file)
62
- mkdir("#{shared_path}/template")
63
- remote_full_path = "#{shared_path}/template/#{remote_file}"
64
- put File.read("config/#{local_file}"), remote_full_path
65
-
66
- remote_full_path
67
- end
68
-
69
- def overwrite_config!(config_file)
70
- origin_config_path = production_config(config_file)
71
- replace_config_path = "#{shared_path}/config/#{config_file}"
72
- run "cp #{origin_config_path} #{replace_config_path}"
73
- end
74
-
75
- def production_config(config_file)
76
- "#{shared_path}/template/#{config_file}"
77
- end
78
-
79
- def have_primary_database?
80
- roles[:app].each do |server|
81
- if server.options[:primary]
82
- return true
83
- end
84
- end
85
- return false
86
- end
87
-
88
- def config_from_yaml(file_path, env)
89
- config = YAML::load_file("./#{file_path}")[env.to_s]
90
- config ||= {config: {}, servers: []}
91
- config['config'].each do |key, value|
92
- send(:set, key, value)
93
- end
94
- config['servers'].each do |server|
95
- roles = server['roles'].is_a?(Array) ? server['roles'].map(&:to_sym) : [ server['roles'].to_sym ]
96
- roles.push(server['opts']) if server['opts'].is_a?(Hash)
97
- send(:server, server['host'], *roles)
98
- end
99
- end
100
- end