rubber 1.0.2

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 +39 -0
  2. data/COPYING +339 -0
  3. data/README +6 -0
  4. data/TODO +11 -0
  5. data/VERSION +1 -0
  6. data/bin/vulcanize +41 -0
  7. data/generators/vulcanize/USAGE +6 -0
  8. data/generators/vulcanize/templates/apache/config/rubber/deploy-apache.rb +51 -0
  9. data/generators/vulcanize/templates/apache/config/rubber/role/apache/deflate.conf +10 -0
  10. data/generators/vulcanize/templates/apache/config/rubber/role/apache/expires.conf +9 -0
  11. data/generators/vulcanize/templates/apache/config/rubber/role/apache/headers.conf +6 -0
  12. data/generators/vulcanize/templates/apache/config/rubber/role/apache/monit-apache.conf +8 -0
  13. data/generators/vulcanize/templates/apache/config/rubber/role/apache/ports.conf +5 -0
  14. data/generators/vulcanize/templates/apache/config/rubber/role/apache/setenvif.conf +52 -0
  15. data/generators/vulcanize/templates/apache/config/rubber/role/web_tools/tools-apache-vhost.conf +62 -0
  16. data/generators/vulcanize/templates/apache/config/rubber/role/web_tools/tools-apache.auth +7 -0
  17. data/generators/vulcanize/templates/apache/config/rubber/role/web_tools/tools-index.html +30 -0
  18. data/generators/vulcanize/templates/apache/config/rubber/rubber-apache.yml +7 -0
  19. data/generators/vulcanize/templates/apache/templates.yml +1 -0
  20. data/generators/vulcanize/templates/base/Capfile +14 -0
  21. data/generators/vulcanize/templates/base/config/deploy.rb +55 -0
  22. data/generators/vulcanize/templates/base/config/rubber/common/crontab +16 -0
  23. data/generators/vulcanize/templates/base/config/rubber/common/profile.rc +9 -0
  24. data/generators/vulcanize/templates/base/config/rubber/deploy-setup.rb +104 -0
  25. data/generators/vulcanize/templates/base/config/rubber/rubber.yml +241 -0
  26. data/generators/vulcanize/templates/base/lib/tasks/rubber.rake +15 -0
  27. data/generators/vulcanize/templates/base/script/cron-rake +18 -0
  28. data/generators/vulcanize/templates/base/script/cron-runner +18 -0
  29. data/generators/vulcanize/templates/base/script/cron-sh +67 -0
  30. data/generators/vulcanize/templates/base/templates.yml +1 -0
  31. data/generators/vulcanize/templates/complete_mongrel_mysql/config/rubber/role/haproxy/haproxy-mongrel.conf +23 -0
  32. data/generators/vulcanize/templates/complete_mongrel_mysql/config/rubber/role/nginx/nginx-mongrel.conf +113 -0
  33. data/generators/vulcanize/templates/complete_mongrel_mysql/config/rubber/rubber-complete.yml +41 -0
  34. data/generators/vulcanize/templates/complete_mongrel_mysql/templates.yml +6 -0
  35. data/generators/vulcanize/templates/complete_passenger_mysql/config/rubber/role/haproxy/haproxy-passenger.conf +19 -0
  36. data/generators/vulcanize/templates/complete_passenger_mysql/config/rubber/rubber-complete.yml +40 -0
  37. data/generators/vulcanize/templates/complete_passenger_mysql/templates.yml +10 -0
  38. data/generators/vulcanize/templates/cruise/config/rubber/deploy-cruise.rb +72 -0
  39. data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/cruise +40 -0
  40. data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/my.cnf +165 -0
  41. data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/production.rb +8 -0
  42. data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/site_config.rb +76 -0
  43. data/generators/vulcanize/templates/cruise/config/rubber/role/web_tools/cruise-nginx.conf +11 -0
  44. data/generators/vulcanize/templates/cruise/config/rubber/rubber-cruise.yml +18 -0
  45. data/generators/vulcanize/templates/cruise/templates.yml +1 -0
  46. data/generators/vulcanize/templates/haproxy/config/rubber/deploy-haproxy.rb +45 -0
  47. data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/haproxy-base.conf +26 -0
  48. data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/haproxy-default.conf +8 -0
  49. data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/monit-haproxy.conf +9 -0
  50. data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/syslog-haproxy.conf +6 -0
  51. data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/syslogd-default.conf +17 -0
  52. data/generators/vulcanize/templates/haproxy/config/rubber/role/web_tools/haproxy-nginx.conf +10 -0
  53. data/generators/vulcanize/templates/haproxy/config/rubber/rubber-haproxy.yml +7 -0
  54. data/generators/vulcanize/templates/haproxy/templates.yml +1 -0
  55. data/generators/vulcanize/templates/memcached/config/memcached.yml +28 -0
  56. data/generators/vulcanize/templates/memcached/config/rubber/common/memcached.yml +14 -0
  57. data/generators/vulcanize/templates/memcached/config/rubber/role/memcached/memcached.conf +52 -0
  58. data/generators/vulcanize/templates/memcached/config/rubber/role/memcached/memcached_munin_plugin +249 -0
  59. data/generators/vulcanize/templates/memcached/config/rubber/rubber-memcached.yml +7 -0
  60. data/generators/vulcanize/templates/memcached/templates.yml +1 -0
  61. data/generators/vulcanize/templates/minimal_mysql/templates.yml +7 -0
  62. data/generators/vulcanize/templates/minimal_nodb/templates.yml +6 -0
  63. data/generators/vulcanize/templates/mongrel/config/rubber/deploy-mongrel.rb +75 -0
  64. data/generators/vulcanize/templates/mongrel/config/rubber/role/mongrel/mongrel_cluster.yml +12 -0
  65. data/generators/vulcanize/templates/mongrel/config/rubber/role/mongrel/monit-mongrel.conf +20 -0
  66. data/generators/vulcanize/templates/mongrel/config/rubber/rubber-mongrel.yml +9 -0
  67. data/generators/vulcanize/templates/mongrel/templates.yml +1 -0
  68. data/generators/vulcanize/templates/monit/config/rubber/common/monit-default.conf +15 -0
  69. data/generators/vulcanize/templates/monit/config/rubber/common/monit.conf +251 -0
  70. data/generators/vulcanize/templates/monit/config/rubber/deploy-monit.rb +32 -0
  71. data/generators/vulcanize/templates/monit/config/rubber/role/web_tools/monit-admin-nginx.conf +10 -0
  72. data/generators/vulcanize/templates/monit/config/rubber/rubber-monit.yml +6 -0
  73. data/generators/vulcanize/templates/monit/templates.yml +1 -0
  74. data/generators/vulcanize/templates/munin/config/rubber/common/monit-munin.conf +8 -0
  75. data/generators/vulcanize/templates/munin/config/rubber/common/munin-node.conf +48 -0
  76. data/generators/vulcanize/templates/munin/config/rubber/deploy-munin.rb +46 -0
  77. data/generators/vulcanize/templates/munin/config/rubber/role/web_tools/munin-nginx.conf +8 -0
  78. data/generators/vulcanize/templates/munin/config/rubber/role/web_tools/munin-plugins.conf +31 -0
  79. data/generators/vulcanize/templates/munin/config/rubber/role/web_tools/munin.conf +80 -0
  80. data/generators/vulcanize/templates/munin/config/rubber/rubber-munin.yml +8 -0
  81. data/generators/vulcanize/templates/munin/script/munin/example_mysql_query.rb +57 -0
  82. data/generators/vulcanize/templates/munin/script/munin/example_simple.rb +24 -0
  83. data/generators/vulcanize/templates/munin/templates.yml +1 -0
  84. data/generators/vulcanize/templates/mysql/config/rubber/common/database.yml +11 -0
  85. data/generators/vulcanize/templates/mysql/config/rubber/deploy-mysql.rb +156 -0
  86. data/generators/vulcanize/templates/mysql/config/rubber/role/db/crontab +14 -0
  87. data/generators/vulcanize/templates/mysql/config/rubber/role/db/monit-mysql.cnf +10 -0
  88. data/generators/vulcanize/templates/mysql/config/rubber/role/db/my.cnf +167 -0
  89. data/generators/vulcanize/templates/mysql/config/rubber/role/mysql_slave/mysql_slave_munin_plugin +51 -0
  90. data/generators/vulcanize/templates/mysql/config/rubber/rubber-mysql.yml +46 -0
  91. data/generators/vulcanize/templates/mysql/templates.yml +1 -0
  92. data/generators/vulcanize/templates/mysql_cluster/config/rubber/common/mysql_cluster_migrations.rb +13 -0
  93. data/generators/vulcanize/templates/mysql_cluster/config/rubber/deploy-mysql_cluster.rb +173 -0
  94. data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_data/my.cnf +15 -0
  95. data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_mgm/ndb_mgmd.cnf +39 -0
  96. data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_sql/monit-mysql_cluster_sql.cnf +10 -0
  97. data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_sql/my.cnf +23 -0
  98. data/generators/vulcanize/templates/mysql_cluster/config/rubber/rubber-mysql_cluster.yml +32 -0
  99. data/generators/vulcanize/templates/mysql_cluster/templates.yml +1 -0
  100. data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/database.yml +16 -0
  101. data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/monit-mysql_proxy.cnf +10 -0
  102. data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/mysql-proxy +153 -0
  103. data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/mysql-proxy.conf +10 -0
  104. data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/mysql-proxy.lua +5 -0
  105. data/generators/vulcanize/templates/mysql_proxy/config/rubber/deploy-mysql_proxy.rb +52 -0
  106. data/generators/vulcanize/templates/mysql_proxy/config/rubber/rubber-mysql_proxy.yml +11 -0
  107. data/generators/vulcanize/templates/mysql_proxy/templates.yml +1 -0
  108. data/generators/vulcanize/templates/nginx/config/rubber/deploy-nginx.rb +45 -0
  109. data/generators/vulcanize/templates/nginx/config/rubber/role/nginx/crontab +9 -0
  110. data/generators/vulcanize/templates/nginx/config/rubber/role/nginx/monit-nginx.conf +8 -0
  111. data/generators/vulcanize/templates/nginx/config/rubber/role/nginx/nginx.conf +42 -0
  112. data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/nginx-tools.conf +55 -0
  113. data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/tools-index.html +30 -0
  114. data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/tools-nginx.auth +7 -0
  115. data/generators/vulcanize/templates/nginx/config/rubber/rubber-nginx.yml +10 -0
  116. data/generators/vulcanize/templates/nginx/templates.yml +1 -0
  117. data/generators/vulcanize/templates/passenger/config/rubber/deploy-passenger.rb +37 -0
  118. data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/munin-passenger-sudoers.conf +6 -0
  119. data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/munin-passenger.conf +47 -0
  120. data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/passenger-apache-vhost.conf +46 -0
  121. data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/passenger.conf +10 -0
  122. data/generators/vulcanize/templates/passenger/config/rubber/rubber-passenger.yml +12 -0
  123. data/generators/vulcanize/templates/passenger/templates.yml +1 -0
  124. data/generators/vulcanize/templates/sphinx/config/rubber/common/sphinx.yml +46 -0
  125. data/generators/vulcanize/templates/sphinx/config/rubber/deploy-sphinx.rb +112 -0
  126. data/generators/vulcanize/templates/sphinx/config/rubber/role/sphinx/crontab +11 -0
  127. data/generators/vulcanize/templates/sphinx/config/rubber/role/sphinx/monit-sphinx.conf +10 -0
  128. data/generators/vulcanize/templates/sphinx/config/rubber/rubber-sphinx.yml +6 -0
  129. data/generators/vulcanize/templates/sphinx/templates.yml +1 -0
  130. data/generators/vulcanize/vulcanize_generator.rb +67 -0
  131. data/lib/capistrano/hostcmd.rb +12 -0
  132. data/lib/rubber.rb +38 -0
  133. data/lib/rubber/capistrano.rb +1 -0
  134. data/lib/rubber/cloud.rb +13 -0
  135. data/lib/rubber/cloud/aws.rb +305 -0
  136. data/lib/rubber/cloud/base.rb +16 -0
  137. data/lib/rubber/configuration.rb +47 -0
  138. data/lib/rubber/dns.rb +13 -0
  139. data/lib/rubber/dns/base.rb +69 -0
  140. data/lib/rubber/dns/dyndns.rb +63 -0
  141. data/lib/rubber/dns/nettica.rb +73 -0
  142. data/lib/rubber/dns/zerigo.rb +131 -0
  143. data/lib/rubber/environment.rb +161 -0
  144. data/lib/rubber/generator.rb +197 -0
  145. data/lib/rubber/instance.rb +165 -0
  146. data/lib/rubber/recipes/rubber.rb +89 -0
  147. data/lib/rubber/recipes/rubber/bundles.rb +28 -0
  148. data/lib/rubber/recipes/rubber/deploy.rb +90 -0
  149. data/lib/rubber/recipes/rubber/instances.rb +348 -0
  150. data/lib/rubber/recipes/rubber/load_balancers.rb +44 -0
  151. data/lib/rubber/recipes/rubber/security_groups.rb +189 -0
  152. data/lib/rubber/recipes/rubber/setup.rb +357 -0
  153. data/lib/rubber/recipes/rubber/static_ips.rb +107 -0
  154. data/lib/rubber/recipes/rubber/utils.rb +203 -0
  155. data/lib/rubber/recipes/rubber/volumes.rb +264 -0
  156. data/lib/rubber/tasks/rubber.rb +221 -0
  157. data/lib/rubber/util.rb +37 -0
  158. data/test/environment_test.rb +118 -0
  159. data/test/generator_test.rb +323 -0
  160. data/test/instance_test.rb +93 -0
  161. data/test/test_helper.rb +4 -0
  162. data/test/util_test.rb +16 -0
  163. metadata +274 -0
