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.
@@ -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
+