arpitjain11-ec2onrails 0.9.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. data/CHANGELOG +180 -0
  2. data/COPYING +339 -0
  3. data/Manifest +162 -0
  4. data/README.textile +214 -0
  5. data/Rakefile +36 -0
  6. data/TODO +102 -0
  7. data/ec2onrails.gemspec +42 -0
  8. data/examples/Capfile +3 -0
  9. data/examples/deploy.rb +101 -0
  10. data/examples/s3.yml +9 -0
  11. data/lib/ec2onrails.rb +20 -0
  12. data/lib/ec2onrails/capistrano_utils.rb +43 -0
  13. data/lib/ec2onrails/recipes.rb +844 -0
  14. data/lib/ec2onrails/version.rb +31 -0
  15. data/server/build-ec2onrails.sh +44 -0
  16. data/server/files/etc/aliases +5 -0
  17. data/server/files/etc/aliases.db +0 -0
  18. data/server/files/etc/apache2/apache2.conf +295 -0
  19. data/server/files/etc/apache2/conf.d/app.proxy_cluster.conf +7 -0
  20. data/server/files/etc/apache2/conf.d/app.proxy_frontend.conf +10 -0
  21. data/server/files/etc/apache2/mods-available/proxy.conf +18 -0
  22. data/server/files/etc/apache2/sites-available/app.common +56 -0
  23. data/server/files/etc/apache2/sites-available/app.custom +0 -0
  24. data/server/files/etc/apache2/sites-available/default +14 -0
  25. data/server/files/etc/apache2/sites-available/default-ssl +19 -0
  26. data/server/files/etc/cron.d/backup_app_db_to_s3 +16 -0
  27. data/server/files/etc/cron.daily/app +9 -0
  28. data/server/files/etc/cron.daily/logrotate_post +19 -0
  29. data/server/files/etc/cron.hourly/app +10 -0
  30. data/server/files/etc/cron.monthly/app +10 -0
  31. data/server/files/etc/cron.weekly/app +10 -0
  32. data/server/files/etc/denyhosts.conf +628 -0
  33. data/server/files/etc/dpkg/dpkg.cfg +13 -0
  34. data/server/files/etc/ec2onrails/README +32 -0
  35. data/server/files/etc/ec2onrails/balancer_members +6 -0
  36. data/server/files/etc/ec2onrails/roles.yml +5 -0
  37. data/server/files/etc/environment +2 -0
  38. data/server/files/etc/god/app.god +35 -0
  39. data/server/files/etc/god/db.god +17 -0
  40. data/server/files/etc/god/examples/have_god_daemonize.god +18 -0
  41. data/server/files/etc/god/master.conf +35 -0
  42. data/server/files/etc/god/memcache.god +15 -0
  43. data/server/files/etc/god/notifications.god +14 -0
  44. data/server/files/etc/god/system.god +34 -0
  45. data/server/files/etc/god/web.god +36 -0
  46. data/server/files/etc/init.d/ec2-every-startup +29 -0
  47. data/server/files/etc/init.d/ec2-first-startup +36 -0
  48. data/server/files/etc/init.d/god +42 -0
  49. data/server/files/etc/init.d/nginx +78 -0
  50. data/server/files/etc/init.d/set_roles +3 -0
  51. data/server/files/etc/logrotate.d/apache2 +16 -0
  52. data/server/files/etc/logrotate.d/mongrel +11 -0
  53. data/server/files/etc/logrotate.d/nginx +11 -0
  54. data/server/files/etc/memcached.conf +47 -0
  55. data/server/files/etc/mongrel_cluster/app.yml +9 -0
  56. data/server/files/etc/motd.tail +13 -0
  57. data/server/files/etc/mysql/my.cnf +152 -0
  58. data/server/files/etc/nginx/nginx.conf +296 -0
  59. data/server/files/etc/postfix/main.cf +4 -0
  60. data/server/files/etc/rcS.d/S91ec2-first-startup +1 -0
  61. data/server/files/etc/rcS.d/S92ec2-every-startup +1 -0
  62. data/server/files/etc/rcS.d/S99set_roles +1 -0
  63. data/server/files/etc/ssh/sshd_config +94 -0
  64. data/server/files/etc/sudoers +1 -0
  65. data/server/files/etc/sudoers.full_access +26 -0
  66. data/server/files/etc/sudoers.restricted_access +28 -0
  67. data/server/files/etc/syslog.conf +69 -0
  68. data/server/files/usr/bin/god +26 -0
  69. data/server/files/usr/local/ec2onrails/COPYING +339 -0
  70. data/server/files/usr/local/ec2onrails/bin/archive_file.rb +44 -0
  71. data/server/files/usr/local/ec2onrails/bin/backup_app_db.rb +159 -0
  72. data/server/files/usr/local/ec2onrails/bin/ec2_meta_data.rb +80 -0
  73. data/server/files/usr/local/ec2onrails/bin/exec_runner +73 -0
  74. data/server/files/usr/local/ec2onrails/bin/init_services.rb +64 -0
  75. data/server/files/usr/local/ec2onrails/bin/optimize_mysql.rb +348 -0
  76. data/server/files/usr/local/ec2onrails/bin/rails_env +35 -0
  77. data/server/files/usr/local/ec2onrails/bin/rebundle.sh +70 -0
  78. data/server/files/usr/local/ec2onrails/bin/restore_app_db.rb +58 -0
  79. data/server/files/usr/local/ec2onrails/bin/set_rails_env +40 -0
  80. data/server/files/usr/local/ec2onrails/bin/set_roles.rb +87 -0
  81. data/server/files/usr/local/ec2onrails/bin/setup_web_proxy.rb +109 -0
  82. data/server/files/usr/local/ec2onrails/config +30 -0
  83. data/server/files/usr/local/ec2onrails/lib/aws_helper.rb +76 -0
  84. data/server/files/usr/local/ec2onrails/lib/god_helper.rb +129 -0
  85. data/server/files/usr/local/ec2onrails/lib/god_patch.rb +43 -0
  86. data/server/files/usr/local/ec2onrails/lib/mysql_helper.rb +101 -0
  87. data/server/files/usr/local/ec2onrails/lib/roles_helper.rb +151 -0
  88. data/server/files/usr/local/ec2onrails/lib/s3_helper.rb +99 -0
  89. data/server/files/usr/local/ec2onrails/lib/utils.rb +16 -0
  90. data/server/files/usr/local/ec2onrails/lib/vendor/ini.rb +268 -0
  91. data/server/files/usr/local/ec2onrails/startup-scripts/every-startup/get-hostname.sh +25 -0
  92. data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/README +5 -0
  93. data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/create-dirs.sh +39 -0
  94. data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/generate-default-web-cert-and-key.sh +49 -0
  95. data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/misc.sh +27 -0
  96. data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/prepare-mysql-data-dir.sh +24 -0
  97. data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/setup-credentials.sh +29 -0
  98. data/server/files/usr/local/ec2onrails/startup-scripts/first-startup/setup-file-permissions.sh +30 -0
  99. data/server/rakefile.rb +248 -0
  100. data/setup.rb +1585 -0
  101. data/test/autobench.conf +60 -0
  102. data/test/spec/lib/s3_helper_spec.rb +134 -0
  103. data/test/spec/lib/s3_old.yml +3 -0
  104. data/test/spec/test_files/test1 +0 -0
  105. data/test/spec/test_files/test2 +0 -0
  106. data/test/test_app/Capfile +3 -0
  107. data/test/test_app/README +182 -0
  108. data/test/test_app/Rakefile +10 -0
  109. data/test/test_app/app/controllers/application.rb +7 -0
  110. data/test/test_app/app/controllers/db_fast_controller.rb +6 -0
  111. data/test/test_app/app/controllers/fast_controller.rb +5 -0
  112. data/test/test_app/app/controllers/slow_controller.rb +6 -0
  113. data/test/test_app/app/controllers/very_slow_controller.rb +6 -0
  114. data/test/test_app/app/helpers/application_helper.rb +3 -0
  115. data/test/test_app/app/helpers/db_fast_helper.rb +2 -0
  116. data/test/test_app/app/helpers/fast_helper.rb +2 -0
  117. data/test/test_app/app/helpers/slow_helper.rb +2 -0
  118. data/test/test_app/app/helpers/very_slow_helper.rb +2 -0
  119. data/test/test_app/config/boot.rb +109 -0
  120. data/test/test_app/config/database.yml +19 -0
  121. data/test/test_app/config/deploy.rb +21 -0
  122. data/test/test_app/config/environment.rb +60 -0
  123. data/test/test_app/config/environments/development.rb +21 -0
  124. data/test/test_app/config/environments/production.rb +18 -0
  125. data/test/test_app/config/environments/test.rb +19 -0
  126. data/test/test_app/config/routes.rb +27 -0
  127. data/test/test_app/db/schema.rb +7 -0
  128. data/test/test_app/doc/README_FOR_APP +2 -0
  129. data/test/test_app/public/404.html +30 -0
  130. data/test/test_app/public/500.html +30 -0
  131. data/test/test_app/public/dispatch.cgi +10 -0
  132. data/test/test_app/public/dispatch.fcgi +24 -0
  133. data/test/test_app/public/dispatch.rb +10 -0
  134. data/test/test_app/public/favicon.ico +0 -0
  135. data/test/test_app/public/images/rails.png +0 -0
  136. data/test/test_app/public/javascripts/application.js +2 -0
  137. data/test/test_app/public/javascripts/controls.js +963 -0
  138. data/test/test_app/public/javascripts/dragdrop.js +972 -0
  139. data/test/test_app/public/javascripts/effects.js +1120 -0
  140. data/test/test_app/public/javascripts/prototype.js +4225 -0
  141. data/test/test_app/public/robots.txt +1 -0
  142. data/test/test_app/script/about +3 -0
  143. data/test/test_app/script/breakpointer +3 -0
  144. data/test/test_app/script/console +3 -0
  145. data/test/test_app/script/destroy +3 -0
  146. data/test/test_app/script/generate +3 -0
  147. data/test/test_app/script/performance/benchmarker +3 -0
  148. data/test/test_app/script/performance/profiler +3 -0
  149. data/test/test_app/script/performance/request +3 -0
  150. data/test/test_app/script/plugin +3 -0
  151. data/test/test_app/script/process/inspector +3 -0
  152. data/test/test_app/script/process/reaper +3 -0
  153. data/test/test_app/script/process/spawner +3 -0
  154. data/test/test_app/script/runner +3 -0
  155. data/test/test_app/script/server +3 -0
  156. data/test/test_app/test/functional/db_fast_controller_test.rb +18 -0
  157. data/test/test_app/test/functional/fast_controller_test.rb +18 -0
  158. data/test/test_app/test/functional/slow_controller_test.rb +18 -0
  159. data/test/test_app/test/functional/very_slow_controller_test.rb +18 -0
  160. data/test/test_app/test/test_helper.rb +28 -0
  161. data/test/test_ec2onrails.rb +11 -0
  162. data/test/test_helper.rb +2 -0
  163. metadata +278 -0
