deployable 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in deployable.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "deployable/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "deployable"
7
+ s.version = Deployable::VERSION
8
+ s.authors = ["Digitpaint", "Flurin Egger"]
9
+ s.email = ["info@digitpaint.nl", "flurin@digitpaint.nl"]
10
+ s.homepage = ""
11
+ s.summary = %q{A collection of handy capistrano deploy recipes}
12
+ s.description = s.summary
13
+
14
+ s.rubyforge_project = "deployable"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
File without changes
File without changes
File without changes
@@ -0,0 +1,190 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # chkconfig: - 85 15
4
+ # description: Passenger Standalone
5
+ require 'yaml'
6
+ require 'pathname'
7
+
8
+ # The user the applications run as.
9
+ USER = "admin"
10
+ USER_HOME_PATH = File.expand_path("~#{USER}")
11
+ RVM_PATH = USER_HOME_PATH + "/.rvm/"
12
+
13
+ # The place where all your applications reside. This scripts assumes that
14
+ # you have the following structure in your APPLICATIONS_PATH:
15
+ # APPLICATIONS_PATH
16
+ # |- APPLICATION_NAME
17
+ # |- STAGE
18
+ # |- server.yml (REQUIRED)
19
+ # |- current
20
+ APPLICATIONS_PATH = USER_HOME_PATH + "/applications/"
21
+
22
+ # Example :Server.yml
23
+ #
24
+ # passenger:
25
+ # port: 10001 # The port number passenger standalone will be ran on
26
+ # rvm:
27
+ # rvm_ruby_string: "rubyversion@gemsetname" # The ruby version and gemset RVM will use
28
+ # callbacks: # All callbacks are optional and are references to scripts relative to APPLICATIONS_PATH/APPLICATION_NAME/STAGE
29
+ # start:
30
+ # before: # Ran before passenger has started
31
+ # after: # Ran after passenger has started
32
+ # stop:
33
+ # before: # Ran before passenger has been stopped
34
+ # after: # Ran after passenger has been stopped
35
+
36
+ # ======================================================
37
+ # Shouldn't be necessary to change stuff below this line
38
+ # ======================================================
39
+
40
+ # Main start routine.
41
+ def run!
42
+ command = ARGV.first
43
+ available_commands = %w{start stop list}
44
+ raise "Use one of #{available_commands.join("|")} as first argument" unless available_commands.include?(command)
45
+
46
+ applications = Dir.glob("#{APPLICATIONS_PATH}*/*").inject({}){|mem, dir| parts = dir.split("/"); mem[parts[-2]] ||= []; mem[parts[-2]] << parts[-1]; mem}
47
+
48
+ if command == "list"
49
+ str = "All applications for #{USER}"
50
+ puts str
51
+ puts "=" * str.size
52
+
53
+ applications.each do |application, stages|
54
+ puts "#{application} (#{APPLICATIONS_PATH}/#{application})"
55
+ stages.each do |stage|
56
+ puts " - #{stage}"
57
+ end
58
+ end
59
+ else
60
+ if application = ARGV[1]
61
+ unless applications.has_key?(application)
62
+ raise "Can't find application #{application}"
63
+ end
64
+
65
+ if stage = ARGV[2]
66
+ unless applications[application].include?(stage)
67
+ raise "Stage #{stage} not found for application #{application}"
68
+ end
69
+ Application.new(application,stage).start_or_stop!(command)
70
+ else
71
+ applications[application].each do |stage|
72
+ Application.new(application,stage).start_or_stop!(command)
73
+ end
74
+ end
75
+ else
76
+ applications.each do |application, stages|
77
+ stages.each do |stage|
78
+ Application.new(application,stage).start_or_stop!(command)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ true
84
+ end
85
+
86
+ # Wrapper class to handle application specific start and stop methods
87
+ # including callbacks
88
+ class Application
89
+
90
+ attr_reader :config, :path, :name, :stage
91
+
92
+ def initialize(application_name,stage)
93
+ @path = Pathname.new("#{APPLICATIONS_PATH}#{application_name}/#{stage}")
94
+ @name = application_name
95
+ @stage = start_or_stop
96
+
97
+ # Sanity check!
98
+ raise "No server.yml found in '#{@path}'" unless File.exist?(@path +"server.yml")
99
+
100
+ # Load config
101
+ @config = YAML.load(File.read((@path +"server.yml").to_s))
102
+ end
103
+
104
+ def start_or_stop!(command)
105
+ case command
106
+ when "start" then self.start!
107
+ when "stop" then self.stop!
108
+ end
109
+ end
110
+
111
+ def start!
112
+ say "Start #{USER} #{self.name} #{self.stage}"
113
+
114
+ # Check for passenger gem.
115
+ unless rvm_execute(self.config, "gem list passenger") =~ /passenger/
116
+ say "Installing Passenger..."
117
+ rvm_execute(self.config, "gem install passenger")
118
+ end
119
+
120
+ # Run the before start callback
121
+ run_callback(:start, :before)
122
+
123
+ # Start the server
124
+ puts rvm_execute(self.config, "passenger start #{self.path + "current"} --user #{user} --port #{server_config['passenger']['port']} --environment production -d --pid-file #{self.path + "passenger.pid"}")
125
+
126
+ # Run the after start callback
127
+ run_callback(:start, :after)
128
+ end
129
+
130
+ def stop!
131
+ say "Stop #{USER} #{self.name} #{self.stage}"
132
+
133
+ # Run the before :stop callback
134
+ run_callback(:stop, :before)
135
+
136
+ puts rvm_execute(self.config, "passenger stop --pid-file #{self.path + "passenger.pid"}")
137
+
138
+ # Run the after :stop callback
139
+ run_callback(:stop, :after)
140
+ end
141
+
142
+ # Simple output wrapper
143
+ def say(msg)
144
+ puts msg
145
+ end
146
+
147
+ protected
148
+
149
+ def callback(key, time)
150
+ return unless self.config.has_key?("callbacks")
151
+
152
+ callbacks = self.config["callbacks"]
153
+
154
+ if callback = (callbacks[key.to_s] && callbacks[key.to_s][time.to_s])
155
+ if File.exists?(self.path + callback)
156
+ say "Running #{time} #{key} callback '#{callback}'"
157
+ say rvm_execute(self.config, "bash #{self.path + callback}")
158
+ else
159
+ raise "Defined callback #{time} #{key} '#{callback}' does not exist!"
160
+ end
161
+ end
162
+ end
163
+
164
+ end
165
+
166
+ # Helper method to run within an RVM environment
167
+ def rvm_execute(server_config, command)
168
+ execute("rvm_path=#{RVM_PATH} #{RVM_PATH}bin/rvm-shell '#{server_config['rvm']['rvm_ruby_string']}' -c '#{command}'")
169
+ end
170
+
171
+ # Execute command and decide wether or not to SUDO
172
+ def execute(command)
173
+ whoami = `whoami`.strip
174
+ if whoami == USER
175
+ `#{command} 2>&1`
176
+ else
177
+ `sudo -u #{USER} -H #{command} 2>&1`
178
+ end
179
+ end
180
+
181
+ begin
182
+ if run!
183
+ puts "Done!"
184
+ else
185
+ puts "Usage: passenger-standalone {start|stop|list} [application] [stage]"
186
+ end
187
+ rescue StandardError => e
188
+ puts "ERROR: #{e.message}"
189
+ puts "Usage: passenger-standalone {start|stop|list} [application] [stage]"
190
+ end
@@ -0,0 +1,23 @@
1
+ # = Bundler 0.7.x related tasks
2
+ #
3
+ # Warning: Do not load 0.7.x AND 1.0.x tasks at the same time!
4
+ Capistrano::Configuration.instance(true).load do
5
+ namespace :bundler do
6
+ desc "Setup bundler dirs in shared"
7
+ task :setup, :roles => [:app] do
8
+ run "mkdir -p #{deploy_to}/shared/bundler_gems/gems #{deploy_to}/shared/bundler_gems/specifications"
9
+ end
10
+
11
+ desc "Bundle gems in release_path/vendor/bundler_gems (symlinked to shared)"
12
+ task :bundle, :roles => [:app] do
13
+ run "cd #{release_path}/vendor/bundler_gems; ln -fs #{deploy_to}/shared/bundler_gems/gems"
14
+ run "cd #{release_path}/vendor/bundler_gems; ln -fs #{deploy_to}/shared/bundler_gems/specifications"
15
+ run "cd #{release_path}; gem bundle --cached"
16
+ end
17
+
18
+ desc "Install bundler"
19
+ task :install, :roles => [:app] do
20
+ run "gem install bundler --version=0.7.2"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,121 @@
1
+ # = Database.yml related tasks
2
+ #
3
+ # == Usage
4
+ #
5
+ # * Include this file in your <tt>deploy.rb</tt> configuration file.
6
+ # * Setup the required variables (see below)
7
+ # * After deploy:setup run database:setup
8
+ # * After deploy:update_code run database:copy_config_to_release
9
+ #
10
+ # == Setting variables
11
+ #
12
+ # The recipe uses the variable :database_config. You can put in there whatever you like but these are the defaults:
13
+ #
14
+ # set :database_config, {
15
+ # :username => "",
16
+ # :host => "",
17
+ # :development => "",
18
+ # :production => "",
19
+ # :test => ""
20
+ # }
21
+ #
22
+ # == Password
23
+ #
24
+ # Because you definitely don't want the password for the database in your SCM the recipe
25
+ # asks you for it.
26
+ #
27
+ # == Custom template
28
+ #
29
+ # By default, this script creates the database.yml below.
30
+ #
31
+ # If you want to overwrite the default template, simply create a custom Erb template
32
+ # called <tt>database.yml.erb</tt> and save it into <tt>config/deploy/templates</tt> folder.
33
+ #
34
+ # Although the name of the file can't be changed, you can customize the directory
35
+ # where it is stored defining a variable called <tt>:template_dir</tt>.
36
+ #
37
+ # # store your custom template at foo/bar/database.yml.erb
38
+ # set :template_dir, "foo/bar"
39
+ #
40
+ # # example of database template
41
+ #
42
+ # # MySQL (default setup). Versions 4.1 and 5.0 are recommended.
43
+ #
44
+ # db: &db
45
+ # adapter: mysql2
46
+ # username: <%= db[:username] %>
47
+ # password: <%= db[:password] %>
48
+ # host: <%= db[:host] %>
49
+ #
50
+ # development:
51
+ # <<: *db
52
+ # database: <%= db[:development] %>
53
+ #
54
+ # test:
55
+ # <<: *db
56
+ # database: <%= db[:test] %>
57
+ #
58
+ # production:
59
+ # <<: *db
60
+ # database: <%= db[:production] %>
61
+ #
62
+ #
63
+ # Because this is an Erb template, you can place variables and Ruby scripts
64
+ # within the file.
65
+ # For instance, the template above takes advantage of Capistrano CLI
66
+ # to ask for a MySQL database password instead of hard coding it into the template.
67
+ require 'ostruct'
68
+
69
+ Capistrano::Configuration.instance.load do
70
+ namespace :database do
71
+ desc <<-DESC
72
+ Creates the database.yml configuration file in deploy path.
73
+ It asks for a database password.
74
+
75
+ By default, this task uses a template unless a template \
76
+ called database.yml.erb is found either is :template_dir \
77
+ or /config/deploy folders. The default template matches \
78
+ the template for config/database.yml file shipped with Rails.
79
+
80
+ DESC
81
+ task :setup, :except => { :no_release => true } do
82
+
83
+ default_template = <<-EOF
84
+ # MySQL (default setup). Versions 4.1 and 5.0 are recommended.
85
+
86
+ db: &db
87
+ adapter: <%= config[:adapter] || "mysql2" %>
88
+ username: <%= config[:username] %>
89
+ password: <%= Capistrano::CLI.ui.ask("Database password: ") %>
90
+ host: <%= config[:host] %>
91
+
92
+ development:
93
+ <<: *db
94
+ database: <%= config[:development] %>
95
+
96
+ test:
97
+ <<: *db
98
+ database: <%= config[:test] %>
99
+
100
+ production:
101
+ <<: *db
102
+ database: <%= config[:production] %>
103
+ EOF
104
+
105
+ location = fetch(:template_dir, "config/deploy/templates") + '/database.yml.erb'
106
+ template = File.file?(location) ? File.read(location) : default_template
107
+
108
+
109
+ view = ERB.new(template)
110
+ put view.result(OpenStruct.new(:config => fetch(:database_config)).send(:binding)), "#{deploy_to}/database.yml"
111
+ end
112
+
113
+ desc <<-DESC
114
+ Copies the setup database.yml to the just deployed release.
115
+ DESC
116
+ task :copy_config_to_release, :except => { :no_release => true } do
117
+ run "cp #{deploy_to}/database.yml #{release_path}/config/database.yml"
118
+ end
119
+
120
+ end
121
+ end
@@ -0,0 +1,24 @@
1
+ # = Passenger related recipes
2
+ #
3
+ # These tasks overwrite the default start/stop/restart tasks for deployment
4
+ # With passenger we only need to touch 'CURRENT_PATH/tmp/restart.txt'
5
+ #
6
+ # Warning: This overwrites the default deploy:restart, deploy:start and deploy:stop tasks
7
+ Capistrano::Configuration.instance(true).load do
8
+
9
+ namespace :deploy do
10
+ task :restart, :roles => [:app] do
11
+ run "touch #{current_path}/tmp/restart.txt"
12
+ end
13
+
14
+ task :start, :roles => [:app] do
15
+ # do nothing
16
+ end
17
+
18
+ task :stop, :roles => [:app] do
19
+ # do nothing
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,34 @@
1
+ # = Passenger Standalone related recipes
2
+ #
3
+ # These tasks handle setup of server.yml to use in combination
4
+ # with the DP init.d script for passenger standalone installations (see examples/scripts/initd.rb)
5
+ #
6
+ #
7
+ require 'yaml'
8
+ Capistrano::Configuration.instance(true).load do
9
+ namespace :passenger_standalone do
10
+ desc "Setup server.yml in the 'deploy_to' directory"
11
+ task :setup, :roles => [:app] do
12
+ config = fetch(:passenger_standalone)
13
+ config = deep_stringify_keys(config)
14
+ unless config["rvm"] && config["rvm"]["rvm_ruby_string"]
15
+ config["rvm"] ||= {}
16
+ config["rvm"]["rvm_ruby_string"] = fetch(:rvm_ruby_string)
17
+ end
18
+
19
+ put config.to_yaml, "#{deploy_to}/server.yml"
20
+ end
21
+ end
22
+
23
+ # Helper method to make all keys of the config strings
24
+ def deep_stringify_keys(hash)
25
+ hash.inject({}) do |mem, (k,v)|
26
+ if v.kind_of?(Hash)
27
+ mem[k.to_s] = deep_stringify_keys(v)
28
+ else
29
+ mem[k.to_s] = v
30
+ end
31
+ mem
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,33 @@
1
+ # = RVM related tasks
2
+ #
3
+ # These tasks make working with RVM and gemsits a little bit easier.
4
+ #
5
+ # == Usage
6
+ # We want to be able to set the defined RVMRC in the deploy script
7
+ # on the server too. To achieve this we have to set the RVMRC
8
+ # after every deploy and we have to trust the just created RVMRC too.
9
+ #
10
+ # == Example
11
+ # require 'deployable/rvm'
12
+ # before "deploy:setup", "rvm:create_gemset"
13
+ # after "deploy:update_code", "rvm:set_rvmrc", "rvm:trust_rvmrc"
14
+ #
15
+ Capistrano::Configuration.instance(true).load do
16
+ namespace :rvm do
17
+ desc "Trust the RVMRC in release_path"
18
+ task :trust_rvmrc do
19
+ run "rvm rvmrc trust #{release_path}"
20
+ end
21
+
22
+ desc "Set an RVMRC according to the rubystring in release_path"
23
+ task :set_rvmrc, :roles => [:app] do
24
+ put "rvm use #{rvm_ruby_string}", "#{release_path}/.rvmrc"
25
+ end
26
+
27
+ desc "Create the gemset"
28
+ task :create_gemset, :roles => [:app] do
29
+ ruby,gemset = rvm_ruby_string.split("@")
30
+ run "rvm gemset create #{gemset}"
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ module Deployable
2
+ VERSION = "0.0.1"
3
+ end
data/lib/deployable.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "deployable/version"
2
+
3
+ unless Capistrano::Configuration.respond_to?(:instance)
4
+ abort "This extension requires Capistrano 2"
5
+ end
6
+
7
+ module Deployable
8
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: deployable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Digitpaint
9
+ - Flurin Egger
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-01-22 00:00:00.000000000Z
14
+ dependencies: []
15
+ description: A collection of handy capistrano deploy recipes
16
+ email:
17
+ - info@digitpaint.nl
18
+ - flurin@digitpaint.nl
19
+ executables: []
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - .gitignore
24
+ - Gemfile
25
+ - Rakefile
26
+ - deployable.gemspec
27
+ - examples/config/deploy.rb
28
+ - examples/config/deploy/acceptance.rb
29
+ - examples/config/deploy/production.rb
30
+ - examples/scripts/initd.rb
31
+ - lib/deployable.rb
32
+ - lib/deployable/bundler-0.7.rb
33
+ - lib/deployable/database.rb
34
+ - lib/deployable/passenger.rb
35
+ - lib/deployable/passenger_standalone.rb
36
+ - lib/deployable/rvm.rb
37
+ - lib/deployable/version.rb
38
+ homepage: ''
39
+ licenses: []
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project: deployable
58
+ rubygems_version: 1.8.6
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: A collection of handy capistrano deploy recipes
62
+ test_files: []