capistrano_auto_multi_install 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,6 @@
1
+ production:
2
+ adapter: mysql
3
+ database: #{application}_production
4
+ username: #{mysql_user}
5
+ password: #{mysql_password}
6
+ encoding: utf8
@@ -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,9 @@
1
+ port: "#{port}"
2
+ cwd: "#{base_directory}"
3
+ log_file: log/mongrel
4
+ environment: production
5
+ address: 127.0.0.1
6
+ pid_file: log/mongrel.pid
7
+ servers #{number_of_instances}
8
+ docroot: public
9
+ user: #{web_user}
@@ -0,0 +1,10 @@
1
+ <Virtualhost *:80>
2
+ DocumentRoot <%=document_root%>
3
+ ServerName <%=server_name%>
4
+ PassengerTempDir <%=passenger_tmp%>
5
+ <Directory <%=document_root%> >
6
+ AllowOverride all
7
+ Order allow,deny
8
+ Allow from all
9
+ </Directory>
10
+ </Virtualhost>
@@ -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
@@ -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"
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :capistrano_auto_multi_install do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class CapistranoAutoMultiInstallTest < ActiveSupport::TestCase
4
+ # Replace this with your real tests.
5
+ test "the truth" do
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require 'active_support/test_case'
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
+