@@ -0,0 +1,129 @@
1
+ module GodHelper
2
+ require '/usr/local/ec2onrails/lib/roles_helper'
3
+ require 'fileutils'
4
+
5
+ def default_configurations(w)
6
+ w.interval = 30.seconds
7
+ w.grace = 30.seconds
8
+
9
+
10
+ w.behavior(:clean_pid_file)
11
+
12
+ w.start_if do |start|
13
+ start.condition(:process_running) do |c|
14
+ c.notify = {:contacts => ['default'], :category => 'process not started...starting'}
15
+ c.interval = 5.seconds
16
+ c.running = false
17
+ end
18
+ end
19
+
20
+ # w.start_if do |start|
21
+ # start.condition(:process_running) do |c|
22
+ # c.interval = 5.seconds
23
+ # c.running = false
24
+ # c.notify = {:contacts => ['default'], :category => 'process exited...restarting'}
25
+ # end
26
+ # end
27
+
28
+ # determine when process has finished starting
29
+ # w.transition([:start, :restart], :up) do |on|
30
+ # on.condition(:process_running) do |c|
31
+ # c.running = true
32
+ # end
33
+ #
34
+ # # failsafe
35
+ # on.condition(:tries) do |c|
36
+ # c.times = 8
37
+ # c.within = 2.minutes
38
+ # c.transition = :start
39
+ # end
40
+ # end
41
+ #
42
+ # # start if process is not running
43
+ # w.transition(:up, :start) do |on|
44
+ # on.condition(:process_exits) do |c|
45
+ # c.notify = {:contacts => ['default'], :category => 'process exited...restarting'}
46
+ # end
47
+ # end
48
+ end
49
+
50
+ def restart_if_resource_hog(w, options={})
51
+ options = {:memory_usage => 175.megabytes, :cpu_usage => 50.percent}.merge(options)
52
+ w.restart_if do |restart|
53
+ if options[:memory_usage]
54
+ restart.condition(:memory_usage) do |c|
55
+ c.notify = {:contacts => ['default'], :category => "process over #{options[:memory_usage]/1.megabyte}MB. restarting"}
56
+ c.above = options[:memory_usage]
57
+ c.times = [3,5]
58
+ end
59
+ end
60
+
61
+ if options[:cpu_usage]
62
+ restart.condition(:cpu_usage) do |c|
63
+ c.notify = {:contacts => ['default'], :category => "process over #{options[:cpu_usage]*100}%. restarting"}
64
+ c.above = options[:cpu_usage]
65
+ c.times = 5
66
+ end
67
+ end
68
+
69
+ yield restart if block_given?
70
+
71
+ end
72
+ end
73
+
74
+ def create_pid_dir(w)
75
+ pid_dir = File.dirname(w.pid_file)
76
+ return if File.exist?(pid_dir)
77
+
78
+ #we need to make sure it is writable...but include all the directories we created...
79
+ starting_dir = pid_dir
80
+ starting_dir = File.dirname(starting_dir) until File.exist?(File.dirname(starting_dir))
81
+
82
+ FileUtils.mkdir_p(pid_dir)
83
+ FileUtils.chown_R(w.uid, w.gid, starting_dir)
84
+ end
85
+
86
+ def monitor_lifecycle(w)
87
+ # w.transition(:up, :unmonitored) do |on|
88
+ w.lifecycle do |on|
89
+ on.condition(:flapping) do |c|
90
+ c.notify = {:contacts => ['default'], :category => 'process flapping...restarting'}
91
+ c.to_state = [:start, :restart]
92
+ c.times = 5
93
+ c.within = 5.minutes
94
+ c.transition = :unmonitored
95
+ c.retry_in = 10.minutes
96
+ c.retry_times = 5
97
+ c.retry_within = 2.hours
98
+ end
99
+ end
100
+ # w.lifecycle do |on|
101
+ # on.condition(:flapping) do |c|
102
+ # c.notify = {:contacts => ['default'], :category => 'process flapping...restarting'}
103
+ # c.to_state = [:start, :restart]
104
+ # c.times = 5
105
+ # c.within = 60.seconds
106
+ # c.retry_in = 10.minutes
107
+ # c.retry_times = 5
108
+ # c.retry_within = 2.hours
109
+ # end
110
+ # end
111
+
112
+ # w.lifecycle do |on|
113
+ # on.condition(:flapping) do |c|
114
+ # c.to_state = [:start, :restart]
115
+ # c.times = 5
116
+ # c.within = 5.minutes
117
+ # c.transition = :unmonitored
118
+ # c.retry_in = 10.minutes
119
+ # c.retry_times = 5
120
+ # c.retry_within = 2.hours
121
+ # end
122
+ # end
123
+ end
124
+
125
+ class Configs
126
+ include Ec2onrails::RolesHelper
127
+ end
128
+
129
+ end
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'god'
3
+
4
+ # this is a hack to put the bin directory back at the top of the load path....
5
+ # the /usr/bin/god script will try to load 'god', which is in the bin path of the gem
6
+ # but is also the name of the module.... it should really be called something like god_bin
7
+ # or god_cli, so then it would have no problem being found.
8
+ $:.unshift File.join($:[0], *%w[.. .. bin])
9
+
10
+ module God
11
+ def self.control(name, command)
12
+ # get the list of items
13
+ items = Array(self.watches[name] || self.groups[name]).dup
14
+
15
+ jobs = []
16
+ # do the command
17
+ case command
18
+ when "start", "monitor"
19
+ items.each { |w| jobs << Thread.new { w.monitor if w.state != :up } }
20
+ when "restart"
21
+ items.each { |w| jobs << Thread.new { w.move(:restart) } }
22
+ when "stop"
23
+ # items.each { |w| jobs << Thread.new { w.unmonitor.action(:stop) if w.state != :unmonitored } }
24
+ items.each do |w|
25
+ jobs << Thread.new do
26
+ w.unmonitor if w.state != :unmonitored
27
+ w.action(:stop) if w.alive?
28
+ end
29
+ end
30
+ when "unmonitor"
31
+ items.each { |w| jobs << Thread.new { w.unmonitor if w.state != :unmonitored } }
32
+ when "remove"
33
+ items.each { |w| self.unwatch(w) }
34
+ else
35
+ raise InvalidCommandError.new
36
+ end
37
+
38
+ jobs.each { |j| j.join }
39
+
40
+ items.map { |x| x.name }
41
+ end
42
+
43
+ end
@@ -0,0 +1,101 @@
1
+ # This file is part of EC2 on Rails.
2
+ # http://rubyforge.org/projects/ec2onrails/
3
+ #
4
+ # Copyright 2007 Paul Dowman, http://pauldowman.com/
5
+ #
6
+ # EC2 on Rails is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # EC2 on Rails is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ require 'rubygems'
20
+ require 'aws/s3'
21
+ require 'yaml'
22
+ require 'erb'
23
+ require 'fileutils'
24
+ require "#{File.dirname(__FILE__)}/utils"
25
+
26
+ module Ec2onrails
27
+ class MysqlHelper
28
+
29
+ DEFAULT_CONFIG_FILE = "/mnt/app/current/config/database.yml"
30
+
31
+ attr_accessor :database
32
+ attr_accessor :user
33
+ attr_accessor :password
34
+
35
+ def initialize(config_file = DEFAULT_CONFIG_FILE, rails_env = Utils.rails_env)
36
+ @rails_env = rails_env
37
+ load_db_config(config_file)
38
+ end
39
+
40
+ def load_db_config(config_file)
41
+ db_config = YAML::load(ERB.new(File.read(config_file)).result)
42
+ if db_config && db_config[@rails_env].nil?
43
+ puts "the rails environment '#{@rails_env}' was not found in this db onfig file: #{config_file}"
44
+ end
45
+ db_config = db_config[@rails_env]
46
+ @database = db_config['database']
47
+ @user = db_config['username']
48
+ @password = db_config['password']
49
+ end
50
+
51
+ def execute_sql(sql)
52
+ raise "@user not set" unless @user
53
+ raise "sql not given" unless sql
54
+ cmd = %{mysql -u #{@user} -e "#{sql}"}
55
+ cmd += " -p'#{@password}' " unless @password.nil?
56
+ Utils.run cmd
57
+ end
58
+
59
+ def execute
60
+ require "mysql"
61
+
62
+ begin
63
+ # connect to the MySQL server
64
+ dbh = Mysql.real_connect("localhost", "#{@user}", "#{@password}", "#{@database}")
65
+ yield dbh
66
+ rescue Mysql::Error => e
67
+ puts "Error code: #{e.errno}"
68
+ puts "Error message: #{e.error}"
69
+ puts "Error SQLSTATE: #{e.sqlstate}" if e.respond_to?("sqlstate")
70
+ ensure
71
+ # disconnect from server
72
+ dbh.close if dbh
73
+ end
74
+
75
+
76
+ end
77
+
78
+ def dump(out_file, reset_logs)
79
+ cmd = "mysqldump --quick --single-transaction --create-options -u#{@user} "
80
+ if reset_logs
81
+ cmd += " --flush-logs --master-data=2 --delete-master-logs "
82
+ end
83
+ cmd += " -p'#{@password}' " unless @password.nil?
84
+ cmd += " #{@database} | gzip > #{out_file}"
85
+ Utils.run cmd
86
+ end
87
+
88
+ def load_from_dump(in_file)
89
+ cmd = "gunzip -c #{in_file} | mysql -u#{@user} "
90
+ cmd += " -p'#{@password}' " unless @password.nil?
91
+ cmd += " #{@database}"
92
+ Utils.run cmd
93
+ end
94
+
95
+ def execute_binary_log(log_file)
96
+ cmd = "mysqlbinlog --database=#{@database} #{log_file} | mysql -u#{@user} "
97
+ cmd += " -p'#{@password}' " unless @password.nil?
98
+ Utils.run cmd
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,151 @@
1
+ # This file is part of EC2 on Rails.
2
+ # http://rubyforge.org/projects/ec2onrails/
3
+ #
4
+ # Copyright 2007 Paul Dowman, http://pauldowman.com/
5
+ #
6
+ # EC2 on Rails is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # EC2 on Rails is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ require 'net/http'
20
+ require 'pp'
21
+ require 'socket'
22
+ require 'yaml'
23
+ require 'erb'
24
+
25
+ module Ec2onrails
26
+ module RolesHelper
27
+ ROLES_FILE = "/etc/ec2onrails/roles.yml"
28
+ MONGREL_CONF_FILE = "/etc/mongrel_cluster/app.yml"
29
+
30
+ def local_address
31
+ @local_address ||= get_metadata "local-ipv4"
32
+ end
33
+
34
+ def public_address
35
+ @public_address ||= get_metadata "public-ipv4"
36
+ end
37
+
38
+ def roles
39
+ @roles ||= resolve_all_addresses(YAML::load_file(ROLES_FILE))
40
+ end
41
+
42
+ def start(role, service, prog_name = service)
43
+ puts "STARTING #{role} role (service: #{service}, program_name: #{prog_name})"
44
+ sudo "god start #{role}"
45
+ # sudo "god monitor #{role}"
46
+ end
47
+
48
+ def stop(role, service, prog_name = service)
49
+ puts "STOPING #{role} role (service: #{service}, program_name: #{prog_name})"
50
+ # sudo "god monitor #{role}"
51
+ sudo "god stop #{role}"
52
+ end
53
+
54
+ def run(cmd)
55
+ result = system(cmd)
56
+ puts("*****ERROR: #{cmd} returned #{$?}") unless result
57
+ end
58
+
59
+ def sudo(cmd)
60
+ run("sudo #{cmd}")
61
+ end
62
+
63
+ def get_metadata(type)
64
+ data = Net::HTTP.get('169.254.169.254', "/latest/meta-data/#{type}").strip
65
+
66
+ raise "couldn't get instance data: #{type}" if data.nil? || data.strip.length == 0
67
+ # puts "#{type}: #{address}"
68
+ return data
69
+ end
70
+
71
+ def resolve(hostname)
72
+ address = IPSocket.getaddress(hostname).strip
73
+ if address == local_address || address == public_address
74
+ "127.0.0.1"
75
+ else
76
+ address
77
+ end
78
+ rescue Exception => e
79
+ puts "couldn't resolve hostname '#{hostname}'"
80
+ raise e
81
+ end
82
+
83
+ def resolve_all_addresses(original)
84
+ resolved = {}
85
+ original.each do |rolename, hostnames|
86
+ resolved[rolename] = hostnames.map{|hostname| resolve(hostname)} if hostnames
87
+ end
88
+ resolved
89
+ end
90
+
91
+ def in_role?(role)
92
+ return false unless roles[role]
93
+ return roles[role].include?("127.0.0.1")
94
+ end
95
+ #to provide deprecated usage
96
+ alias :in_role :in_role?
97
+
98
+
99
+ def add_etc_hosts_entry(entry_name, entry_addr)
100
+ host_file = "/etc/hosts"
101
+ run("cp #{host_file}.original #{host_file}") unless File.exists?("#{host_file}.original")
102
+ hosts = File.read(host_file)
103
+ if hosts =~ /\s*.+?\s+#{entry_name}\s*$/
104
+ hosts.sub!(/\s*.+?\s+#{entry_name}\s*$/, "\n#{entry_addr}\t#{entry_name}\n")
105
+ else
106
+ puts "adding '#{entry_addr}\t#{entry_name}' to /etc/hosts"
107
+ hosts << "\n#{entry_addr}\t#{entry_name}\n"
108
+ end
109
+ File.open(host_file, 'w') {|f| f.write(hosts) }
110
+ end
111
+
112
+ def web_starting_port
113
+ mongrel_config['port'].to_i rescue 8000
114
+ end
115
+
116
+ def web_num_instances
117
+ mongrel_config['servers'].to_i rescue 6
118
+ end
119
+
120
+ def web_port_range
121
+ (web_starting_port..(web_starting_port + web_num_instances-1))
122
+ end
123
+
124
+ def server_environment
125
+ mongrel_config["environment"]
126
+ end
127
+
128
+ def user
129
+ mongrel_config['user']
130
+ end
131
+
132
+ def group
133
+ mongrel_config['group']
134
+ end
135
+
136
+ def application_root
137
+ mongrel_config['cwd']
138
+ end
139
+
140
+ def pid_file
141
+ "#{application_root}/#{mongrel_config['pid_file']}"
142
+ end
143
+
144
+ private
145
+
146
+ def mongrel_config
147
+ @mongrel_config ||= YAML::load_file(MONGREL_CONF_FILE)
148
+ end
149
+
150
+ end
151
+ end
@@ -0,0 +1,99 @@
1
+ # This file is part of EC2 on Rails.
2
+ # http://rubyforge.org/projects/ec2onrails/
3
+ #
4
+ # Copyright 2007 Paul Dowman, http://pauldowman.com/
5
+ #
6
+ # EC2 on Rails is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # EC2 on Rails is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ require 'rubygems'
20
+ require 'aws/s3'
21
+ require 'yaml'
22
+ require 'erb'
23
+ require 'fileutils'
24
+ require "#{File.dirname(__FILE__)}/utils"
25
+ require "#{File.dirname(__FILE__)}/aws_helper"
26
+
27
+ module Ec2onrails
28
+ class S3Helper
29
+
30
+ # make attributes available for specs
31
+ attr_accessor :bucket
32
+ attr_accessor :dir
33
+ attr_accessor :config_file
34
+ attr_accessor :rails_env
35
+ attr_accessor :aws_access_key
36
+ attr_accessor :aws_secret_access_key
37
+ attr_accessor :bucket
38
+
39
+ def initialize(bucket, dir, config_file = Ec2onrails::AwsHelper.default_config_file, rails_env = Utils.rails_env)
40
+ @dir = dir
41
+ @config_file = config_file
42
+ @rails_env = rails_env
43
+ @awsHelper = Ec2onrails::AwsHelper.new(config_file, rails_env)
44
+ @aws_access_key = @awsHelper.aws_access_key
45
+ @aws_secret_access_key = @awsHelper.aws_secret_access_key
46
+ @bucket_base_name = @awsHelper.bucket_base_name
47
+ @bucket = bucket || "#{@bucket_base_name}-#{Ec2onrails::Utils.hostname}"
48
+ AWS::S3::Base.establish_connection!(:access_key_id => @aws_access_key, :secret_access_key => @aws_secret_access_key, :use_ssl => true)
49
+ end
50
+
51
+ def create_bucket
52
+ retries = 0
53
+ begin
54
+ AWS::S3::Bucket.find(@bucket)
55
+ rescue AWS::S3::NoSuchBucket
56
+ AWS::S3::Bucket.create(@bucket)
57
+ sleep 1 # If we try to use the bucket too quickly sometimes it's not found
58
+ retry if (retries += 1) < 15
59
+ end
60
+ end
61
+
62
+ def store_file(file)
63
+ create_bucket
64
+ AWS::S3::S3Object.store(s3_key(file), open(file), @bucket)
65
+ end
66
+
67
+ def retrieve_file(file)
68
+ key = s3_key(file)
69
+ AWS::S3::S3Object.find(key, @bucket)
70
+ open(file, 'w') do |f|
71
+ AWS::S3::S3Object.stream(key, @bucket) do |chunk|
72
+ f.write chunk
73
+ end
74
+ end
75
+ end
76
+
77
+ def list_keys(filename_prefix)
78
+ prefix = @dir ? "#{@dir}/#{filename_prefix}" : filename_prefix
79
+ AWS::S3::Bucket.objects(@bucket, :prefix => prefix).collect{|obj| obj.key}
80
+ end
81
+
82
+ def retrieve_files(filename_prefix, local_dir)
83
+ list_keys(filename_prefix).each do |k|
84
+ file = "#{local_dir}/#{File.basename(k)}"
85
+ retrieve_file(file)
86
+ end
87
+ end
88
+
89
+ def delete_files(filename_prefix)
90
+ list_keys(filename_prefix).each do |k|
91
+ AWS::S3::S3Object.delete(k, @bucket)
92
+ end
93
+ end
94
+
95
+ def s3_key(file)
96
+ @dir ? "#{@dir}/#{File.basename(file)}" : File.basename(file)
97
+ end
98
+ end
99
+ end