capup 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.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/CHANGELOG.md +1 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +41 -0
  7. data/Rakefile +1 -0
  8. data/bin/capup +6 -0
  9. data/capup.gemspec +29 -0
  10. data/lib/capup.rb +0 -0
  11. data/lib/capup/all.rb +4 -0
  12. data/lib/capup/application.rb +0 -0
  13. data/lib/capup/capistrano/Capfile +2 -0
  14. data/lib/capup/capistrano/application.rb +18 -0
  15. data/lib/capup/capistrano/tasks/install.rake +65 -0
  16. data/lib/capup/capistrano/tasks/uninstall.rake +14 -0
  17. data/lib/capup/capistrano/templates/Capfile.erb +17 -0
  18. data/lib/capup/capistrano/templates/deploy.rb.erb +77 -0
  19. data/lib/capup/capistrano/templates/stage.rb.erb +50 -0
  20. data/lib/capup/fix.rb +1 -0
  21. data/lib/capup/fix/sshkit/pretty.rb +83 -0
  22. data/lib/capup/load_tasks.rb +2 -0
  23. data/lib/capup/sub_strings.rb +12 -0
  24. data/lib/capup/tasks/check_revision.cap +14 -0
  25. data/lib/capup/tasks/compile_assets_locally.cap +16 -0
  26. data/lib/capup/tasks/logs.cap +14 -0
  27. data/lib/capup/tasks/restart_unicorn.cap +8 -0
  28. data/lib/capup/tasks/run_tests.cap +18 -0
  29. data/lib/capup/tasks/setup_config.cap +34 -0
  30. data/lib/capup/tasks/try.cap +5 -0
  31. data/lib/capup/template.rb +41 -0
  32. data/lib/capup/templates/log_rotation.erb +11 -0
  33. data/lib/capup/templates/mongoid.example.yml.erb +69 -0
  34. data/lib/capup/templates/monit.erb +22 -0
  35. data/lib/capup/templates/nginx.conf.erb +55 -0
  36. data/lib/capup/templates/sidekiq.yml.erb +3 -0
  37. data/lib/capup/templates/sidekiq_init.sh.erb +40 -0
  38. data/lib/capup/templates/unicorn.rb.erb +35 -0
  39. data/lib/capup/templates/unicorn_init.sh.erb +86 -0
  40. data/lib/capup/version.rb +3 -0
  41. metadata +168 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 44a3c064ccfbc1a38bff0c5d5c6cb873f9de1dda
