capistrano_auto_multi_install 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/capistrano_auto_multi_install.rb +11 -0
- data/lib/capistrano_auto_multi_install/configure_database.rb +98 -0
- data/lib/capistrano_auto_multi_install/configure_web_server.rb +36 -0
- data/lib/capistrano_auto_multi_install/database.yml.erb +6 -0
- data/lib/capistrano_auto_multi_install/handlers.rb +102 -0
- data/lib/capistrano_auto_multi_install/mongrel.conf.erb +9 -0
- data/lib/capistrano_auto_multi_install/passenger.conf.erb +10 -0
- data/lib/capistrano_auto_multi_install/server.rb +82 -0
- data/lib/locales/en.yml +12 -0
- data/tasks/capistrano_auto_multi_install_tasks.rake +4 -0
- data/tests/capistrano_auto_multi_install_test.rb +8 -0
- data/tests/test_helper.rb +3 -0
- metadata +95 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'i18n'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module CapistranoAutoMultiInstall
|
6
|
+
I18n.load_path += Dir.glob(File.dirname(__FILE__)+"/locales/*.yml")
|
7
|
+
I18n.default_locale = 'en'
|
8
|
+
end
|
9
|
+
|
10
|
+
require "capistrano_auto_multi_install/configure_web_server"
|
11
|
+
require "capistrano_auto_multi_install/configure_database"
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require File.dirname(__FILE__)+"/handlers"
|
2
|
+
require File.dirname(__FILE__)+"/server"
|
3
|
+
class CapistranoAutoMultiInstall::ConfigureDatabase < CapistranoAutoMultiInstall::Handlers
|
4
|
+
attr_accessor :username,:password, :admin_username, :admin_password
|
5
|
+
|
6
|
+
def initialize(*args)
|
7
|
+
super *args
|
8
|
+
@username = fetch(:mysql_user)
|
9
|
+
end
|
10
|
+
|
11
|
+
def check_or_create_database
|
12
|
+
log 'Checking if '+fetch(:application)+'_production database exists'
|
13
|
+
log "Creating it if it doesn't exist yet"
|
14
|
+
|
15
|
+
@admin_username = fetch(:mysql_admin_name)
|
16
|
+
@admin_password = fetch(:mysql_admin_password)
|
17
|
+
@admin_password = '-p'+@admin_password unless @admin_password.empty?
|
18
|
+
|
19
|
+
run_as_admin("'CREATE DATABASE IF NOT EXISTS `#{fetch(:application)}_production` \
|
20
|
+
DEFAULT CHARACTER SET utf8 \
|
21
|
+
DEFAULT COLLATE utf8_general_ci;'")
|
22
|
+
|
23
|
+
log "Database done"
|
24
|
+
end
|
25
|
+
|
26
|
+
def check_or_create_user
|
27
|
+
log 'Checking if '+fetch(:mysql_user)+' has already been created and granted correctly'
|
28
|
+
log 'Errors messages reporting a missing user can be safely ignored'
|
29
|
+
|
30
|
+
grants = capture_as_admin "'SHOW GRANTS FOR #{@username}@localhost;'", ";true;"
|
31
|
+
|
32
|
+
ok = true
|
33
|
+
|
34
|
+
required_grants = ["SELECT","INSERT","UPDATE","DELETE","CREATE","DROP", "INDEX", "LOCK TABLES", "ALTER", "CREATE VIEW"]
|
35
|
+
if grants == "" # User is not present
|
36
|
+
log 'User not present, creating him'
|
37
|
+
ok = false
|
38
|
+
# now let's create him
|
39
|
+
@password = fetch(:mysql_user_password)
|
40
|
+
run_as_admin "\"CREATE USER '#{@username}'@localhost IDENTIFIED BY '#{@password}'\""
|
41
|
+
else
|
42
|
+
log "User present, checking his rights"
|
43
|
+
|
44
|
+
# First we've gotta filter the permissions by table.
|
45
|
+
# here we wanna make sure he has the necessary rights on "application"_production
|
46
|
+
grants = grants.split("\n").delete_if{ |grant| !(grant =~ Regexp.new(fetch(:application)+'_production'))}[0]
|
47
|
+
|
48
|
+
# Are all "required_grants" present?
|
49
|
+
required_grants.each do |grant|
|
50
|
+
ok = grants =~ Regexp.new(grant) if ok
|
51
|
+
end
|
52
|
+
end
|
53
|
+
# Ok = true => User exists and has the right rights on the right table
|
54
|
+
if ok
|
55
|
+
log 'Permissions are ok'
|
56
|
+
else
|
57
|
+
log 'Permissions are missing, adding them'
|
58
|
+
flush = "&& mysqladmin flush-privileges -u #{@admin_username} #{@admin_password}"
|
59
|
+
run_as_admin "\"GRANT "+required_grants.join(',')+" ON #{fetch(:application)}_production.* TO '#{@username}'@localhost\"", flush
|
60
|
+
end
|
61
|
+
log "Alright, now database and user are correctly set up"
|
62
|
+
|
63
|
+
|
64
|
+
create_database_yml_file
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_database_yml_file
|
68
|
+
|
69
|
+
mysql_password = fetch(:mysql_user_password)
|
70
|
+
mysql_user = fetch(:mysql_user)
|
71
|
+
|
72
|
+
conf = ERB.new(File.read(File.dirname(__FILE__)+"/database.yml.erb")).result(binding)
|
73
|
+
run_with_power "mkdir -p #{fetch(:shared_path)}/db", fetch(:runner)
|
74
|
+
run_with_power "mkdir -p #{fetch(:shared_path)}/config", fetch(:runner)
|
75
|
+
put_with_power conf, "#{fetch(:shared_path)}/config/database.yml", fetch(:runner)
|
76
|
+
|
77
|
+
syslink
|
78
|
+
end
|
79
|
+
|
80
|
+
def syslink
|
81
|
+
run_with_power "ln -nfs #{fetch(:shared_path)}/config/database.yml #{fetch(:current_path)}/config/database.yml", fetch(:runner)
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def capture_as_admin command, string_to_add=''
|
87
|
+
capture "echo #{command} | mysql -u #{@admin_username} #{@admin_password}"+string_to_add
|
88
|
+
end
|
89
|
+
|
90
|
+
def run_as_admin command, string_to_add=''
|
91
|
+
run "echo #{command} | mysql -u #{@admin_username} #{@admin_password}"+string_to_add
|
92
|
+
end
|
93
|
+
|
94
|
+
def mysql_admin_password
|
95
|
+
'-p'+@admin_username unless @admin_password.nil?
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.dirname(__FILE__)+"/handlers"
|
2
|
+
require File.dirname(__FILE__)+"/server"
|
3
|
+
class CapistranoAutoMultiInstall::ConfigureWebServer < CapistranoAutoMultiInstall::Handlers
|
4
|
+
attr_accessor :server, :server_type, :server_name, :server_conf_dir
|
5
|
+
|
6
|
+
def generate_conf_files
|
7
|
+
log I18n.t :apache_only_supported
|
8
|
+
|
9
|
+
@server_name = fetch(:application_url)
|
10
|
+
@server_conf_dir = fetch(:apache_conf_directory)
|
11
|
+
@server_type = fetch(:passenger_or_mongrel)
|
12
|
+
|
13
|
+
if server_type == 'passenger'
|
14
|
+
@server = CapistranoAutoMultiInstall::Passenger.new(capistrano_instance,:logger=>logger)
|
15
|
+
else
|
16
|
+
server_local_conf = fetch(:mongrel_local_conf)
|
17
|
+
@server.port = fetch(:mongrel_port)
|
18
|
+
if fetch(:mongrel_cluster) == "no"
|
19
|
+
log I18n.t :single_mongrel_selected
|
20
|
+
@server = CapistranoAutoMultiInstall::Mongrel.new(capistrano_instance,:logger=>logger)
|
21
|
+
else
|
22
|
+
log I18n.t :cluster_mongrel_selected
|
23
|
+
@server = CapistranoAutoMultiInstall::MongrelCluster.new(capistrano_instance,:logger=>logger)
|
24
|
+
@server.number_instances = fetch(:number_of_mongrel_instance)
|
25
|
+
end
|
26
|
+
@server.local_conf_dir = server_local_conf
|
27
|
+
end
|
28
|
+
@server.conf_dir = @server_conf_dir
|
29
|
+
@server.name = @server_name
|
30
|
+
@server.generate_conf_files
|
31
|
+
end
|
32
|
+
|
33
|
+
def write
|
34
|
+
@server.write
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
class CapistranoAutoMultiInstall::Handlers
|
2
|
+
@@conf_file = nil
|
3
|
+
|
4
|
+
def logger
|
5
|
+
@logger
|
6
|
+
end
|
7
|
+
|
8
|
+
def capistrano_instance
|
9
|
+
@@capistrano
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize capistrano, options
|
13
|
+
@@capistrano = capistrano
|
14
|
+
@logger = options[:logger]
|
15
|
+
end
|
16
|
+
|
17
|
+
def run_with_power command, as_user=nil
|
18
|
+
if fetch(:use_sudo)
|
19
|
+
log "Running a command with sudo"
|
20
|
+
if as_user
|
21
|
+
sudo "su -c '"+command+"' "+as_user
|
22
|
+
else
|
23
|
+
sudo command
|
24
|
+
end
|
25
|
+
# elsif exists?(:use_su) && fetch(:use_su)
|
26
|
+
# log "Running a command with su"
|
27
|
+
# command = "su -c '#{command}'"
|
28
|
+
else
|
29
|
+
log "Then trying to proceed as a normal user"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def run command
|
35
|
+
@@capistrano.run command
|
36
|
+
end
|
37
|
+
|
38
|
+
def sudo *command
|
39
|
+
@@capistrano.sudo *command
|
40
|
+
end
|
41
|
+
|
42
|
+
def capture command
|
43
|
+
@@capistrano.capture command
|
44
|
+
end
|
45
|
+
|
46
|
+
def put *command
|
47
|
+
@@capistrano.put *command
|
48
|
+
end
|
49
|
+
|
50
|
+
def put_with_power *command
|
51
|
+
log "Putting with power"
|
52
|
+
content = command.delete_at 0
|
53
|
+
destination = command.delete_at 0
|
54
|
+
run_as = nil
|
55
|
+
|
56
|
+
if command.last.is_a? String
|
57
|
+
run_as = command.last
|
58
|
+
command.delete(run_as)
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
put content, destination, ((command[0].is_a? Hash)?command[0]:{})
|
63
|
+
|
64
|
+
unless run_as.nil?
|
65
|
+
log "Changing owner"
|
66
|
+
run_with_power "chown -R #{run_as} #{destination}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def fetch attr
|
71
|
+
@@capistrano.fetch attr
|
72
|
+
end
|
73
|
+
|
74
|
+
def exists? attr
|
75
|
+
@@capistrano.exists? attr
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
protected
|
80
|
+
def get_in_conf_file(key)
|
81
|
+
deploy_conf_file = ''
|
82
|
+
if exists? :deploy_conf_file
|
83
|
+
deploy_conf_file = fetch(:deploy_conf_file)
|
84
|
+
else
|
85
|
+
@@conf_file = Hash.new
|
86
|
+
end
|
87
|
+
@@conf_file = YAML::load(File.open()) if @@conf_file.nil?
|
88
|
+
@@conf_file[key.to_s]
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
private
|
93
|
+
@logger = nil
|
94
|
+
|
95
|
+
def err message
|
96
|
+
@logger.info message
|
97
|
+
end
|
98
|
+
|
99
|
+
def log message
|
100
|
+
@logger.info message
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
class CapistranoAutoMultiInstall::Server < CapistranoAutoMultiInstall::Handlers
|
2
|
+
attr_accessor :name, :conf , :conf_dir
|
3
|
+
end
|
4
|
+
|
5
|
+
class CapistranoAutoMultiInstall::Passenger < CapistranoAutoMultiInstall::Server
|
6
|
+
|
7
|
+
attr_accessor :tmp
|
8
|
+
|
9
|
+
def initialize capistrano, options
|
10
|
+
@tmp = fetch(:deploy_to)+'/../passenger_tmp/'+fetch(:application)
|
11
|
+
super capistrano, options
|
12
|
+
end
|
13
|
+
|
14
|
+
def generate_conf_files
|
15
|
+
# Intanciate some locals which will be used in erb file
|
16
|
+
document_root = fetch(:deploy_to)+'/public'
|
17
|
+
server_name = name
|
18
|
+
passenger_tmp = tmp
|
19
|
+
|
20
|
+
@conf = ERB.new(File.read(File.dirname(__FILE__)+"/passenger.conf.erb")).result(binding)
|
21
|
+
end
|
22
|
+
|
23
|
+
def write
|
24
|
+
# If the user we use to connect to the server is not the same one running the application,
|
25
|
+
# namely web_user, then we've gotta use "with_power" methods
|
26
|
+
if exists?(:runner) && fetch(:runner) != fetch(:user)
|
27
|
+
run_with_power "mkdir -p "+tmp, fetch(:web_user)
|
28
|
+
put_with_power conf, conf_dir+'/'+fetch(:application)+'.conf', fetch(:runner)
|
29
|
+
else
|
30
|
+
run "mkdir -p "+tmp
|
31
|
+
put conf, conf_dir+'/'+fetch(:application)+'.conf'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
class CapistranoAutoMultiInstall::MongrelCluster < CapistranoAutoMultiInstall::Server
|
38
|
+
attr_accessor :port, :number_instances, :local_conf_dir
|
39
|
+
|
40
|
+
def initialize *args
|
41
|
+
super *args
|
42
|
+
@DEFAULT_LOCAL_CONF_DIR=fetch(:shared_path)+'/config'
|
43
|
+
end
|
44
|
+
|
45
|
+
def generate_conf_files
|
46
|
+
base_directory = fetch(:deploy_to)+'/current'
|
47
|
+
web_user = (exists?(:web_user))?fetch(:web_user):fetch(:user)
|
48
|
+
@conf = ERB.new(File.read(File.dirname(__FILE__)+"/mongrel.conf.erb")).result(binding)
|
49
|
+
end
|
50
|
+
|
51
|
+
def write
|
52
|
+
if local_conf_dir == '/config'
|
53
|
+
put conf,@DEFAULT_LOCAL_CONF_DIR+'/mongrel_cluster.yml'
|
54
|
+
else
|
55
|
+
if exists?(:runner) && fetch(:runner) != fetch(:user)
|
56
|
+
put_with_power conf, local_conf_dir+'/'+fetch(:application)+'.conf', fetch(:runner)
|
57
|
+
else
|
58
|
+
put conf, local_conf_dir+'/'+fetch(:application)+'.conf'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
class CapistranoAutoMultiInstall::Mongrel < CapistranoAutoMultiInstall::MongrelCluster
|
66
|
+
def write
|
67
|
+
if local_conf_dir == @DEFAULT_LOCAL_CONF_DIR
|
68
|
+
put conf,@DEFAULT_LOCAL_CONF_DIR+'/mongrel.yml'
|
69
|
+
else
|
70
|
+
if exists?(:runner) && fetch(:runner) != fetch(:user)
|
71
|
+
put_with_power conf, local_conf_dir+'/'+fetch(:application)+'.conf', fetch(:runner)
|
72
|
+
else
|
73
|
+
put conf, local_conf_dir+'/'+fetch(:application)+'.conf'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
def number_of_instances
|
80
|
+
1
|
81
|
+
end
|
82
|
+
end
|
data/lib/locales/en.yml
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
"en":
|
2
|
+
apache_only_supported: "At the moment only Apache is supported"
|
3
|
+
application_url: "Application URL"
|
4
|
+
apache_conf_directory: "Directory where Apache finds the websites config"
|
5
|
+
passenger_or_mongrel: "Does your application use Passenger or Mongrel"
|
6
|
+
mongrel_local_conf: "Where you want the '.yml' config file to be?"
|
7
|
+
mongrel_cluster: "Is it a Mongrel Cluster?"
|
8
|
+
single_mongrel_selected: "Single Mongrel Instance selected"
|
9
|
+
mongrel_port: "Which port would you like to use?"
|
10
|
+
cluster_mongrel_selected: "Mongrel Cluster selected"
|
11
|
+
number_of_mongrel_instance: "How many instances of Mongrel do you want"
|
12
|
+
mongrel_multiple_port: "Which port would you like to use? The others ports will be the ones following"
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: capistrano_auto_multi_install
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stefano Grioni
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-01-16 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: capistrano
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.0.0
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: i18n
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: yamler
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
description:
|
46
|
+
email: stefano_dot_grioni_at.gmail_dot_com
|
47
|
+
executables: []
|
48
|
+
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
extra_rdoc_files: []
|
52
|
+
|
53
|
+
files:
|
54
|
+
- tests/test_helper.rb
|
55
|
+
- tests/capistrano_auto_multi_install_test.rb
|
56
|
+
- lib/locales/en.yml
|
57
|
+
- lib/capistrano_auto_multi_install.rb
|
58
|
+
- lib/capistrano_auto_multi_install/passenger.conf.erb
|
59
|
+
- lib/capistrano_auto_multi_install/configure_web_server.rb
|
60
|
+
- lib/capistrano_auto_multi_install/handlers.rb
|
61
|
+
- lib/capistrano_auto_multi_install/database.yml.erb
|
62
|
+
- lib/capistrano_auto_multi_install/server.rb
|
63
|
+
- lib/capistrano_auto_multi_install/mongrel.conf.erb
|
64
|
+
- lib/capistrano_auto_multi_install/configure_database.rb
|
65
|
+
- tasks/capistrano_auto_multi_install_tasks.rake
|
66
|
+
has_rdoc: true
|
67
|
+
homepage:
|
68
|
+
licenses: []
|
69
|
+
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "0"
|
80
|
+
version:
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: "0"
|
86
|
+
version:
|
87
|
+
requirements: []
|
88
|
+
|
89
|
+
rubyforge_project:
|
90
|
+
rubygems_version: 1.3.5
|
91
|
+
signing_key:
|
92
|
+
specification_version: 3
|
93
|
+
summary: A set of tasks helping you to deploy with capistrano
|
94
|
+
test_files: []
|
95
|
+
|