AppTower-ubistrano 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.markdown +110 -0
- data/Rakefile +23 -0
- data/changelog.rdoc +25 -0
- data/example/deploy.rb +17 -0
- data/lib/ubistrano.rb +71 -0
- data/lib/ubistrano/apache.rb +38 -0
- data/lib/ubistrano/deploy.rb +52 -0
- data/lib/ubistrano/gems.rb +29 -0
- data/lib/ubistrano/helpers.rb +237 -0
- data/lib/ubistrano/log.rb +20 -0
- data/lib/ubistrano/mysql.rb +94 -0
- data/lib/ubistrano/rails.rb +76 -0
- data/lib/ubistrano/sinatra.rb +23 -0
- data/lib/ubistrano/ssh.rb +51 -0
- data/lib/ubistrano/stage.rb +30 -0
- data/lib/ubistrano/ubuntu.rb +269 -0
- data/templates/apache/virtual_host.erb +8 -0
- data/templates/log/rotate.conf.erb +9 -0
- data/templates/rails/database.yml.erb +13 -0
- data/templates/sinatra/config.ru.erb +10 -0
- data/templates/ubuntu/apache.god.erb +31 -0
- data/templates/ubuntu/god.erb +36 -0
- data/templates/ubuntu/god.god.erb +1 -0
- data/templates/ubuntu/iptables.rules.erb +31 -0
- data/templates/ubuntu/mysql.god.erb +31 -0
- data/templates/ubuntu/sshd.god.erb +31 -0
- data/ubistrano.gemspec +47 -0
- metadata +80 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 AppTower
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
Ubistrano
|
2
|
+
=========
|
3
|
+
|
4
|
+
Provision and deploy to an Ubuntu/God/Apache/Passenger stack using Capistrano.
|
5
|
+
|
6
|
+
Goals
|
7
|
+
-----
|
8
|
+
|
9
|
+
* Provision a solid Ubuntu Hardy application server in one command (<code>cap ubuntu</code>)
|
10
|
+
* Deploy PHP, Rails, and Sinatra apps
|
11
|
+
* Be descriptive about what is going on and allow the user to opt out
|
12
|
+
* Simplify the deploy.rb file
|
13
|
+
|
14
|
+
The stack
|
15
|
+
---------
|
16
|
+
|
17
|
+
* Apache
|
18
|
+
* Git
|
19
|
+
* MySQL
|
20
|
+
* MySQLTuner
|
21
|
+
* Perl
|
22
|
+
* PHP
|
23
|
+
* Postfix (relay)
|
24
|
+
* Ruby
|
25
|
+
* RubyGems
|
26
|
+
* Passenger (mod\_rails)
|
27
|
+
* God
|
28
|
+
* Rails
|
29
|
+
* Sinatra
|
30
|
+
* Sphinx
|
31
|
+
|
32
|
+
|
33
|
+
Getting started
|
34
|
+
---------------
|
35
|
+
|
36
|
+
### Install gem
|
37
|
+
|
38
|
+
gem install AppTower-ubistrano
|
39
|
+
|
40
|
+
### Capify your project
|
41
|
+
|
42
|
+
capify .
|
43
|
+
|
44
|
+
### Edit config/deploy.rb
|
45
|
+
|
46
|
+
<pre>
|
47
|
+
set :ubistrano, {
|
48
|
+
:application => :my_app,
|
49
|
+
:platform => :rails, # :php, :rails, :sinatra
|
50
|
+
:repository => 'git@github.com:user/my-app.git',
|
51
|
+
|
52
|
+
:production => {
|
53
|
+
:domain => [ 'myapp.com', 'www.myapp.com' ],
|
54
|
+
:host => '127.0.0.1'
|
55
|
+
},
|
56
|
+
|
57
|
+
:staging => {
|
58
|
+
:domain => 'staging.myapp.com',
|
59
|
+
:host => '127.0.0.1'
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
require 'ubistrano'
|
64
|
+
</pre>
|
65
|
+
|
66
|
+
Ubistrano uses the same Capistrano options you've come to love, but provides defaults and a few extra options as well.
|
67
|
+
|
68
|
+
Feel free to add standard options like :user to the stage groups.
|
69
|
+
|
70
|
+
Set up your Ubuntu Hardy server
|
71
|
+
-------------------------------
|
72
|
+
|
73
|
+
### From your app directory
|
74
|
+
|
75
|
+
<pre>cap ubuntu</pre>
|
76
|
+
|
77
|
+
### Example output
|
78
|
+
|
79
|
+
<pre>
|
80
|
+
=================================================================================
|
81
|
+
Let's set up an Ubuntu server! (Tested with 8.04 LTS Hardy)
|
82
|
+
|
83
|
+
With each task, Ubistrano will describe what it is doing, and wait for a yes/no.
|
84
|
+
|
85
|
+
=================================================================================
|
86
|
+
Have you already created the user defined in deploy.rb? (y/n)
|
87
|
+
</pre>
|
88
|
+
|
89
|
+
Deploy your app
|
90
|
+
---------------
|
91
|
+
|
92
|
+
All apps should have a <code>public</code> directory.
|
93
|
+
|
94
|
+
### First deploy
|
95
|
+
|
96
|
+
cap deploy:first
|
97
|
+
|
98
|
+
### Subsequent deploys
|
99
|
+
|
100
|
+
cap deploy
|
101
|
+
|
102
|
+
|
103
|
+
Deploy to staging
|
104
|
+
-----------------
|
105
|
+
|
106
|
+
Use any capistrano task, but replace `cap` with `cap staging`.
|
107
|
+
|
108
|
+
### Example
|
109
|
+
|
110
|
+
cap staging deploy:first
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rake'
|
2
|
+
|
3
|
+
task :default => 'ubistrano.gemspec'
|
4
|
+
|
5
|
+
file 'ubistrano.gemspec' => FileList['{example,lib,templates}/**','Rakefile'] do |f|
|
6
|
+
# read spec file and split out manifest section
|
7
|
+
spec = File.read(f.name)
|
8
|
+
parts = spec.split(" # = MANIFEST =\n")
|
9
|
+
fail 'bad spec' if parts.length != 3
|
10
|
+
# determine file list from git ls-files
|
11
|
+
files = `git ls-files`.
|
12
|
+
split("\n").
|
13
|
+
sort.
|
14
|
+
reject{ |file| file =~ /^\./ }.
|
15
|
+
reject { |file| file =~ /^doc/ }.
|
16
|
+
map{ |file| " #{file}" }.
|
17
|
+
join("\n")
|
18
|
+
# piece file back together and write...
|
19
|
+
parts[1] = " s.files = %w[\n#{files}\n ]\n"
|
20
|
+
spec = parts.join(" # = MANIFEST =\n")
|
21
|
+
File.open(f.name, 'w') { |io| io.write(spec) }
|
22
|
+
puts "Updated #{f.name}"
|
23
|
+
end
|
data/changelog.rdoc
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
Version 2.0.0
|
3
|
+
* Tested on Ubuntu 8.04 LTS Hardy
|
4
|
+
* Deploys PHP, Rails, and Sinatra apps
|
5
|
+
* Redux version with new stack
|
6
|
+
* Apache
|
7
|
+
* Git
|
8
|
+
* God
|
9
|
+
* MySQL
|
10
|
+
* Passenger (mod_rails)
|
11
|
+
* Rails
|
12
|
+
* Ruby Enterprise Edition
|
13
|
+
|
14
|
+
Version 1.1.0
|
15
|
+
* Tested on Debian Etch
|
16
|
+
* Git
|
17
|
+
* Nginx
|
18
|
+
* Mongrel cluster
|
19
|
+
* Monit
|
20
|
+
* MySQL
|
21
|
+
* PHP (Nginx w/ spawn-fcgi)
|
22
|
+
* Rails
|
23
|
+
* Ruby
|
24
|
+
* RubyGems
|
25
|
+
* Sphinx
|
data/example/deploy.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
set :ubistrano, {
|
2
|
+
:application => :my_app,
|
3
|
+
:platform => :rails, # :php, :rails, :sinatra
|
4
|
+
:repository => 'git@github.com:user/my-app.git',
|
5
|
+
|
6
|
+
:production => {
|
7
|
+
:domain => [ 'myapp.com', 'www.myapp.com' ],
|
8
|
+
:host => '127.0.0.1'
|
9
|
+
},
|
10
|
+
|
11
|
+
:staging => {
|
12
|
+
:domain => 'staging.myapp.com',
|
13
|
+
:host => '127.0.0.1'
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
require 'ubistrano'
|
data/lib/ubistrano.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
|
2
|
+
# Require helpers and recipes
|
3
|
+
Dir["#{File.dirname(__FILE__)}/ubistrano/*.rb"].each { |f| require f }
|
4
|
+
|
5
|
+
|
6
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
7
|
+
|
8
|
+
# Reference ROOT when namespaces clash
|
9
|
+
ROOT = self
|
10
|
+
|
11
|
+
# Default package versions
|
12
|
+
ubistrano[:versions] ||= {}
|
13
|
+
ubistrano[:versions].merge!(
|
14
|
+
:git => '1.6.0.4',
|
15
|
+
:mysecureshell => '1.1',
|
16
|
+
:rails => '2.2.2',
|
17
|
+
:ruby => '1.8.7-p72',
|
18
|
+
:rubygems => '1.3.1',
|
19
|
+
:sphinx => '0.9.8.1'
|
20
|
+
)
|
21
|
+
|
22
|
+
# Merge ubistrano hash with capistrano
|
23
|
+
ubistrano.each do |key, value|
|
24
|
+
value.respond_to?(:keys) ?
|
25
|
+
value.each { |k, v| set "#{key}_#{k}".intern, v } :
|
26
|
+
set(key, value)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Set default capistrano values
|
30
|
+
set :db_user, fetch(:db_user, 'app')
|
31
|
+
set :db_pass, fetch(:db_pass, '')
|
32
|
+
set :platform, fetch(:platform, :rails)
|
33
|
+
set :port, fetch(:port, 22)
|
34
|
+
set :stage, fetch(:stage, :production)
|
35
|
+
set :use_sudo, fetch(:use_sudo, false)
|
36
|
+
set :user, fetch(:user, 'deploy')
|
37
|
+
set :sources, fetch(:sources, {
|
38
|
+
:git => "http://kernel.org/pub/software/scm/git/git-#{versions_git}.tar.gz",
|
39
|
+
:mysecureshell => "http://internap.dl.sourceforge.net/sourceforge/mysecureshell/MySecureShell-#{versions_mysecureshell}_source.tgz",
|
40
|
+
:mysqltuner => "http://mysqltuner.com/mysqltuner.pl",
|
41
|
+
:ruby => "ftp://ftp.ruby-lang.org/pub/ruby/#{versions_ruby.split('.')[0..1].join('.')}/ruby-#{versions_ruby}.tar.gz",
|
42
|
+
:rubygems => "http://rubyforge.org/frs/download.php/45905/rubygems-#{versions_rubygems}.tgz",
|
43
|
+
:sphinx => "http://www.sphinxsearch.com/downloads/sphinx-#{versions_sphinx}.tar.gz"
|
44
|
+
})
|
45
|
+
|
46
|
+
# Rails plugins
|
47
|
+
set :app_helpers, fetch(:app_helpers, false)
|
48
|
+
set :rails_widget, fetch(:rails_widget, false)
|
49
|
+
set :ultrasphinx, fetch(:ultrasphinx, false)
|
50
|
+
set :thinking_sphinx, fetch(:thinking_sphinx, false)
|
51
|
+
set :attachment_fu, fetch(:attachment_fu, false)
|
52
|
+
set :asset_packager, fetch(:asset_packager, false)
|
53
|
+
after('deploy:update_code', 'rails:config:app_helpers') if app_helpers
|
54
|
+
after('deploy:update_code', 'rails:config:asset_packager') if asset_packager
|
55
|
+
after('deploy:update_code', 'rails:config:attachment_fu') if attachment_fu
|
56
|
+
after('deploy:update_code', 'rails:config:rails_widget') if rails_widget
|
57
|
+
after('deploy:update_code', 'rails:config:ultrasphinx') if ultrasphinx
|
58
|
+
after('deploy:update_code', 'rails:config:thinking_sphinx') if thinking_sphinx
|
59
|
+
|
60
|
+
# Git by default
|
61
|
+
set :scm, :git
|
62
|
+
set :deploy_via, :remote_cache
|
63
|
+
set :repository_cache, 'git_cache'
|
64
|
+
ssh_options[:paranoid] = false
|
65
|
+
|
66
|
+
# Events
|
67
|
+
on :before, 'setup_stage', :except => [ :staging, :testing ] # Executed before every task
|
68
|
+
after('deploy:update_code', 'rails:config:to_app' ) if platform == :rails
|
69
|
+
after('deploy:update_code', 'sinatra:config:to_app') if platform == :sinatra
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
namespace :apache do
|
4
|
+
desc "Reload apache settings"
|
5
|
+
task :reload, :roles => :web do
|
6
|
+
sudo_puts "/etc/init.d/apache2 reload"
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "Restart apache"
|
10
|
+
task :restart, :roles => :web do
|
11
|
+
sudo_puts "/etc/init.d/apache2 restart"
|
12
|
+
end
|
13
|
+
|
14
|
+
namespace :virtual_host do
|
15
|
+
desc "Create a new virtual host"
|
16
|
+
task :create, :roles => :web do
|
17
|
+
upload_from_erb "/etc/apache2/sites-available/#{application}_#{stage}", binding, :name => 'virtual_host', :folder => 'ubuntu'
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Enable a virtual host"
|
21
|
+
task :enable, :roles => :web do
|
22
|
+
sudo_puts "a2ensite #{application}_#{stage}"
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Destroy a virtual host"
|
26
|
+
task :destroy, :roles => :web do
|
27
|
+
apache.virtual_host.disable
|
28
|
+
sudo_each "rm /etc/apache2/sites-available/#{application}_#{stage}"
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "Disable a virtual host"
|
32
|
+
task :disable, :roles => :web do
|
33
|
+
sudo_puts "a2dissite #{application}_#{stage}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
namespace :deploy do
|
4
|
+
desc "Restart application"
|
5
|
+
task :restart, :roles => :app, :except => { :no_release => true } do
|
6
|
+
run_each [
|
7
|
+
"mkdir #{current_path}/tmp",
|
8
|
+
"touch #{current_path}/tmp/restart.txt"
|
9
|
+
]
|
10
|
+
end
|
11
|
+
|
12
|
+
desc "Start application"
|
13
|
+
task :start, :roles => :app do
|
14
|
+
apache.virtual_host.enable
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Stop application"
|
18
|
+
task :stop, :roles => :app do
|
19
|
+
apache.virtual_host.disable
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Deploy for the first time"
|
23
|
+
task :first, :roles => :app do
|
24
|
+
sudo_each [
|
25
|
+
"mkdir -p #{base_dir}",
|
26
|
+
"chown -R #{user}:#{user} #{base_dir}"
|
27
|
+
]
|
28
|
+
mysql.create.db
|
29
|
+
deploy.setup
|
30
|
+
deploy.update
|
31
|
+
apache.virtual_host.create
|
32
|
+
case platform
|
33
|
+
when :rails
|
34
|
+
rails.config.default
|
35
|
+
deploy.migrate
|
36
|
+
when :sinatra
|
37
|
+
sinatra.config.default
|
38
|
+
sinatra.install
|
39
|
+
end
|
40
|
+
deploy.start
|
41
|
+
apache.reload
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "Stop servers and destroy all files"
|
45
|
+
task :destroy, :roles => :app do
|
46
|
+
deploy.stop
|
47
|
+
sudo "rm -Rf #{deploy_to}"
|
48
|
+
mysql.destroy.db
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
namespace :gems do
|
4
|
+
desc "List gems on remote server"
|
5
|
+
task :list, :roles => :app do
|
6
|
+
run_puts "gem list"
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "Update gems on remote server"
|
10
|
+
task :update, :roles => :app do
|
11
|
+
sudo_each [
|
12
|
+
"gem update --system",
|
13
|
+
"gem update"
|
14
|
+
]
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Install a remote gem"
|
18
|
+
task :install, :roles => :app do
|
19
|
+
gem_install ask('Enter the name of the gem to install:')
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Uninstall a remote gem"
|
23
|
+
task :uninstall, :roles => :app do
|
24
|
+
gem_name = ask 'Enter the name of the gem to remove:'
|
25
|
+
sudo "gem uninstall #{gem_name}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,237 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
4
|
+
|
5
|
+
# Install
|
6
|
+
|
7
|
+
def gem_install(name, options='')
|
8
|
+
sudo_puts "gem install #{name} #{options} --no-rdoc --no-ri -q"
|
9
|
+
end
|
10
|
+
|
11
|
+
def install_source(source)
|
12
|
+
path, source = unpack_source source
|
13
|
+
yield path
|
14
|
+
sudo "rm -Rf #{source}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def make_install(path)
|
18
|
+
";cd #{path} && ./configure && make && sudo make install"
|
19
|
+
end
|
20
|
+
|
21
|
+
def unpack_source(source)
|
22
|
+
url = sources[source]
|
23
|
+
name = File.basename url
|
24
|
+
src = "/home/#{user}/sources"
|
25
|
+
base = nil
|
26
|
+
[ 'tar.gz', 'tgz' ].each do |ext|
|
27
|
+
base = name[0..((ext.length + 2) * -1)] if name.include?(ext)
|
28
|
+
end
|
29
|
+
run_each [
|
30
|
+
"mkdir -p #{src}",
|
31
|
+
"cd #{src} && wget --quiet #{url}",
|
32
|
+
"tar -xzvf #{src}/#{name} -C #{src}"
|
33
|
+
]
|
34
|
+
[ "#{src}/#{base}", src ]
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
# Files
|
39
|
+
|
40
|
+
def add_line(file, *lines)
|
41
|
+
lines.each do |line|
|
42
|
+
sudo_each "echo \"#{line}\" | sudo tee -a #{file}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def change_line(file, from, to)
|
47
|
+
sudo_each "sed 's/#{from}/#{to}/' #{file}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def remove_line(file, *lines)
|
51
|
+
lines.each do |line|
|
52
|
+
change_line file, line, ''
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_ssh_keys
|
57
|
+
keys = Dir[File.expand_path('~/.ssh/*.pub')].collect do |f|
|
58
|
+
File.open(f).collect { |line| line.strip.empty? ? nil : line.strip }.compact
|
59
|
+
end
|
60
|
+
keys.flatten.join("\n").strip
|
61
|
+
end
|
62
|
+
|
63
|
+
def upload_from_erb(destination, bind=nil, options={})
|
64
|
+
# options[ :chown => owner of file (default: deploy user),
|
65
|
+
# :chmod => 0644 etc
|
66
|
+
# :folder => 'postfix' etc,
|
67
|
+
# :name => name of template if differs from destination ]
|
68
|
+
if destination.respond_to?(:uniq)
|
69
|
+
destination.each { |d| upload_from_erb d, bind, options }
|
70
|
+
else
|
71
|
+
template = File.basename destination
|
72
|
+
template = template[1..-1] if template[0..0] == '.'
|
73
|
+
folder = options[:folder] ? options[:folder] + '/' : ''
|
74
|
+
template = File.expand_path("../../templates/#{folder}#{options[:name]||template}.erb", File.dirname(__FILE__))
|
75
|
+
template = File.read template
|
76
|
+
sudo "touch #{destination}"
|
77
|
+
sudo "chown #{user} #{destination}"
|
78
|
+
put ERB.new(template).result(bind || binding), destination
|
79
|
+
sudo("chown #{options[:chown]} #{destination}") if options[:chown]
|
80
|
+
sudo("chmod #{options[:chmod]} #{destination}") if options[:chmod]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
# MySQL
|
86
|
+
|
87
|
+
def mysql_run(sql)
|
88
|
+
if sql.respond_to?(:uniq)
|
89
|
+
sql.each { |s| mysql_run s }
|
90
|
+
else
|
91
|
+
run "echo \"#{sql}\" | #{mysql_call}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def mysql_call
|
96
|
+
@mysql_root_password = @mysql_root_password || ask("Password for mysql root:")
|
97
|
+
"mysql -u root --password=#{@mysql_root_password}"
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
# Questions
|
102
|
+
|
103
|
+
def ask(question, default='')
|
104
|
+
question = "\n" + question.join("\n") if question.respond_to?(:uniq)
|
105
|
+
answer = Capistrano::CLI.ui.ask(space(question)).strip
|
106
|
+
answer.empty? ? default : answer
|
107
|
+
end
|
108
|
+
|
109
|
+
def yes(question)
|
110
|
+
question = "\n" + question.join("\n") if question.respond_to?(:uniq)
|
111
|
+
question += ' (y/n)'
|
112
|
+
ask(question).downcase.include? 'y'
|
113
|
+
end
|
114
|
+
|
115
|
+
def space(str)
|
116
|
+
"\n#{'=' * 90}\n#{str}"
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
# Runners
|
121
|
+
|
122
|
+
def run_each(*args, &block)
|
123
|
+
cmd = args[0]
|
124
|
+
sudo = args[1]
|
125
|
+
if cmd.respond_to?(:uniq)
|
126
|
+
cmd.each { |c| run_each c, sudo, &block }
|
127
|
+
elsif sudo
|
128
|
+
puts space("sudo #{cmd}")
|
129
|
+
sudo(cmd) { |ch, st, data| block.call(data) if block }
|
130
|
+
else
|
131
|
+
puts space(cmd)
|
132
|
+
run(cmd) { |ch, st, data| block.call(data) if block }
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def sudo_each(cmds, &block)
|
137
|
+
run_each cmds, true, &block
|
138
|
+
end
|
139
|
+
|
140
|
+
def run_puts(cmds, &block)
|
141
|
+
run_each(cmds) { |data| puts data }
|
142
|
+
end
|
143
|
+
|
144
|
+
def sudo_puts(cmds, &block)
|
145
|
+
sudo_each(cmds) { |data| puts data }
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
# Messages
|
150
|
+
|
151
|
+
def msg(type)
|
152
|
+
case type
|
153
|
+
when :about_templates
|
154
|
+
"Let's set up an Ubuntu server! (Tested with 8.04 LTS Hardy)
|
155
|
+
|
156
|
+
With each task, Ubistrano will describe what it is doing, and wait for a yes/no."
|
157
|
+
when :aptitude_default
|
158
|
+
"Do you want me to run aptitude update, upgrade, and install build-essential?
|
159
|
+
If not, instructions for doing it manually will be displayed."
|
160
|
+
when :aptitude_instructions
|
161
|
+
"Please run these manually:
|
162
|
+
sudo aptitude update
|
163
|
+
sudo aptitude upgrade
|
164
|
+
sudo aptitude build-essential"
|
165
|
+
when :create_keys
|
166
|
+
"May I generate an rsa ssh key pair in your ~/.ssh folder?"
|
167
|
+
when :create_server_keys
|
168
|
+
"May I generate an rsa ssh key pair in the server's ~/.ssh folder?
|
169
|
+
The public key will be displayed."
|
170
|
+
when :god
|
171
|
+
"May I install God?"
|
172
|
+
when :god_apache
|
173
|
+
"Would you like God to monitor apache?
|
174
|
+
See #{File.expand_path '../../', File.dirname(__FILE__)}/templates/ubuntu/apache.god.erb"
|
175
|
+
when :god_mysql
|
176
|
+
"Would you like God to monitor mysql?
|
177
|
+
See #{File.expand_path '../../', File.dirname(__FILE__)}/templates/ubuntu/mysql.god.erb"
|
178
|
+
when :god_apache
|
179
|
+
"Would you like God to monitor sshd?
|
180
|
+
See #{File.expand_path '../../', File.dirname(__FILE__)}/templates/ubuntu/sshd.god.erb"
|
181
|
+
when :have_keys
|
182
|
+
"Do you have rsa key pairs installed on your system? (see ~/.ssh/id_rsa)"
|
183
|
+
when :iptables
|
184
|
+
"May I update your server's iptables, limiting access to SSH, HTTP, HTTPS, and ping only?
|
185
|
+
See #{File.expand_path '../../', File.dirname(__FILE__)}/templates/ubuntu/iptables.rules.erb"
|
186
|
+
when :logrotate
|
187
|
+
"May I add a logrotate entry for this application?
|
188
|
+
See #{File.expand_path '../../', File.dirname(__FILE__)}/templates/log/rotate.conf.erb"
|
189
|
+
when :mysqltuner
|
190
|
+
"Would you like to install MySQLTuner and receive instructions for running it?"
|
191
|
+
when :mysqltuner_instructions
|
192
|
+
"Please ssh to your server and run `sudo mysqltuner`.
|
193
|
+
Continue?"
|
194
|
+
when :passenger
|
195
|
+
"Please run `sudo passenger-install-apache2-module` manually.
|
196
|
+
The apache config file is found at /etc/apache2/apache2.conf.
|
197
|
+
Reload apache?"
|
198
|
+
when :secure_mysql
|
199
|
+
"It is highly recommended you run mysql_secure_installation manually.
|
200
|
+
See http://dev.mysql.com/doc/refman/5.1/en/mysql-secure-installation.html
|
201
|
+
Continue?"
|
202
|
+
when :ssh_keys_create
|
203
|
+
"Create rsa ssh key pairs locally or remotely? (default: remote)"
|
204
|
+
when :ssh_keys_upload
|
205
|
+
"Press enter to copy all public keys (~/.ssh/*.pub), or paste a key: "
|
206
|
+
when :sshd_config
|
207
|
+
"May I update your server's sshd_config with the following settings?
|
208
|
+
Port #{port}
|
209
|
+
PermitRootLogin no
|
210
|
+
X11Forwarding no
|
211
|
+
UsePAM no
|
212
|
+
UseDNS no
|
213
|
+
"
|
214
|
+
when :sudoers
|
215
|
+
"May I add sudo-without-password privileges for the deploy user?
|
216
|
+
I will have to edit /etc/sudoers."
|
217
|
+
when :ubuntu_restart
|
218
|
+
"Would you like to restart the server now?"
|
219
|
+
when :ubuntu_finished
|
220
|
+
"That's it! Glad you made it.
|
221
|
+
|
222
|
+
Use `cap deploy:first` to set up your PHP, Rails, or Sinatra app.
|
223
|
+
Use `cap deploy` for all subsequent deploys.
|
224
|
+
|
225
|
+
"
|
226
|
+
when :upload_keys
|
227
|
+
"May I copy all of your public keys in ~/.ssh to the server's authorized_keys?"
|
228
|
+
when :visudo
|
229
|
+
"Please run the following commands:
|
230
|
+
ssh root@#{host}:#{port}
|
231
|
+
adduser #{user}
|
232
|
+
|
233
|
+
"
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|