4
+ data.tar.gz: e48090690f98d6cd769dc13572aa57fa7fbf44f4
5
+ SHA512:
6
+ metadata.gz: eee5450d2c88a216ffe383b2922d3912bb4f8cefc85f28797a363395ba5c315e8e410bec813a84375f60bf7d288398a9839778d897a2ccfe7e318ec1c75afd3f
7
+ data.tar.gz: f26d00ac12cae413f70d2d6df3f9e17c899cf8978daba76853c504b23a0b1e9283247c7611e7965eacff817878d9772a2ee024c6f43e11f85ef9f2b7a3681546
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1 @@
1
+ * 20140125 Init
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://ruby.taobao.org'
2
+
3
+ # Specify your gem's dependencies in capup.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 cao7113
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,41 @@
1
+ # Capup
2
+
3
+ Cap v3 bootup with some fixes. This is a customization from http://www.talkingquickly.co.uk/2014/01/deploying-rails-apps-to-a-vps-with-capistrano-v3/ and forked from https://github.com/TalkingQuickly/capistrano-3-rails-template
4
+
5
+ Opinioned at bundler [ + rails ] + uwsgi
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'capup'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install capup
20
+
21
+ ## Usage
22
+
23
+ Init instead run: `cap install`, you run:
24
+
25
+ `capup install` (install plus/customization!)
26
+
27
+ also has:
28
+
29
+ `capup uninstall` #remove Capfile, config/deploy{,.rb}
30
+
31
+ Put this line into Capfile
32
+
33
+ require 'capup/all'
34
+
35
+ ## Contributing
36
+
37
+ 1. Fork it ( http://github.com/<my-github-username>/capup/fork )
38
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
39
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
40
+ 4. Push to the branch (`git push origin my-new-feature`)
41
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'capistrano/all'
4
+ require 'capup/capistrano/application'
5
+
6
+ Capistrano::Application.new.run
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'capup/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "capup"
8
+ spec.version = Capup::VERSION
9
+ spec.authors = ["cao7113"]
10
+ spec.email = ["cao7113@hotmail.com"]
11
+ spec.summary = %q{Capistrano extension for bootup.}
12
+ spec.description = spec.summary
13
+ spec.homepage = "http://github.com/cao7113/capup"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ #spec.add_dependency "capistrano-rbenv"
22
+ spec.add_dependency "capistrano-bundler"
23
+ spec.add_dependency "capistrano-rails"
24
+ spec.add_dependency "cap-uwsgi"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.5"
27
+ spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "gem-release"
29
+ end
File without changes
@@ -0,0 +1,4 @@
1
+ require 'capup/sub_strings'
2
+ require 'capup/template'
3
+ require "capup/fix"
4
+ require "capup/load_tasks"
File without changes
@@ -0,0 +1,2 @@
1
+ include Capistrano::DSL
2
+ Dir[File.join(File.dirname(__FILE__), 'tasks', '*.rake')].each{|t| load t}
@@ -0,0 +1,18 @@
1
+ #open class and monkey-patching
2
+ class Capistrano::Application
3
+
4
+ def initialize
5
+ super
6
+ #@rakefiles = %w{capfile Capfile capfile.rb Capfile.rb} << capfile
7
+ @rakefiles = [capfile]
8
+ end
9
+
10
+ # allows the `capup install` task to load without a capfile
11
+ def capfile
12
+ File.expand_path(File.join(File.dirname(__FILE__), 'Capfile'))
13
+ end
14
+
15
+ def default_tasks
16
+ %w{install uninstall}
17
+ end
18
+ end
@@ -0,0 +1,65 @@
1
+ require 'erb'
2
+ require 'pathname'
3
+ desc 'Install Capistrano, capup install STAGES=test,production'
4
+ task :install do
5
+ envs = ENV['STAGES'] || 'test,production,online'
6
+
7
+ tasks_dir = Pathname.new('lib/capistrano/tasks')
8
+ config_dir = Pathname.new('config')
9
+ deploy_dir = config_dir.join('deploy')
10
+
11
+ deploy_user = ENV['CAP_DEPLOY_USER']||ENV['DEPLOY_USER']||ENV['USER']||'deploy'
12
+ approot = Rake.original_dir||Dir.pwd
13
+ appname = ENV['CAP_APP_NAME']||ENV['APP_NAME']||File.basename(approot)
14
+ rails_appfile = File.join(approot, "config/application.rb")
15
+ is_rails = File.exist?(rails_appfile) && File.read(rails_appfile).include?("Rails::Application")
16
+ gemfile = File.join(approot, 'Gemfile')
17
+ has_gemfile = File.exist?(gemfile)
18
+ #write capup into Gemfile or manually? now just manualy!
19
+
20
+ deploy_rb = File.expand_path("../../templates/deploy.rb.erb", __FILE__)
21
+ stage_rb = File.expand_path("../../templates/stage.rb.erb", __FILE__)
22
+ #capfile = File.expand_path("../../templates/Capfile", __FILE__)
23
+ capfile = File.expand_path("../../templates/Capfile.erb", __FILE__)
24
+
25
+ mkdir_p deploy_dir
26
+
27
+ template = File.read(deploy_rb)
28
+ file = config_dir.join('deploy.rb')
29
+ File.open(file, 'w+') do |f|
30
+ f.write(ERB.new(template).result(binding))
31
+ puts I18n.t(:written_file, scope: :capistrano, file: file)
32
+ end
33
+
34
+ template = File.read(stage_rb)
35
+ envs.split(',').each do |stage|
36
+ file = deploy_dir.join("#{stage}.rb")
37
+ is_prod = stage == 'production'
38
+ File.open(file, 'w+') do |f|
39
+ f.write(ERB.new(template).result(binding))
40
+ puts I18n.t(:written_file, scope: :capistrano, file: file)
41
+ end
42
+ end
43
+
44
+ mkdir_p tasks_dir
45
+
46
+ #FileUtils.cp(capfile, 'Capfile')
47
+ template = File.read(capfile)
48
+ file = 'Capfile'
49
+ File.open(file, 'w+') do |f|
50
+ f.write(ERB.new(template).result(binding))
51
+ puts I18n.t(:written_file, scope: :capistrano, file: file)
52
+ end
53
+
54
+ File.open(gemfile, 'a') do |f|
55
+ f.puts <<-Doc
56
+
57
+ gem 'uwsgi'
58
+ group :development do
59
+ gem 'capup' #, github: 'cao7113/capup'
60
+ end
61
+ Doc
62
+ end
63
+
64
+ puts I18n.t :capified, scope: :capistrano
65
+ end
@@ -0,0 +1,14 @@
1
+ require 'fileutils'
2
+
3
+ def rmf_if_exist(path)
4
+ FileUtils.rm_r(path, secure: true, verbose: true) if File.exist?(path)
5
+ end
6
+
7
+ desc 'Uninstall Capistrano, capup uninstall'
8
+ task :uninstall do
9
+ approot = Rake.original_dir||Dir.pwd
10
+ rmf_if_exist File.join(approot, 'Capfile')
11
+ rmf_if_exist File.join(approot, 'config/deploy.rb')
12
+ rmf_if_exist File.join(approot, 'config/deploy')
13
+ puts "Uninstall cap files"
14
+ end
@@ -0,0 +1,17 @@
1
+ require 'capistrano/setup' # Load DSL and Setup Up Stages
2
+ require 'capistrano/deploy' # Includes default deployment tasks
3
+
4
+ # Includes tasks from gems in your Gemfile, eg: capistrano-rbenv, capistrano-bundler, capistrano-rails
5
+ #require 'capistrano/rbenv' # https://github.com/capistrano/rbenv, other: rvm, chruby
6
+ <%='#' unless has_gemfile %>require 'capistrano/bundler' # https://github.com/capistrano/bundler
7
+ <%='#' unless is_rails %>require 'capistrano/rails/assets' # https://github.com/capistrano/rails
8
+ <%='#' unless is_rails %>require 'capistrano/rails/migrations'
9
+
10
+ require 'capup/all'
11
+
12
+ require 'capistrano/uwsgi'
13
+ require 'capistrano/uwsgi/emperor'
14
+ require 'capistrano/uwsgi/nginx'
15
+
16
+ # Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
17
+ #Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
@@ -0,0 +1,77 @@
1
+ # config valid only for Capistrano 3.1
2
+ lock '<%= Capistrano::VERSION %>'
3
+
4
+ set :application, '<%=appname%>'
5
+ set :repo_url, File.expand_path("../../.git", __FILE__) #or set :repo_url, "git@shareup:<%=appname%>"
6
+
7
+ # Default branch is :master
8
+ #set :branch, :master #or ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }
9
+
10
+ # Default deploy_to directory is /var/www/my_app
11
+ set :deploy_to, File.expand_path('/apps/<%=appname%>')
12
+
13
+ # Default value for :scm is :git
14
+ set :scm, :git
15
+
16
+ # Default value for :format is :pretty
17
+ set :format, :pretty
18
+
19
+ # Default value for :log_level is :debug
20
+ #set :log_level, :debug
21
+
22
+ # Default value for :pty is false
23
+ # set :pty, true
24
+
25
+ # Default value for :linked_files is []
26
+ <%='#' unless is_rails%>set :linked_files, %w{config/database.yml}
27
+ <%='#' unless is_rails%>set :config_files, %w{database.yml.sample}
28
+
29
+ # Default value for linked_dirs is []
30
+ <%='#' unless is_rails%>set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
31
+
32
+ # Default value for default_env is {}
33
+ # set :default_env, { path: "<%=File.dirname(`which ruby`.chomp)%>:$PATH" }
34
+
35
+ #set :rbenv_custom_path, '<%=`rbenv root`.chomp%>' #eg. /opt/rbenv
36
+ #set :rbenv_ruby, '<%=`rbenv global`.chomp%>' #eg. '2.0.0-p353'
37
+
38
+ # Default value for keep_releases is 5
39
+ set :keep_releases, 3
40
+
41
+ namespace :deploy do
42
+
43
+ desc 'Restart application'
44
+ task :restart do
45
+ invoke "uwsgi:emperor:add"
46
+ #on roles(:app), in: :sequence, wait: 1 do
47
+ # # Your restart mechanism here, for example:
48
+ # # execute :touch, release_path.join('tmp/restart.txt')
49
+ #end
50
+ end
51
+
52
+ after :publishing, :restart
53
+
54
+ after :restart, :clear_cache do
55
+ on roles(:web), in: :groups, limit: 3, wait: 1 do
56
+ # Here we can do anything such as:
57
+ # within release_path do
58
+ # execute :rake, 'cache:clear'
59
+ # end
60
+ end
61
+ end
62
+
63
+ # this:
64
+ # http://www.capistranorb.com/documentation/getting-started/flow/
65
+ # is worth reading for a quick overview of what tasks are called
66
+ # and when for `cap stage deploy`
67
+
68
+ # make sure we're deploying what we think we're deploying
69
+ before :deploy, "deploy:check_revision"
70
+
71
+ # only allow a deploy with passing tests to deployed
72
+ # before :deploy, "deploy:run_tests"
73
+
74
+ # compile assets locally then rsync
75
+ # after 'deploy:symlink:shared', 'deploy:compile_assets_locally'
76
+ #before :publishing, :compile_assets_locally
77
+ end
@@ -0,0 +1,50 @@
1
+ # Simple Role Syntax
2
+ # ==================
3
+ # Supports bulk-adding hosts to roles, the primary
4
+ # server in each group is considered to be the first
5
+ # unless any hosts have the primary property set.
6
+ # Don't declare `role :all`, it's a meta role
7
+ #role :app, %w{<%=deploy_user%>@example.com}
8
+ #role :web, %w{<%=deploy_user%>@example.com}
9
+ #role :db, %w{<%=deploy_user%>@example.com}
10
+
11
+ <%if stage == 'online'%>
12
+ #Customize, override config/deploy.rb
13
+ set :repo_url, "https://github.com/cao7113/<%=appname%>.git"
14
+ set :deploy_to, File.expand_path('/apps/<%=appname%>')
15
+ set :rails_env, 'production'
16
+ <%else%>
17
+ ## Customize
18
+ set :deploy_to, File.expand_path('~/<%=is_prod ? "apps" : "tmp/#{stage}"%>/<%=appname%>')
19
+ <%end%>
20
+
21
+ # Extended Server Syntax
22
+ # ======================
23
+ # This can be used to drop a more detailed server
24
+ # definition into the server list. The second argument
25
+ # something that quacks like a hash can be used to set
26
+ # extended properties on the server.
27
+ server "<%=stage == 'online' ? 'ip_or_shareup.me' : 'localhost'%>", user: '<%=deploy_user%>', roles: %w{web app db} #, my_property: :my_value
28
+ #set :log_level, :<%=(fetch(:rails_env)||stage) == 'production' ? 'info' : 'debug'%>
29
+
30
+ # you can set custom ssh options
31
+ # it's possible to pass any option but you need to keep in mind that net/ssh understand limited list of options
32
+ # you can see them in [net/ssh documentation](http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start)
33
+ # set it globally
34
+ # set :ssh_options, {
35
+ # keys: %w(/home/rlisowski/.ssh/id_rsa),
36
+ # forward_agent: false,
37
+ # auth_methods: %w(password)
38
+ # }
39
+ # and/or per server
40
+ # server 'example.com',
41
+ # user: 'user_name',
42
+ # roles: %w{web app},
43
+ # ssh_options: {
44
+ # user: 'user_name', # overrides user setting above
45
+ # keys: %w(/home/user_name/.ssh/id_rsa),
46
+ # forward_agent: false,
47
+ # auth_methods: %w(publickey password)
48
+ # # password: 'please use keys'
49
+ # }
50
+ # setting per server overrides global ssh_options
@@ -0,0 +1 @@
1
+ require 'capup/fix/sshkit/pretty.rb'
@@ -0,0 +1,83 @@
1
+ require 'term/ansicolor'
2
+
3
+ module SSHKit
4
+
5
+ module Formatter
6
+
7
+ class Pretty < Abstract
8
+
9
+ def write(obj)
10
+ return if obj.verbosity < SSHKit.config.output_verbosity
11
+ case obj
12
+ when SSHKit::Command then write_command(obj)
13
+ when SSHKit::LogMessage then write_log_message(obj)
14
+ else
15
+ original_output << c.black(c.on_yellow("Output formatter doesn't know how to handle #{obj.class}\n"))
16
+ end
17
+ end
18
+ alias :<< :write
19
+
20
+ private
21
+
22
+ def write_command(command)
23
+ unless command.started?
24
+ original_output << level(command.verbosity) + uuid(command) + "Running #{c.yellow(c.bold(String(command)))} on #{c.blue(command.host.to_s)}\n"
25
+ if SSHKit.config.output_verbosity == Logger::DEBUG
26
+ original_output << level(Logger::DEBUG) + uuid(command) + "Command: #{c.blue(command.to_command)}" + "\n"
27
+ end
28
+ end
29
+
30
+ if SSHKit.config.output_verbosity == Logger::DEBUG
31
+ unless command.stdout.empty?
32
+ command.stdout.lines.each do |line|
33
+ #Fix 中文输出问题
34
+ original_output << level(Logger::DEBUG) + uuid(command) + c.green("\t" + line.force_encoding("utf-8"))
35
+ original_output << "\n" unless line[-1] == "\n"
36
+ end
37
+ end
38
+
39
+ unless command.stderr.empty?
40
+ command.stderr.lines.each do |line|
41
+ #Fix 中文输出问题
42
+ original_output << level(Logger::DEBUG) + uuid(command) + c.red("\t" + line.force_encoding("utf-8"))
43
+ original_output << "\n" unless line[-1] == "\n"
44
+ end
45
+ end
46
+ end
47
+
48
+ if command.finished?
49
+ original_output << level(command.verbosity) + uuid(command) + "Finished in #{sprintf('%5.3f seconds', command.runtime)} with exit status #{command.exit_status} (#{c.bold { command.failure? ? c.red('failed') : c.green('successful') }}).\n"
50
+ end
51
+ end
52
+
53
+ def write_log_message(log_message)
54
+ original_output << level(log_message.verbosity) + log_message.to_s + "\n"
55
+ end
56
+
57
+ def c
58
+ @c ||= Term::ANSIColor
59
+ end
60
+
61
+ def uuid(obj)
62
+ "[#{c.green(obj.uuid)}] "
63
+ end
64
+
65
+ def level(verbosity)
66
+ # Insane number here accounts for the control codes added
67
+ # by term-ansicolor
68
+ sprintf "%14s ", c.send(level_formatting(verbosity), level_names(verbosity))
69
+ end
70
+
71
+ def level_formatting(level_num)
72
+ %w{ black blue yellow red red }[level_num]
73
+ end
74
+
75
+ def level_names(level_num)
76
+ %w{ DEBUG INFO WARN ERROR FATAL }[level_num]
77
+ end
78
+
79
+ end
80
+
81
+ end
82
+
83
+ end
@@ -0,0 +1,2 @@
1
+ tasks_path = File.expand_path("../tasks", __FILE__)
2
+ Dir["#{tasks_path}/*.cap"].each{|cap| load cap}
@@ -0,0 +1,12 @@
1
+ # we often want to refer to variables which
2
+ # are defined in subsequent stage files. This
3
+ # let's us use the {{var}} to represent fetch(:var)
4
+ # in strings which are only evaluated at runtime.
5
+
6
+ def sub_strings(input_string)
7
+ output_string = input_string
8
+ input_string.scan(/{{(\w*)}}/).each do |var|
9
+ output_string.gsub!("{{#{var[0]}}}", fetch(var[0].to_sym))
10
+ end
11
+ output_string
12
+ end
@@ -0,0 +1,14 @@
1
+ namespace :deploy do
2
+ desc "checks whether the currently checkout out revision matches the
3
+ remote one we're trying to deploy from"
4
+ task :check_revision do
5
+ branch = fetch(:branch)
6
+ unless `git rev-parse HEAD` == `git rev-parse origin/#{branch}`
7
+ puts "WARNING: HEAD is not the same as origin/#{branch}"
8
+ puts "Run `git push` to sync changes or make sure you've"
9
+ puts "checked out the branch: #{branch} as you can only deploy"
10
+ puts "if you've got the target branch checked out"
11
+ exit
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ namespace :deploy do
2
+ desc "compiles assets locally then rsyncs"
3
+ task :compile_assets_locally do
4
+ run_locally do
5
+ execute "bundle exec rake assets:precompile"
6
+ end
7
+ on roles(:app) do |role|
8
+ run_locally do
9
+ execute "rsync -av ./public/assets/ #{role.user}@#{role.hostname}:#{release_path}/public/assets/;"
10
+ end
11
+ end
12
+ run_locally do
13
+ execute "rm -rf ./public/assets"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ namespace :logs do
2
+ task :tail, :file do |t, args|
3
+ if args[:file]
4
+ on roles(:app) do
5
+ execute "tail -f #{shared_path}/log/#{args[:file]}.log"
6
+ end
7
+ else
8
+ puts "please specify a logfile e.g: 'rake logs:tail[logfile]"
9
+ puts "will tail 'shared_path/log/logfile.log'"
10
+ puts "remember if you use zsh you'll need to format it as:"
11
+ puts "rake 'logs:tail[logfile]' (single quotes)"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ namespace :deploy do
2
+ desc 'Restart unicorn application'
3
+ task :restart_unicorn do
4
+ on roles(:app), in: :sequence, wait: 5 do
5
+ sudo "/etc/init.d/unicorn_#{fetch(:full_app_name)} restart"
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ namespace :deploy do
2
+ desc "Runs test before deploying, can't deploy unless they pass"
3
+ task :run_tests do
4
+ test_log = "log/capistrano.test.log"
5
+ tests = fetch(:tests)
6
+ tests.each do |test|
7
+ puts "--> Running tests: '#{test}', please wait ..."
8
+ unless system "bundle exec rspec #{test} > #{test_log} 2>&1"
9
+ puts "--> Tests: '#{test}' failed. Results in: #{test_log} and below:"
10
+ system "cat #{test_log}"
11
+ exit;
12
+ end
13
+ puts "--> '#{test}' passed"
14
+ end
15
+ puts "--> All tests passed"
16
+ system "rm #{test_log}"
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ namespace :deploy do
2
+ desc "Upload config sample files to server"
3
+ task :setup_config do
4
+ on roles(:app) do
5
+ # make the config dir
6
+ execute :mkdir, "-p #{shared_path}/config"
7
+ full_app_name = fetch(:full_app_name)
8
+
9
+ # config files to be uploaded to shared/config, see the
10
+ # definition of smart_template for details of operation.
11
+ # Essentially looks for #{filename}.erb in deploy/#{full_app_name}/
12
+ # and if it isn't there, falls back to deploy/#{shared}. Generally
13
+ # everything should be in deploy/shared with params which differ
14
+ # set in the stage files
15
+ config_files = fetch(:config_files)
16
+ config_files.each do |file|
17
+ smart_template file
18
+ end if config_files
19
+
20
+ # which of the above files should be marked as executable
21
+ executable_files = fetch(:executable_config_files)
22
+ executable_files.each do |file|
23
+ execute :chmod, "+x #{shared_path}/config/#{file}"
24
+ end if executable_files
25
+
26
+ # symlink stuff which should be... symlinked
27
+ symlinks = fetch(:symlinks)
28
+
29
+ symlinks.each do |symlink|
30
+ sudo "ln -nfs #{shared_path}/config/#{symlink[:source]} #{sub_strings(symlink[:link])}"
31
+ end if symlinks
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,5 @@
1
+ namespace :deploy do
2
+ task :try do
3
+ puts "====try deploy from capup gem"
4
+ end
5
+ end
@@ -0,0 +1,41 @@
1
+ # will first try and copy the file:
2
+ # config/deploy/#{full_app_name}/#{from}.erb
3
+ # to:
4
+ # shared/config/to
5
+ # if the original source path doesn exist then it will
6
+ # search in:
7
+ # config/deploy/shared/#{from}.erb
8
+ # this allows files which are common to all enviros to
9
+ # come from a single source while allowing specific
10
+ # ones to be over-ridden
11
+ # if the target file name is the same as the source then
12
+ # the second parameter can be left out
13
+ def smart_template(from, to=nil)
14
+ to ||= from
15
+ full_to_path = "#{shared_path}/config/#{to.sub(/\.sample$/, '')}"
16
+ if from_erb_path = template_file(from)
17
+ from_erb = StringIO.new(ERB.new(File.read(from_erb_path)).result(binding))
18
+ upload! from_erb, full_to_path
19
+ info "copying: #{from_erb_path} to: #{full_to_path}"
20
+ else
21
+ error "error #{from} not found"
22
+ end
23
+ end
24
+
25
+ #find a template file in order.
26
+ def template_file(name)
27
+ app_root = Dir.pwd #may use Rake.application.original_dir
28
+ unless File.exist?(File.join(app_root, 'Capfile'))
29
+ raise "Assume run in app root(there exists a Capfile), but now in #{app_root}!"
30
+ end
31
+ items = []
32
+ items << "#{app_root}/config/#{name}"
33
+ items << "#{app_root}/config/deploy/#{fetch(:stage)}/#{name}.erb"
34
+ items << "#{app_root}/config/deploy/shared/#{name}.erb"
35
+ tmpl_path = File.join(File.dirname(__FILE__), "templates")
36
+ items << "#{tmpl_path}/#{name}.erb"
37
+ items.each do |f|
38
+ return f if File.exist?(f)
39
+ end
40
+ nil
41
+ end
@@ -0,0 +1,11 @@
1
+ <%= fetch(:deploy_to) %>/shared/log/*.log {
2
+ daily
3
+ missingok
4
+ rotate 52
5
+ compress
6
+ delaycompress
7
+ notifempty
8
+ sharedscripts
9
+ endscript
10
+ copytruncate
11
+ }
@@ -0,0 +1,69 @@
1
+ <%= fetch(:rails_env) %>:
2
+ # Configure available database sessions. (required)
3
+ sessions:
4
+ # Defines the default session. (required)
5
+ default:
6
+ # Defines the name of the default database that Mongoid can connect to.
7
+ # (required).
8
+ database: <%= "#{fetch(:applocation)}_#{fetch(:rails_env)}" %>
9
+ # Provides the hosts the default session can connect to. Must be an array
10
+ # of host:port pairs. (required)
11
+ hosts:
12
+ - localhost
13
+ options:
14
+ # Change whether the session persists in safe mode by default.
15
+ # (default: false)
16
+ safe: true
17
+
18
+ # Change the default consistency model to :eventual or :strong.
19
+ # :eventual will send reads to secondaries, :strong sends everything
20
+ # to master. (default: :eventual)
21
+ # consistency: :eventual
22
+
23
+ # How many times Moped should attempt to retry an operation after
24
+ # failure. (default: 30)
25
+ # max_retries: 30
26
+
27
+ # The time in seconds that Moped should wait before retrying an
28
+ # operation on failure. (default: 1)
29
+ # retry_interval: 1
30
+ # Configure Mongoid specific options. (optional)
31
+ options:
32
+ # Configuration for whether or not to allow access to fields that do
33
+ # not have a field definition on the model. (default: true)
34
+ # allow_dynamic_fields: true
35
+
36
+ # Enable the identity map, needed for eager loading. (default: false)
37
+ identity_map_enabled: true
38
+
39
+ # Includes the root model name in json serialization. (default: false)
40
+ # include_root_in_json: false
41
+
42
+ # Include the _type field in serializaion. (default: false)
43
+ # include_type_for_serialization: false
44
+
45
+ # Preload all models in development, needed when models use
46
+ # inheritance. (default: false)
47
+ # preload_models: false
48
+
49
+ # Protect id and type from mass assignment. (default: true)
50
+ # protect_sensitive_fields: true
51
+
52
+ # Raise an error when performing a #find and the document is not found.
53
+ # (default: true)
54
+ # raise_not_found_error: true
55
+
56
+ # Raise an error when defining a scope with the same name as an
57
+ # existing method. (default: false)
58
+ # scope_overwrite_exception: false
59
+
60
+ # Skip the database version check, used when connecting to a db without
61
+ # admin access. (default: false)
62
+ # skip_version_check: false
63
+
64
+ # User Active Support's time zone in conversions. (default: true)
65
+
66
+ # Ensure all times are UTC in the app side. (default: false)
67
+ use_utc: true
68
+
69
+
@@ -0,0 +1,22 @@
1
+ <% application = fetch(:application) %>
2
+ set mail-format { subject: <%= "#{fetch(:full_app_name)} - #{fetch(:rails_env)}" %> $SERVICE $EVENT at $DATE }
3
+
4
+ check process unicorn
5
+ with pidfile <%= current_path %>/tmp/pids/unicorn.pid
6
+ start program = "/etc/init.d/unicorn_<%= application %>_<%= fetch(:rails_env)%> start"
7
+ stop program = "/etc/init.d/unicorn_<%= application %>_<%= fetch(:rails_env)%> stop"
8
+ if mem is greater than 300.0 MB for 1 cycles then restart # eating up memory?
9
+ if cpu is greater than 50% for 2 cycles then alert # send an email to admin
10
+ if cpu is greater than 80% for 30 cycles then restart # hung process?
11
+ group unicorn
12
+
13
+ <% (0..(fetch(:unicorn_worker_count) -1)).each do |worker| %>
14
+ check process unicorn_worker_<%= (5000 + worker).to_s %>
15
+ with pidfile <%= current_path %>/tmp/pids/unicorn.<%= (5000 + worker).to_s %>.pid
16
+ start program = "/bin/true"
17
+ stop program = "/etc/init.d/unicorn_<%= application %>_<%= fetch(:rails_env)%> kill_worker <%= (5000 + worker).to_s %>"
18
+ if mem is greater than 350.0 MB for 1 cycles then restart
19
+ if cpu is greater than 80% for 30 cycles then restart
20
+
21
+ group unicorn_workers
22
+ <% end %>
@@ -0,0 +1,55 @@
1
+ upstream unicorn {
2
+ server unix:/tmp/unicorn.<%= fetch(:full_app_name) %>.sock fail_timeout=0;
3
+ }
4
+
5
+ server {
6
+ listen 80 default deferred;
7
+ root <%= fetch(:deploy_to) %>/current/public;
8
+
9
+ location ^~ /assets/ {
10
+ gzip_static on;
11
+ expires max;
12
+ add_header Cache-Control public;
13
+ }
14
+
15
+ try_files $uri/index.html $uri @unicorn;
16
+ location @unicorn {
17
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
18
+ proxy_set_header Host $http_host;
19
+ proxy_redirect off;
20
+ proxy_pass http://unicorn;
21
+ }
22
+
23
+ error_page 500 502 503 504 /500.html;
24
+ client_max_body_size 4G;
25
+ keepalive_timeout 10;
26
+ }
27
+
28
+ <% if fetch(:enable_ssl) %>
29
+ server {
30
+ listen 443 default deferred;
31
+ root <%= fetch(:deploy_to) %>/current/public;
32
+
33
+ location ^~ /assets/ {
34
+ gzip_static on;
35
+ expires max;
36
+ add_header Cache-Control public;
37
+ }
38
+
39
+ try_files $uri/index.html $uri @unicorn;
40
+ location @unicorn {
41
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
42
+ proxy_set_header X-Forwarded-Proto https;
43
+ proxy_set_header Host $http_host;
44
+ proxy_redirect off;
45
+ proxy_pass http://unicorn;
46
+ }
47
+
48
+ error_page 500 502 503 504 /500.html;
49
+ client_max_body_size 4G;
50
+ keepalive_timeout 10;
51
+ ssl on;
52
+ ssl_certificate <%= fetch(:deploy_to) %>/shared/ssl_cert.crt;
53
+ ssl_certificate_key <%= fetch(:deploy_to) %>/shared/ssl_private_key.key;
54
+ }#
55
+ <% end %>
@@ -0,0 +1,3 @@
1
+ concurrency: 5
2
+ <%= fetch(:rails_env) %>:
3
+ pidfile: tmp/pids/sidekiq.pid
@@ -0,0 +1,40 @@
1
+ #!/bin/sh
2
+ set -e
3
+
4
+ APP_ROOT=<%= current_path %>
5
+ PID=$APP_ROOT/tmp/pids/sidekiq.pid
6
+ CMD="cd $APP_ROOT; RAILS_ENV=<%= "#{fetch(:rails_env)}" %> nohup bundle exec sidekiq -e <%= "#{fetch(:rails_env)}" %> -C <%= current_path %>/config/sidekiq.yml -i 0 -P $PID >> <%= current_path %>/log/sidekiq.log 2>&1 &"
7
+ AS_USER="deploy"
8
+
9
+ run () {
10
+ if [ "$(id -un)" = "$AS_USER" ]; then
11
+ eval $1
12
+ else
13
+ su -c "$1" - $AS_USER
14
+ fi
15
+ }
16
+
17
+ sig () {
18
+ test -s "$PID" && kill -$1 `cat $PID`
19
+ }
20
+
21
+ case "$1" in
22
+ start)
23
+ sig 0 && echo >&2 "Already Running" && exit 0
24
+ run "$CMD"
25
+ ;;
26
+ stop)
27
+ if kill -0 `cat $PID`
28
+ then
29
+ cd $APP_ROOT
30
+ bundle exec sidekiqctl stop $APP_ROOT/tmp/pids/sidekiq.pid 10
31
+ echo "stopping...."
32
+ else
33
+ echo "not running"
34
+ fi
35
+ ;;
36
+ *)
37
+ echo >&2 "Usage: $0 <start|stop>"
38
+ exit 1
39
+ ;;
40
+ esac
@@ -0,0 +1,35 @@
1
+ root = "<%= current_path %>"
2
+ working_directory root
3
+ pid "#{root}/tmp/pids/unicorn.pid"
4
+ stderr_path "#{root}/log/unicorn.log"
5
+ stdout_path "#{root}/log/unicorn.log"
6
+
7
+ listen "/tmp/unicorn.<%= fetch(:full_app_name) %>.sock"
8
+ worker_processes <%= fetch(:unicorn_worker_count) %>
9
+ timeout 40
10
+ preload_app true
11
+
12
+ before_fork do |server, worker|
13
+ defined?(ActiveRecord::Base) and
14
+ ActiveRecord::Base.connection.disconnect!
15
+ # Quit the old unicorn process
16
+ old_pid = "#{server.config[:pid]}.oldbin"
17
+ if File.exists?(old_pid) && server.pid != old_pid
18
+ puts "We've got an old pid and server pid is not the old pid"
19
+ begin
20
+ Process.kill("QUIT", File.read(old_pid).to_i)
21
+ puts "killing master process (good thing tm)"
22
+ rescue Errno::ENOENT, Errno::ESRCH
23
+ puts "unicorn master already killed"
24
+ # someone else did our job for us
25
+ end
26
+ end
27
+ end
28
+
29
+ after_fork do |server, worker|
30
+ port = 5000 + worker.nr
31
+ child_pid = server.config[:pid].sub('.pid', ".#{port}.pid")
32
+ system("echo #{Process.pid} > #{child_pid}")
33
+ defined?(ActiveRecord::Base) and
34
+ ActiveRecord::Base.establish_connection
35
+ end
@@ -0,0 +1,86 @@
1
+ #!/bin/sh
2
+ set -e
3
+
4
+ # Feel free to change any of the following variables for your app:
5
+ TIMEOUT=${TIMEOUT-60}
6
+ APP_ROOT=<%= current_path %>
7
+ PID_DIR=$APP_ROOT/tmp/pids
8
+ PID=$PID_DIR/unicorn.pid
9
+ CMD="cd $APP_ROOT; bundle exec unicorn -D -c <%= "#{shared_path}/config/unicorn.rb" %> -E <%= fetch(:rails_env) %>"
10
+ AS_USER=deploy
11
+ set -u
12
+
13
+ OLD_PIN="$PID.oldbin"
14
+
15
+ sig () {
16
+ test -s "$PID" && kill -$1 `cat $PID`
17
+ }
18
+
19
+ oldsig () {
20
+ test -s $OLD_PIN && kill -$1 `cat $OLD_PIN`
21
+ }
22
+
23
+ workersig () {
24
+ workerpid="$APP_ROOT/tmp/pids/unicorn.$2.pid"
25
+
26
+ test -s "$workerpid" && kill -$1 `cat $workerpid`
27
+ }
28
+
29
+ run () {
30
+ if [ "$(id -un)" = "$AS_USER" ]; then
31
+ eval $1
32
+ else
33
+ su -c "$1" - $AS_USER
34
+ fi
35
+ }
36
+
37
+ case "$1" in
38
+ start)
39
+ sig 0 && echo >&2 "Already running" && exit 0
40
+ run "$CMD"
41
+ ;;
42
+ stop)
43
+ sig QUIT && exit 0
44
+ echo >&2 "Not running"
45
+ ;;
46
+ force-stop)
47
+ sig TERM && exit 0
48
+ echo >&2 "Not running"
49
+ ;;
50
+ kill_worker)
51
+ workersig QUIT $2 && exit 0
52
+ echo >&2 "Worker not running"
53
+ ;;
54
+ restart|reload)
55
+ sig USR2 && echo reloaded OK && exit 0
56
+ echo >&2 "Couldn't reload, starting '$CMD' instead"
57
+ run "$CMD"
58
+ ;;
59
+ upgrade)
60
+ if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
61
+ then
62
+ n=$TIMEOUT
63
+ while test -s $OLD_PIN && test $n -ge 0
64
+ do
65
+ printf '.' && sleep 1 && n=$(( $n - 1 ))
66
+ done
67
+ echo
68
+
69
+ if test $n -lt 0 && test -s $OLD_PIN
70
+ then
71
+ echo >&2 "$OLD_PIN still exists after $TIMEOUT seconds"
72
+ exit 1
73
+ fi
74
+ exit 0
75
+ fi
76
+ echo >&2 "Couldn't upgrade, starting '$CMD' instead"
77
+ run "$CMD"
78
+ ;;
79
+ reopen-logs)
80
+ sig USR1
81
+ ;;
82
+ *)
83
+ echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
84
+ exit 1
85
+ ;;
86
+ esac
@@ -0,0 +1,3 @@
1
+ module Capup
2
+ VERSION = "0.0.2"
3
+ end
metadata ADDED
@@ -0,0 +1,168 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capup
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - cao7113
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano-bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: capistrano-rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: cap-uwsgi
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.5'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.5'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: gem-release
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Capistrano extension for bootup.
98
+ email:
99
+ - cao7113@hotmail.com
100
+ executables:
101
+ - capup
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - .gitignore
106
+ - CHANGELOG.md
107
+ - Gemfile
108
+ - LICENSE.txt
109
+ - README.md
110
+ - Rakefile
111
+ - bin/capup
112
+ - capup.gemspec
113
+ - lib/capup.rb
114
+ - lib/capup/all.rb
115
+ - lib/capup/application.rb
116
+ - lib/capup/capistrano/Capfile
117
+ - lib/capup/capistrano/application.rb
118
+ - lib/capup/capistrano/tasks/install.rake
119
+ - lib/capup/capistrano/tasks/uninstall.rake
120
+ - lib/capup/capistrano/templates/Capfile.erb
121
+ - lib/capup/capistrano/templates/deploy.rb.erb
122
+ - lib/capup/capistrano/templates/stage.rb.erb
123
+ - lib/capup/fix.rb
124
+ - lib/capup/fix/sshkit/pretty.rb
125
+ - lib/capup/load_tasks.rb
126
+ - lib/capup/sub_strings.rb
127
+ - lib/capup/tasks/check_revision.cap
128
+ - lib/capup/tasks/compile_assets_locally.cap
129
+ - lib/capup/tasks/logs.cap
130
+ - lib/capup/tasks/restart_unicorn.cap
131
+ - lib/capup/tasks/run_tests.cap
132
+ - lib/capup/tasks/setup_config.cap
133
+ - lib/capup/tasks/try.cap
134
+ - lib/capup/template.rb
135
+ - lib/capup/templates/log_rotation.erb
136
+ - lib/capup/templates/mongoid.example.yml.erb
137
+ - lib/capup/templates/monit.erb
138
+ - lib/capup/templates/nginx.conf.erb
139
+ - lib/capup/templates/sidekiq.yml.erb
140
+ - lib/capup/templates/sidekiq_init.sh.erb
141
+ - lib/capup/templates/unicorn.rb.erb
142
+ - lib/capup/templates/unicorn_init.sh.erb
143
+ - lib/capup/version.rb
144
+ homepage: http://github.com/cao7113/capup
145
+ licenses:
146
+ - MIT
147
+ metadata: {}
148
+ post_install_message:
149
+ rdoc_options: []
150
+ require_paths:
151
+ - lib
152
+ required_ruby_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - '>='
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ required_rubygems_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - '>='
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ requirements: []
163
+ rubyforge_project:
164
+ rubygems_version: 2.0.14
165
+ signing_key:
166
+ specification_version: 4
167
+ summary: Capistrano extension for bootup.
168
+ test_files: []