mdh-ec2onrails 0.9.10

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