capistrano_auto_multi_install 1.0.1
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.
- 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
|
+
|