@@ -0,0 +1,11 @@
1
+ <%
2
+ @read_cmd = 'crontab -l'
3
+ @write_cmd = 'crontab -'
4
+ @additive = ["# rubber-sphinx-start", "# rubber-sphinx-end"]
5
+ %>
6
+
7
+ # incremental index once every 10 minutes
8
+ */10 * * * * sudo -u rails <%= RUBBER_ROOT %>/script/cron-rake RUBBER_ENV=<%= RUBBER_ENV %> ts:in:delta
9
+
10
+ # full reindex daily at 4:35
11
+ 35 4 * * * sudo -u rails <%= RUBBER_ROOT %>/script/cron-rake RUBBER_ENV=<%= RUBBER_ENV %> ts:index
@@ -0,0 +1,10 @@
1
+ <%
2
+ @path = '/etc/monit/monit.d/monit-sphinx.conf'
3
+ %>
4
+
5
+ check process sphinx with pidfile <%= RUBBER_ROOT %>/log/searchd.<%= RUBBER_ENV %>.pid
6
+ group sphinx-<%= RUBBER_ENV %>
7
+ start program = "/usr/bin/sudo -u rails sh -c 'cd <%= RUBBER_ROOT %> && PATH=/usr/local/bin:$PATH RAILS_ENV=<%= RUBBER_ENV %> rake ts:start'"
8
+ stop program = "/usr/bin/sudo -u rails sh -c 'cd <%= RUBBER_ROOT %> && PATH=/usr/local/bin:$PATH RAILS_ENV=<%= RUBBER_ENV %> rake ts:stop'"
9
+ if failed host <%= rubber_env.host %> port 3312 with timeout 5 seconds for 5 cycles then restart
10
+
@@ -0,0 +1,6 @@
1
+ gems: []
2
+
3
+ roles:
4
+ sphinx:
5
+ packages: [bzr-builddeb, autotools-dev, dpatch, libpq-dev, autoconf,
6
+ libtool, automake, gawk, libmysqlclient15-dev]
@@ -0,0 +1 @@
1
+ description: The sphinx searchd / thinking sphinx module
@@ -0,0 +1,67 @@
1
+ require 'fileutils'
2
+ require 'find'
3
+
4
+ class VulcanizeGenerator < Rails::Generator::NamedBase
5
+
6
+ TEMPLATE_ROOT = File.dirname(__FILE__) + "/templates"
7
+ TEMPLATE_FILE = "templates.yml"
8
+
9
+ def manifest
10
+ record do |m|
11
+ templates = [file_name] + actions
12
+ templates.each do |t|
13
+ apply_template(m, t)
14
+ end
15
+ end
16
+ end
17
+
18
+ def apply_template(m, name)
19
+ sp = source_path("#{name}/")
20
+ unless File.directory?(sp)
21
+ raise Rails::Generator::UsageError.new("Invalid template #{name}, use one of #{valid_templates.join(', ')}")
22
+ end
23
+
24
+ templ_conf = load_template_config(sp)
25
+ deps = templ_conf['dependent_templates'] || []
26
+ deps.each do |dep|
27
+ apply_template(m, dep)
28
+ end
29
+
30
+ Find.find(sp) do |f|
31
+ Find.prune if File.basename(f) =~ /^(CVS|\.svn)$/
32
+ Find.prune if f == "#{sp}#{TEMPLATE_FILE}"
33
+
34
+ rel = f.gsub(/#{source_root}\//, '')
35
+ dest_rel = rel.gsub(/^#{name}\//, '')
36
+ m.directory(dest_rel) if File.directory?(f)
37
+ if File.file?(f)
38
+ # force scripts to be executable
39
+ opts = (File.read(f) =~ /^#!/) ? {:chmod => 0755} : {}
40
+ m.file(rel, dest_rel, opts)
41
+ end
42
+
43
+ end
44
+ end
45
+
46
+ protected
47
+ def valid_templates
48
+ valid = Dir.entries(TEMPLATE_ROOT).delete_if {|e| e =~ /(^\.)|svn|CVS/ }
49
+ end
50
+
51
+ def load_template_config(template_dir)
52
+ templ_file = "#{template_dir}/templates.yml"
53
+ templ_conf = YAML.load(File.read(templ_file)) rescue {}
54
+ return templ_conf
55
+ end
56
+
57
+ def banner
58
+ usage = "Usage: #{$0} vulcanize template_name ...\n"
59
+ usage << "where template_name is one of:\n\n"
60
+ valid_templates.each do |t|
61
+ templ_conf = load_template_config("#{TEMPLATE_ROOT}/#{t}")
62
+ desc = templ_conf['description']
63
+ usage << " #{t}: #{desc}\n"
64
+ end
65
+ return usage
66
+ end
67
+ end
@@ -0,0 +1,12 @@
1
+ require 'capistrano/command'
2
+
3
+ # capistrano hack to allow us to run slightly different commands on multiple
4
+ # hosts in parallel
5
+ module Capistrano
6
+ class Command
7
+ def replace_placeholders(command, channel)
8
+ command = command.gsub(/\$CAPISTRANO:HOST\$/, channel[:host])
9
+ command.gsub(/\$CAPISTRANO:VAR\$/, @options["hostvar_#{channel[:host]}"].to_s)
10
+ end
11
+ end
12
+ end
data/lib/rubber.rb ADDED
@@ -0,0 +1,38 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+
3
+ module Rubber
4
+
5
+ VERSION = File.read(File.join(File.dirname(__FILE__), '..', 'VERSION')).chomp
6
+
7
+ def self.initialize(project_root, project_env)
8
+ return if defined?(RUBBER_ROOT) && defined?(RUBBER_ENV)
9
+
10
+ Object.const_set('RUBBER_ENV', project_env)
11
+ Object.const_set('RUBBER_ROOT', File.expand_path(project_root))
12
+
13
+ # pull in basic rails env. rubber only needs RAILS_ROOT and RAILS_ENV.
14
+ # We actually do NOT want the entire rails environment because it
15
+ # complicates bootstrap (i.e. can't run config to create db because full
16
+ # rails env needs db to exist as some plugin accesses model or something)
17
+ rails_boot_file = File.join(RUBBER_ROOT, 'config', 'boot')
18
+ require(rails_boot_file) if File.exists? rails_boot_file
19
+
20
+ if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER
21
+ Object.const_set('LOGGER', RAILS_DEFAULT_LOGGER)
22
+ else
23
+ Object.const_set('LOGGER', Logger.new($stdout))
24
+ LOGGER.level = Logger::INFO
25
+ LOGGER.formatter = lambda {|severity, time, progname, msg| "Rubber[%s]: %s\n" % [severity, msg.to_s.lstrip]}
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+
32
+ require 'rubber/configuration'
33
+ require 'rubber/environment'
34
+ require 'rubber/generator'
35
+ require 'rubber/instance'
36
+ require 'rubber/util'
37
+ require 'rubber/cloud'
38
+ require 'rubber/dns'
@@ -0,0 +1 @@
1
+ Capistrano::Configuration.instance.load(File.join(File.dirname(__FILE__), 'recipes', 'rubber.rb'))
@@ -0,0 +1,13 @@
1
+ require "rubber/cloud/base"
2
+
3
+ module Rubber
4
+ module Cloud
5
+
6
+ def self.get_provider(provider, env, capistrano)
7
+ require "rubber/cloud/#{provider}"
8
+ clazz = Rubber::Cloud.const_get(provider.capitalize)
9
+ return clazz.new(env, capistrano)
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,305 @@
1
+ require 'rubygems'
2
+ require 'AWS'
3
+ require 'aws/s3'
4
+
5
+ module Rubber
6
+ module Cloud
7
+
8
+ class Aws < Base
9
+
10
+ def initialize(env, capistrano)
11
+ super(env, capistrano)
12
+ @aws_env = env.cloud_providers.aws
13
+ @ec2 = AWS::EC2::Base.new(:access_key_id => @aws_env.access_key, :secret_access_key => @aws_env.secret_access_key)
14
+ @ec2elb = AWS::ELB::Base.new(:access_key_id => @aws_env.access_key, :secret_access_key => @aws_env.secret_access_key)
15
+ AWS::S3::Base.establish_connection!(:access_key_id => @aws_env.access_key, :secret_access_key => @aws_env.secret_access_key)
16
+ end
17
+
18
+
19
+ def create_instance(ami, ami_type, security_groups, availability_zone)
20
+ response = @ec2.run_instances(:image_id => ami, :key_name => @aws_env.key_name, :instance_type => ami_type, :group_id => security_groups, :availability_zone => availability_zone)
21
+ instance_id = response.instancesSet.item[0].instanceId
22
+ return instance_id
23
+ end
24
+
25
+ def describe_instances(instance_id=nil)
26
+ instances = []
27
+ opts = {}
28
+ opts[:instance_id] = instance_id if instance_id
29
+
30
+ response = @ec2.describe_instances(opts)
31
+ response.reservationSet.item.each do |ritem|
32
+ ritem.instancesSet.item.each do |item|
33
+ instance = {}
34
+ instance[:id] = item.instanceId
35
+ instance[:external_host] = item.dnsName
36
+ instance[:external_ip] = IPSocket.getaddress(instance[:external_host]) rescue nil
37
+ instance[:internal_host] = item.privateDnsName
38
+ instance[:state] = item.instanceState.name
39
+ instance[:zone] = item.placement.availabilityZone
40
+ instances << instance
41
+ end
42
+ end if response.reservationSet
43
+
44
+ return instances
45
+ end
46
+
47
+ def destroy_instance(instance_id)
48
+ response = @ec2.terminate_instances(:instance_id => instance_id)
49
+ end
50
+
51
+ def describe_availability_zones
52
+ zones = []
53
+ response = @ec2.describe_availability_zones()
54
+ response.availabilityZoneInfo.item.each do |item|
55
+ zone = {}
56
+ zone[:name] = item.zoneName
57
+ zone[:state] =item.zoneState
58
+ zones << zone
59
+ end if response.availabilityZoneInfo
60
+ return zones
61
+ end
62
+
63
+ def create_security_group(group_name, group_description)
64
+ @ec2.create_security_group(:group_name => group_name, :group_description => group_description)
65
+ end
66
+
67
+ def describe_security_groups(group_name=nil)
68
+ groups = []
69
+
70
+ opts = {}
71
+ opts[:group_name] = group_name if group_name
72
+ response = @ec2.describe_security_groups(opts)
73
+
74
+ response.securityGroupInfo.item.each do |item|
75
+ group = {}
76
+ group[:name] = item.groupName
77
+ group[:description] = item.groupDescription
78
+
79
+ item.ipPermissions.item.each do |ip_item|
80
+ group[:permissions] ||= []
81
+ rule = {}
82
+
83
+ rule[:protocol] = ip_item.ipProtocol
84
+ rule[:from_port] = ip_item.fromPort
85
+ rule[:to_port] = ip_item.toPort
86
+
87
+ ip_item.groups.item.each do |rule_group|
88
+ rule[:source_groups] ||= []
89
+ source_group = {}
90
+ source_group[:account] = rule_group.userId
91
+ source_group[:name] = rule_group.groupName
92
+ rule[:source_groups] << source_group
93
+ end if ip_item.groups
94
+
95
+ ip_item.ipRanges.item.each do |ip_range|
96
+ rule[:source_ips] ||= []
97
+ rule[:source_ips] << ip_range.cidrIp
98
+ end if ip_item.ipRanges
99
+
100
+ group[:permissions] << rule
101
+ end if item.ipPermissions
102
+
103
+ groups << group
104
+
105
+ end if response.securityGroupInfo
106
+
107
+ return groups
108
+ end
109
+
110
+ def add_security_group_rule(group_name, protocol, from_port, to_port, source)
111
+ opts = {:group_name => group_name}
112
+ if source.instance_of? Hash
113
+ opts = opts.merge(:source_security_group_name => source[:name], :source_security_group_owner_id => source[:account])
114
+ else
115
+ opts = opts.merge(:ip_protocol => protocol, :from_port => from_port, :to_port => to_port, :cidr_ip => source)
116
+ end
117
+ @ec2.authorize_security_group_ingress(opts)
118
+ end
119
+
120
+ def remove_security_group_rule(group_name, protocol, from_port, to_port, source)
121
+ opts = {:group_name => group_name}
122
+ if source.instance_of? Hash
123
+ opts = opts.merge(:source_security_group_name => source[:name], :source_security_group_owner_id => source[:account])
124
+ else
125
+ opts = opts.merge(:ip_protocol => protocol, :from_port => from_port, :to_port => to_port, :cidr_ip => source)
126
+ end
127
+ @ec2.revoke_security_group_ingress(opts)
128
+ end
129
+
130
+ def destroy_security_group(group_name)
131
+ @ec2.delete_security_group(:group_name => group_name)
132
+ end
133
+
134
+ def create_static_ip
135
+ response = @ec2.allocate_address()
136
+ return response.publicIp
137
+ end
138
+
139
+ def attach_static_ip(ip, instance_id)
140
+ response = @ec2.associate_address(:instance_id => instance_id, :public_ip => ip)
141
+ return response.return == "true"
142
+ end
143
+
144
+ def detach_static_ip(ip)
145
+ response = @ec2.disassociate_address(:public_ip => ip)
146
+ return response.return == "true"
147
+ end
148
+
149
+ def describe_static_ips(ip=nil)
150
+ ips = []
151
+ opts = {}
152
+ opts[:public_ip] = ip if ip
153
+ response = @ec2.describe_addresses(opts)
154
+ response.addressesSet.item.each do |item|
155
+ ip = {}
156
+ ip[:instance_id] = item.instanceId
157
+ ip[:ip] = item.publicIp
158
+ ips << ip
159
+ end if response.addressesSet
160
+ return ips
161
+ end
162
+
163
+ def destroy_static_ip(ip)
164
+ response = @ec2.release_address(:public_ip => ip)
165
+ return response.return == "true"
166
+ end
167
+
168
+ def create_volume(size, zone)
169
+ response = @ec2.create_volume(:size => size.to_s, :availability_zone => zone)
170
+ return response.volumeId
171
+ end
172
+
173
+ def attach_volume(volume_id, instance_id, device)
174
+ response = @ec2.attach_volume(:volume_id => volume_id, :instance_id => instance_id, :device => device)
175
+ return response.status
176
+ end
177
+
178
+ def detach_volume(volume_id)
179
+ @ec2.detach_volume(:volume_id => volume_id, :force => 'true')
180
+ end
181
+
182
+ def describe_volumes(volume_id=nil)
183
+ volumes = []
184
+ opts = {}
185
+ opts[:volume_id] = volume_id if volume_id
186
+ response = @ec2.describe_volumes(opts)
187
+ response.volumeSet.item.each do |item|
188
+ volume = {}
189
+ volume[:id] = item.volumeId
190
+ volume[:status] = item.status
191
+ if item.attachmentSet
192
+ attach = item.attachmentSet.item[0]
193
+ volume[:attachment_instance_id] = attach.instanceId
194
+ volume[:attachment_status] = attach.status
195
+ end
196
+ volumes << volume
197
+ end if response.volumeSet
198
+ return volumes
199
+ end
200
+
201
+ def destroy_volume(volume_id)
202
+ @ec2.delete_volume(:volume_id => volume_id)
203
+ end
204
+
205
+ def create_image(image_name)
206
+ ec2_key = @aws_env.key_file
207
+ ec2_pk = @aws_env.pk_file
208
+ ec2_cert = @aws_env.cert_file
209
+ ec2_key_dest = "/mnt/#{File.basename(ec2_key)}"
210
+ ec2_pk_dest = "/mnt/#{File.basename(ec2_pk)}"
211
+ ec2_cert_dest = "/mnt/#{File.basename(ec2_cert)}"
212
+
213
+ capistrano.put(File.read(ec2_key), ec2_key_dest)
214
+ capistrano.put(File.read(ec2_pk), ec2_pk_dest)
215
+ capistrano.put(File.read(ec2_cert), ec2_cert_dest)
216
+
217
+ arch = capistrano.capture "uname -m"
218
+ arch = case arch when /i\d86/ then "i386" else arch end
219
+
220
+ capistrano.sudo_script "create_bundle", <<-CMD
221
+ export RUBYLIB=/usr/lib/site_ruby/
222
+ nohup ec2-bundle-vol --batch -d /mnt -k #{ec2_pk_dest} -c #{ec2_cert_dest} -u #{@aws_env.account} -p #{image_name} -r #{arch} &> /tmp/ec2-bundle-vol.log &
223
+ echo "Creating image from instance volume..."
224
+ while true; do
225
+ if ! ps ax | grep -q "[e]c2-bundle-vol"; then exit; fi
226
+ echo -n .
227
+ sleep 1
228
+ done
229
+ CMD
230
+
231
+ capistrano.sudo_script "register_bundle", <<-CMD
232
+ export RUBYLIB=/usr/lib/site_ruby/
233
+ echo "Uploading image to S3..."
234
+ ec2-upload-bundle --batch -b #{@aws_env.image_bucket} -m /mnt/#{image_name}.manifest.xml -a #{@aws_env.access_key} -s #{@aws_env.secret_access_key}
235
+ CMD
236
+
237
+ image_location = "#{@aws_env.image_bucket}/#{image_name}.manifest.xml"
238
+ response = @ec2.register_image(:image_location => image_location)
239
+ return response.imageId
240
+ end
241
+
242
+ def describe_images(image_id=nil)
243
+ images = []
244
+ opts = {:owner_id => 'self'}
245
+ opts[:image_id] = image_id if image_id
246
+ response = @ec2.describe_images(opts)
247
+ response.imagesSet.item.each do |item|
248
+ image = {}
249
+ image[:id] = item.imageId
250
+ image[:location] = item.imageLocation
251
+ images << image
252
+ end if response.imagesSet
253
+ return images
254
+ end
255
+
256
+ def destroy_image(image_id)
257
+ image = describe_images(image_id).first
258
+ image_location = image[:location]
259
+ bucket = image_location.split('/').first
260
+ image_name = image_location.split('/').last.gsub(/\.manifest\.xml$/, '')
261
+
262
+ @ec2.deregister_image(:image_id => image_id)
263
+
264
+ s3_bucket = AWS::S3::Bucket.find(bucket)
265
+ s3_bucket.objects(:prefix => image_name).clone.each do |obj|
266
+ obj.delete
267
+ end
268
+ if s3_bucket.empty?
269
+ s3_bucket.delete
270
+ end
271
+ end
272
+
273
+ def describe_load_balancers(name=nil)
274
+ lbs = []
275
+ opts = {}
276
+ opts[:load_balancer_names] = name if name
277
+ response = @ec2elb.describe_load_balancers(opts)
278
+ response.describeLoadBalancersResult.member.each do |member|
279
+ lb = {}
280
+ lb[:name] = member.loadBalancerName
281
+ lb[:dns_name] = member.dNSName
282
+
283
+ member.availabilityZones.member.each do |zone|
284
+ lb[:zones] ||= []
285
+ lb[:zones] << zone
286
+ end
287
+
288
+ member.listeners.member.each do |member|
289
+ listener = {}
290
+ listener[:protocol] = member.protocol
291
+ listener[:port] = member.loadBalancerPort
292
+ listener[:instance_port] = member.instancePort
293
+ lb[:listeners] ||= []
294
+ lb[:listeners] << listener
295
+ end
296
+
297
+ lbs << lb
298
+ end if response.describeLoadBalancersResult
299
+ return lbs
300
+ end
301
+
302
+ end
303
+
304
+ end
305
+ end