visionbundles 0.2.0 → 0.3.0

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.
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