auser-poolparty 1.2.8 → 1.2.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/VERSION.yml +1 -1
  2. data/bin/cloud-list +4 -4
  3. data/bin/cloud-provision +2 -0
  4. data/bin/cloud-ssh +1 -1
  5. data/bin/install-poolparty +1 -1
  6. data/examples/fairchild.rb +26 -17
  7. data/examples/metavirt_cloud.rb +2 -4
  8. data/lib/poolparty.rb +2 -7
  9. data/lib/poolparty/core/array.rb +1 -1
  10. data/lib/poolparty/core/exception.rb +1 -1
  11. data/lib/poolparty/core/hash.rb +12 -5
  12. data/lib/poolparty/core/integer.rb +11 -0
  13. data/lib/poolparty/core/object.rb +14 -0
  14. data/lib/poolparty/core/string.rb +6 -1
  15. data/lib/poolparty/core/time.rb +6 -0
  16. data/lib/poolparty/extra/duration.rb +96 -0
  17. data/lib/poolparty/helpers/binary.rb +1 -1
  18. data/lib/poolparty/modules/cloud_resourcer.rb +1 -1
  19. data/lib/poolparty/modules/definable_resource.rb +5 -7
  20. data/lib/poolparty/modules/output.rb +2 -2
  21. data/lib/poolparty/monitors/base_monitor.rb +17 -0
  22. data/lib/poolparty/net/init.rb +4 -11
  23. data/lib/poolparty/net/remote_instance.rb +5 -0
  24. data/lib/poolparty/net/remoter/connections.rb +14 -11
  25. data/lib/poolparty/net/remoter/interactive.rb +13 -2
  26. data/lib/poolparty/net/remoter_base.rb +9 -4
  27. data/lib/poolparty/net/remoter_bases/ec2/ec2.rb +50 -35
  28. data/lib/poolparty/net/remoter_bases/ec2/ec2_remote_instance.rb +46 -5
  29. data/lib/poolparty/net/remoter_bases/ec2/ec2_response_object.rb +57 -1
  30. data/lib/poolparty/plugins/apache2/apache.rb +13 -160
  31. data/lib/poolparty/plugins/apache2/passenger_site.rb +86 -0
  32. data/lib/poolparty/plugins/apache2/php5.rb +40 -0
  33. data/lib/poolparty/plugins/apache2/virtual_host.rb +53 -0
  34. data/lib/poolparty/plugins/authorized_key.rb +2 -2
  35. data/lib/poolparty/plugins/bind.rb +5 -6
  36. data/lib/poolparty/plugins/{chef.rb → chef/chef.rb} +22 -18
  37. data/lib/poolparty/plugins/{chef_deploy.rb → chef/chef_deploy.rb} +20 -19
  38. data/lib/poolparty/plugins/deploy_directory.rb +2 -3
  39. data/lib/poolparty/plugins/gem_package.rb +6 -12
  40. data/lib/poolparty/plugins/git.rb +22 -7
  41. data/lib/poolparty/{base_packages → plugins}/haproxy.rb +2 -2
  42. data/lib/poolparty/{base_packages → plugins}/heartbeat.rb +7 -7
  43. data/lib/poolparty/plugins/line_in_file.rb +4 -2
  44. data/lib/poolparty/plugins/plugin_template.rb +13 -0
  45. data/lib/poolparty/{base_packages/poolparty.rb → plugins/poolparty_base_packages.rb} +2 -2
  46. data/lib/poolparty/plugins/rails_deploy.rb +2 -3
  47. data/lib/poolparty/{base_packages → plugins}/ruby.rb +3 -3
  48. data/lib/poolparty/{base_packages → plugins}/runit.rb +3 -3
  49. data/lib/poolparty/plugins/svn.rb +8 -6
  50. data/lib/poolparty/poolparty/cloud.rb +5 -8
  51. data/lib/poolparty/poolparty/default.rb +1 -1
  52. data/lib/poolparty/poolparty/plugin.rb +36 -15
  53. data/lib/poolparty/poolparty/pool.rb +6 -2
  54. data/lib/poolparty/poolparty/poolparty_base_class.rb +5 -11
  55. data/lib/poolparty/poolparty/resource.rb +2 -1
  56. data/lib/poolparty/poolparty/service.rb +6 -8
  57. data/lib/poolparty/provision/dr_configure.rb +3 -3
  58. data/lib/poolparty/verification/verifier_base.rb +10 -0
  59. data/spec/bin/server-list-active_spec.rb +1 -3
  60. data/spec/poolparty/core/string_spec.rb +1 -1
  61. data/spec/poolparty/dependency_resolver/chef_resolver_spec.rb +0 -2
  62. data/spec/poolparty/dependency_resolver/dependency_resolver_cloud_extensions_spec.rb +16 -13
  63. data/spec/poolparty/extra/deployments_spec.rb +68 -68
  64. data/spec/poolparty/net/remoter_bases/ec2_spec.rb +1 -0
  65. data/spec/poolparty/plugins/deploydirectory_spec.rb +64 -51
  66. data/spec/poolparty/poolparty/cloud_spec.rb +21 -19
  67. data/spec/poolparty/poolparty/configurers/files/ruby_basic.rb +1 -1
  68. data/spec/poolparty/poolparty/configurers/files/ruby_plugins.rb +1 -1
  69. data/spec/poolparty/{base_packages → poolparty}/haproxy_spec.rb +1 -1
  70. data/spec/poolparty/{base_packages → poolparty}/heartbeat_spec.rb +1 -1
  71. data/spec/poolparty/poolparty/plugin_model_spec.rb +6 -13
  72. data/spec/poolparty/poolparty/plugin_spec.rb +7 -7
  73. data/spec/poolparty/poolparty/resource_spec.rb +15 -5
  74. data/spec/poolparty/poolparty/test_plugins/webserver.rb +27 -23
  75. data/test/fixtures/metavirt_cloud.json +1 -0
  76. data/test/poolparty/dependency_resolver/puppet_resolver_test.rb +0 -5
  77. data/test/poolparty/modules/cloud_dsl_test.rb +1 -1
  78. data/test/poolparty/monitors/test_base_monitor.rb +17 -0
  79. data/test/poolparty/monitors/test_monitor_rack.rb +39 -0
  80. data/test/poolparty/net/remoter_base_test.rb +18 -0
  81. data/test/poolparty/plugins/chef_deploy_test.rb +1 -1
  82. data/test/poolparty/plugins/rails_deploy_test.rb +3 -3
  83. data/test/poolparty/poolparty/cloud_test.rb +27 -2
  84. data/test/poolparty/poolparty/isolated_cloud_test.rb +25 -0
  85. data/test/poolparty/poolparty/plugin_test.rb +9 -8
  86. data/test/poolparty/poolparty/schema_test.rb +13 -0
  87. data/test/poolparty/verification/verify_test.rb +4 -0
  88. data/test/test_helper.rb +10 -3
  89. data/test/test_methods.rb +11 -0
  90. data/vendor/gems/dslify/test/dslify_test.rb +28 -0
  91. metadata +29 -15
  92. data/lib/poolparty/extra/deployments.rb +0 -31
  93. data/lib/poolparty/poolparty/plugin_model.rb +0 -46
@@ -5,17 +5,10 @@ class Object
5
5
  end
6
6
  end
7
7
 
8
- # Load the core net libraries. These are neccessary for any of the remoter_bases to function.
9
- %w(remote_instance remoter_base).each do |file|
10
- require File.join(::File.dirname(__FILE__),file+'.rb')
11
- end
12
- #
13
- # # Register available remoter_bases
14
- # Dir["#{::File.dirname(__FILE__)}/remoter_bases/*/*.rb"].each do |base|
15
- # name = File.join(::File.basename(base, ::File.extname(base)))
16
- # require base
17
- # end
18
-
8
+ # Load the core net libraries.
9
+ # These are neccessary for any of the remoter_bases to function.
10
+ require ::File.join(::File.dirname(__FILE__),'remoter_base.rb')
11
+ require ::File.join(::File.dirname(__FILE__),'remote_instance.rb')
19
12
 
20
13
  Dir["#{::File.dirname(__FILE__)}/remoter_bases/*/*.rb"].each do |base|
21
14
  name = ::File.basename(base, ::File.extname(base))
@@ -7,6 +7,7 @@ module PoolParty
7
7
  dsl_methods :name, # Name of the remote instance (internal usage)
8
8
  :ip, # Ip of the remote instance
9
9
  :internal_ip, # Internal ip of the remote instance
10
+ :public_ip,
10
11
  :status # Status of the remote instance
11
12
 
12
13
  def initialize(opts={})
@@ -64,6 +65,10 @@ module PoolParty
64
65
  "#{name}\t#{ip}\t#{instance_id rescue ""}"
65
66
  end
66
67
 
68
+ def has_key?(key)
69
+ dsl_options.has_key?(key)
70
+ end
71
+
67
72
  # Class method to disect a neighborhood line
68
73
  def self.hash_from_s(s)
69
74
  arr = s.split("\t")
@@ -9,7 +9,7 @@ module PoolParty
9
9
  def target_host(dns_or_ip=nil)
10
10
  dns_or_ip ? @target_host=dns_or_ip : @target_host
11
11
  end
12
-
12
+
13
13
  # Simply shell out and call ssh, simple, reliable and fewest dependencies, but slow
14
14
  def simplest_run_remote(host=target_host, command=[], extra_ssh_ops={})
15
15
  command = command.compact.join(' && ') if command.is_a? Array
@@ -34,19 +34,20 @@ module PoolParty
34
34
  }.merge(opts)
35
35
  o.collect{ |k,v| "#{k} #{v}"}.join(' ')
36
36
  end
37
-
37
+
38
38
  def rsync( source_path, destination_path, rsync_opts=['-v -a'] )
39
39
  dputs "rsync -e 'ssh #{ssh_options}' #{rsync_opts.join(' ')} #{source_path} root@#{target_host}:#{destination_path}"
40
40
  out = %x{ rsync -e 'ssh #{ssh_options}' #{rsync_opts.join(' ')} #{source_path} root@#{target_host}:#{destination_path} }
41
41
  puts out if debugging?
42
42
  end
43
-
43
+
44
+ # Run commands on the local machine, i.e. your laptop, not the server
44
45
  def run_local(commands)
45
46
  commands.each do |cmd|
46
47
  puts `#{cmd}`
47
48
  end
48
49
  end
49
-
50
+
50
51
  def commands
51
52
  @commands ||= Array.new
52
53
  end
@@ -60,15 +61,17 @@ module PoolParty
60
61
  end
61
62
 
62
63
  def netssh(cmds=[], opts={})
63
- user = opts.delete(:user) || user #rescue 'root'
64
+ user = opts.delete(:user) || 'root' #user rescue 'root'
64
65
  host = opts.delete(:host) || target_host
65
- ssh_options_hash = {:keys => [keypair.full_filepath],
66
+ ssh_options_hash = {:keys => [keypair.full_filepath],
66
67
  :auth_methods => 'publickey',
67
- :paranoid => false
68
+ :paranoid => false,
69
+ :timeout => 3.minutes,
70
+ :user => user
68
71
  }.merge(opts)
69
-
70
- # Start the connection
71
- Net::SSH.start(host, user, ssh_options_hash) do |ssh|
72
+ ssh_options_hash[:verbose]=:debug if debugging?
73
+ puts "connecting to ssh with options = #{ssh_options_hash.inspect}"
74
+ Net::SSH.start(host, user, ssh_options_hash) do |ssh|
72
75
  cmds.each do |command|
73
76
  ssh.exec!(command) do |ch, stream, data|
74
77
  if stream == :stdout
@@ -82,7 +85,7 @@ module PoolParty
82
85
  end
83
86
 
84
87
 
85
- ##########################################################################################################
88
+ ##########################################################################################
86
89
  # TODO: Delete deprecated commands below here
87
90
 
88
91
  def rsync_storage_files_to_command(remote_instance)
@@ -2,8 +2,19 @@ module PoolParty
2
2
  module Remote
3
3
 
4
4
  # Select a list of instances based on their status
5
- def nodes(hsh={}, with_neighborhood_default=true)
6
- list_of_instances(with_neighborhood_default).select_with_hash(hsh)
5
+ def nodes(hsh={}, with_neighborhood_default=false)
6
+ if with_neighborhood_default
7
+ list_of_instances(with_neighborhood_default).select_with_hash(hsh)
8
+ else
9
+ key_condition = {:key_name => (hsh[:key_name] ||self.key_name || keypair.basename) }
10
+ # if hsh.delete(:uncached)
11
+ # @nodes = describe_instances.select_with_hash(conditions)
12
+ # else
13
+ # @nodes ||= describe_instances.select_with_hash(conditions)
14
+ # end
15
+ results = describe_instances.select_with_hash(key_condition)
16
+ results.select_with_hash(hsh)
17
+ end
7
18
  end
8
19
 
9
20
  # Select the list of instances, either based on the neighborhoods
@@ -33,7 +33,7 @@ module PoolParty
33
33
  def initialize(opts={}, &block)
34
34
  opts.each {|k,v| opts[k] = v.call if v.respond_to?(:call) }
35
35
  set_vars_from_options opts
36
- instance_eval &block if block
36
+ instance_eval(&block) if block
37
37
  end
38
38
 
39
39
  def cloud(n=nil)
@@ -58,14 +58,13 @@ module PoolParty
58
58
  # end
59
59
 
60
60
  def self.available_bases
61
- @available_bases ||= []
61
+ @available_bases ||= []
62
62
  end
63
63
  def self.inherited(arg)
64
64
  base_name = "#{arg}".downcase.top_level_class.to_sym
65
65
  (available_bases << base_name) unless available_bases.include?(base_name)
66
- (remote_bases << base_name) unless remote_bases.include?(base_name)
66
+ (remote_bases << base_name) unless remote_bases.include?(base_name) #TODO: Deprecate
67
67
  end
68
-
69
68
 
70
69
  # def method_missing(meth, *args, &block)
71
70
  # if @cloud
@@ -115,8 +114,14 @@ module PoolParty
115
114
 
116
115
  # TODO: Rename and modularize the @inst.status =~ /pending/ so that it works on all
117
116
  # remoter_bases
117
+ # 1.) Launches a new instance,
118
+ # 2.) Waits for the instance to get an ip address
119
+ # 3.) Waits for port 22 to be open
120
+ # 4.) Calls call_after_launch_instance callbacks
121
+ # 5.) Executes passes block, if any
118
122
  def launch_instance!(o={}, &block)
119
123
  @cloud = clouds[o[:cloud_name] || o[:name]]
124
+ o[:keypair_name] = @cloud.keypair.basename
120
125
  @inst = launch_new_instance!( dsl_options.merge(o) )
121
126
  sleep(2)
122
127
 
@@ -35,30 +35,33 @@ end
35
35
  module PoolParty
36
36
  module Remote
37
37
  class Ec2 < Remote::RemoterBase
38
+ require "#{::File.dirname(__FILE__)}/ec2_remote_instance"
38
39
 
39
40
  dsl_methods :elastic_ips, # An array of the elastic ips
40
41
  :ebs_volume_id # The volume id of an ebs volume
41
42
 
42
43
  default_options({
43
- :image_id => 'ami-bf5eb9d6',
44
+ :image_id => 'ami-bf5eb9d6',
45
+ :ami => 'ami-bf5eb9d6', #Deprecated, but here for backwards compatability
44
46
  # :key_name => ::File.basename(keypair.is_a?(String) ? keypair : keypair.full_filepath),
45
- :instance_type => 'm1.small', # or 'm1.large', 'm1.xlarge', 'c1.medium', or 'c1.xlarge'
46
- :addressing_type => "public",
47
- :availability_zone => "us-east-1a",
48
- :access_key => ENV['AWS_ACCESS_KEY'],
49
- :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'],
50
- :security_group => ["default"],
51
- :keypair_name =>nil
47
+ :instance_type => 'm1.small', # or 'm1.large', 'm1.xlarge', 'c1.medium', or 'c1.xlarge'
48
+ :addressing_type => "public",
49
+ :availability_zone => "us-east-1a",
50
+ :access_key => ENV['AWS_ACCESS_KEY'],
51
+ :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'],
52
+ :security_group => ["default"],
53
+ :keypair_name => nil,
54
+ :key_name => nil
52
55
  })
53
56
 
54
57
  # alias to image_id
55
- def ami(n=nil)
56
- if n.nil?
57
- image_id
58
- else
59
- image_id n
60
- end
61
- end
58
+ # def ami(n=nil)
59
+ # if n.nil?
60
+ # image_id
61
+ # else
62
+ # image_id n
63
+ # end
64
+ # end
62
65
 
63
66
  # Requires a hash of options
64
67
  def self.launch_new_instance!(o)
@@ -69,7 +72,8 @@ module PoolParty
69
72
  # Start a new instance with the given options
70
73
  def launch_new_instance!(o={})
71
74
  set_vars_from_options o
72
- raise "You must pass a keypair to launch an instance, or else you will not be able to login. options = #{o.inspect}" if !keypair
75
+ keypair_name ||= o[:keypair_name] || keypair || (clouds[o[:cloud_name]].keypair.basename if o[:cloud_name])
76
+ raise "You must pass a keypair to launch an instance, or else you will not be able to login. options = #{o.inspect}" if !keypair_name
73
77
  o.merge!( dsl_options.merge(:key_name=>keypair_name) )
74
78
  instance = ec2(o).run_instances(o)
75
79
  begin
@@ -81,36 +85,47 @@ module PoolParty
81
85
  end
82
86
  h
83
87
  end
88
+
84
89
  # Terminate an instance by id
85
90
  def terminate_instance!(o={})
86
91
  ec2(o).terminate_instances(:instance_id => o[:instance_id])
87
92
  end
93
+
88
94
  # Describe an instance's status
89
95
  def describe_instance(o={})
90
- return describe_instances.first if o[:instance_id].nil?
96
+ return describe_instances.first if o.empty? || o[:instance_id].nil?
91
97
  describe_instances.detect {|a| a[:name] == o[:instance_id] || a[:ip] == o[:instance_id] || a[:instance_id] == o[:instance_id] }
92
98
  end
93
- # TODO: Clean up this method and remove hostnames
99
+
94
100
  def describe_instances(o={})
95
- id = 0
96
- set_vars_from_options(dsl_options.merge(o))
97
- get_instances_description(dsl_options).each_with_index do |h,i|
98
- if h[:status] == "running"
99
- inst_name = id == 0 ? "master" : "node#{id}"
100
- id += 1
101
- else
102
- inst_name = "#{h[:status]}_node#{i}"
103
- end
104
- h.merge!({
105
- :name => inst_name,
106
- :hostname => h[:ip],
107
- :ip => h[:ip].convert_from_ec2_to_ip,
108
- :index => i, #TODO get the instance id from the aws result instead
109
- :launching_time => (h[:launching_time])
110
- })
111
- end.compact.sort {|a,b| a[:index] <=> b[:index] }
101
+ ec2_instants = EC2ResponseObject.describe_instances(ec2.describe_instances)
102
+ insts = ec2_instants.select_with_hash(o) if !o.empty?
103
+ ec2_remote_instances = ec2_instants.collect{|i| Ec2RemoteInstance.new(i)}
104
+ ec2_remote_instances.sort {|a,b| a[:ami_launch_index] <=> b[:ami_launch_index] }
112
105
  end
113
106
 
107
+ # TODO: Clean up this method and remove hostnames
108
+ # def describe_instances(o={})
109
+ # id = 0
110
+ # set_vars_from_options(dsl_options.merge(o))
111
+ # get_instances_description(dsl_options).each_with_index do |h,i|
112
+ # if h[:status] == "running"
113
+ # inst_name = id == 0 ? "master" : "node#{id}"
114
+ # id += 1
115
+ # else
116
+ # inst_name = "#{h[:status]}_node#{i}"
117
+ # end
118
+ # h.merge!({
119
+ # :name => inst_name,
120
+ # :hostname => h[:ip],
121
+ # :ip => h[:ip].convert_from_ec2_to_ip,
122
+ # # :internal_ip => h.ip
123
+ # :index => i, #TODO get the instance id from the aws result instead
124
+ # :launching_time => (h[:launching_time])
125
+ # })
126
+ # end.compact.sort {|a,b| a[:index] <=> b[:index] }
127
+ # end
128
+
114
129
  # ===================================
115
130
  # = Ec2 Specific methods below here =
116
131
  # ===================================
@@ -3,10 +3,24 @@ module PoolParty
3
3
  module Remote
4
4
  class Ec2RemoteInstance < RemoteInstance
5
5
  include Dslify
6
+ include Remote
6
7
 
7
- attr_reader :uniquely_identifiable_by, :found_at
8
+ default_options({
9
+ # :launching_time => Time.now,
10
+ :dns_name => nil,
11
+ :private_dns_name => nil,
12
+ :key_name => nil,
13
+ :kernel_id => nil,
14
+ :ramdisk_id => nil,
15
+ :launch_time => nil,
16
+ :instance_id => nil,
17
+ :ami_launch_index => nil,
18
+ :ip => nil,
19
+ :public_ip => nil,
20
+ :internal_ip => nil
21
+ }.merge(Remote::Ec2.default_options) )
8
22
 
9
- default_options( {:launching_time => Time.now}.merge(Remote::Ec2.default_options) )
23
+ @uniquely_identifiable_by = [:ip, :name, :dns_name, :instance_id]
10
24
 
11
25
  # A new instance will be created from the passed in hash.
12
26
  # This hash of passed in values will be converted to methods on this instance.
@@ -14,11 +28,38 @@ module PoolParty
14
28
  # If an instance is found, this instance's properties will be set to the properties provided
15
29
  # If the found instance has properties of the same key as the provided options, the found instance's values will override the passed in options
16
30
  def initialize(opts={})
17
- @uniquely_identifiable_by = [:ip, :name, :dns_name, :instance_id]
18
- @original_options = opts
19
- super(opts)
31
+ set_vars_from_options(opts) if opts.is_a?(Hash)
32
+ @target_host = public_ip || internal_ip || ip #set this for the netssh commands
33
+ # super(opts)
34
+ end
35
+
36
+ def keypair(*n)
37
+ @keypair ||= Key.new(key_name)
38
+ end
39
+
40
+ ## hash like methods
41
+ # TODO: move these into a module, or into dslify
42
+ # include Enumerable
43
+ def each
44
+ dsl_options.each{ |k,v| yield k,v }
45
+ end
46
+ def [](k)
47
+ dsl_options[k]
48
+ end
49
+
50
+ def []=(k,v)
51
+ dsl_options[k] = v
52
+ end
53
+
54
+ def keys
55
+ dsl_options.keys
20
56
  end
21
57
 
58
+ def values
59
+ dsl_options.values
60
+ end
61
+ ##end of hash like methods
62
+
22
63
  # Is this instance running?
23
64
  def running?
24
65
  !(status =~ /running/).nil?
@@ -50,6 +50,7 @@ class EC2ResponseObject
50
50
  group
51
51
  end
52
52
  def self.get_hash_from_response(resp, group = 'default')
53
+ symbolize_and_snakecase
53
54
  {
54
55
  :instance_id => resp.instanceId,
55
56
  :name => resp.instanceId,
@@ -60,6 +61,61 @@ class EC2ResponseObject
60
61
  :launching_time => resp.launchTime.parse_datetime,
61
62
  :keypair => (resp.keyName rescue ""),
62
63
  :security_group => group
63
- }
64
+ }
64
65
  end
66
+
67
+ #####
68
+
69
+ # Convert the standard reponse into output similar to this example
70
+ # {:dns_name=>"ec2-75-101-175-49.compute-1.amazonaws.com",
71
+ # :private_dns_name=>"domU-11-31-39-00-DC-78.compute-1.internal",
72
+ # :reason=>nil,
73
+ # :instance_state=>{"name"=>"running", "code"=>"16"},
74
+ # :kernel_id=>"aki-a71cf9ce",
75
+ # :ramdisk_id=>"ari-a51cf9cc",
76
+ # :placement=>{"availabilityZone"=>"us-east-1a"},
77
+ # :product_codes=>nil,
78
+ # :image_id=>"ami-bf5eb9d6",
79
+ # :launch_time=>"2009-05-29T05:07:09.000Z",
80
+ # :key_name=>"poolname_cloudname",
81
+ # :instance_id=>"i-1b7b2942",
82
+ # :ami_launch_index=>"0",
83
+ # :instance_type=>"m1.small"}
84
+ #
85
+ # Selects the first instance if an index is not given.
86
+ def self.describe_instance(response, index=0)
87
+ inst=response['reservationSet']['item'].first['instancesSet']['item'][index]
88
+ Ec2RemoteInstance.new(symbolize_and_snakecase(inst))
89
+ end
90
+
91
+ def self.describe_instances(response)
92
+ return [] if response['reservationSet'].nil?
93
+ ec2_insts = response['reservationSet']['item'].collect do |ri|
94
+ ri['instancesSet']['item'].collect{|i| i}
95
+ end
96
+ ec2_insts.flatten.collect {|i| symbolize_and_snakecase(i) }
97
+ end
98
+
99
+ # Convert the standard response hash to format used throughout the rest of PoolParty code.
100
+ # And add in some more values we rely on
101
+ def self.symbolize_and_snakecase(inst)
102
+ n = inst.symbolize_keys(:snake_case)
103
+ n[:internal_ip] = convert_from_ec2_dns_to_ip(n[:private_dns_name])
104
+ n[:public_ip] = convert_from_ec2_dns_to_ip(n[:dns_name])
105
+ n[:ip] = n[:public_ip]
106
+ n[:launch_time] = parse_datetime(n[:launch_time])
107
+ n[:status] = n[:instance_state][:name]
108
+ n[:availability_zone] = n[:placement][:availability_zone]
109
+ n
110
+ end
111
+
112
+ def self.convert_from_ec2_dns_to_ip(str)
113
+ return nil if str.nil?
114
+ str.scan(/-(\d{1,3})-(\d{1,3})-(\d{1,3})-(\d{1,3})/).flatten.join('.')
115
+ end
116
+
117
+ def self.parse_datetime(str)
118
+ DateTime.parse( str.chomp ) rescue self
119
+ end
120
+
65
121
  end
@@ -1,5 +1,5 @@
1
1
  module PoolParty
2
- class Base
2
+ module Plugin
3
3
 
4
4
  =begin rdoc
5
5
 
@@ -10,10 +10,12 @@ host. This means apache will not start up unless you specify at least the
10
10
  default host.
11
11
 
12
12
  =end
13
-
14
- plugin :apache do
13
+ class Apache < Plugin
15
14
  dsl_methods :passenger_version
16
15
 
16
+ default_options :port => 80,
17
+ :www_user => 'www-data'
18
+
17
19
  def loaded(opts={}, &block)
18
20
  configs
19
21
  has_service("apache2", :requires => get_package("apache2"))
@@ -27,29 +29,25 @@ default host.
27
29
  install
28
30
  end
29
31
 
30
- def www_user(www_user_name='www-data')
31
- www_user_name
32
- end
33
-
34
32
  def install
35
33
  installed_as_worker
36
34
  end
37
35
 
38
- def installed_as_worker
36
+ def installed_as_worker
39
37
  unless @installed_as_worker
40
38
  has_package("apache2")
41
39
  has_package("apache2-mpm-worker")
42
40
 
43
41
  base_install
44
42
  @installed_as_worker = true
45
- end
43
+ end
46
44
  end
47
45
 
48
- def base_install
46
+ def base_install
49
47
  unless @base_install
50
48
  has_exec({:name => "restart-apache2", :command => "/etc/init.d/apache2 restart", :action => :nothing})
51
49
  has_exec({:name => "reload-apache2", :command => "/etc/init.d/apache2 reload", :action => :nothing})
52
- has_exec({:name => "force-reload-apache2", :command => "/etc/init.d/apache2 force-reload", :action => :nothing})
50
+ has_exec({:name => "force-reload-apache2", :command => "/etc/init.d/apache2 force-reload", :action => :nothing})
53
51
  @base_install = true
54
52
  end
55
53
  end
@@ -125,7 +123,7 @@ default host.
125
123
 
126
124
  def configs
127
125
  unless @configs
128
- listen unless @listen
126
+ listen(port) unless @listen
129
127
  has_directory("/etc/apache2")
130
128
  has_directory("/etc/apache2/conf.d")
131
129
  has_directory("/etc/apache2/site-includes")
@@ -168,6 +166,7 @@ default host.
168
166
 
169
167
  def listen(p="80")
170
168
  has_variable(:name => "port", :value => p)
169
+ self.port = p
171
170
  @listen = true
172
171
  end
173
172
 
@@ -212,126 +211,14 @@ default host.
212
211
  has_exec({:name => "no-mod-#{name}"}, :command => "/usr/sbin/a2dismod #{name}") do
213
212
  requires get_package("apache2")
214
213
  if_not "/bin/sh -c \'[ -L /etc/apache2/mods-enabled/#{name}.load ] && [ /etc/apache2/mods-enabled/#{name}.load -ef /etc/apache2/mods-available/#{name}.load ]\'"
215
- calls get_exec("force-reload-apache2")
214
+ calls get_exec("force-reload-apache2")
216
215
  end
217
216
  end
218
217
  end
219
218
 
220
219
  end
221
220
 
222
- virtual_resource(:virtualhost) do
223
- def listen(port="80")
224
- has_variable(:name => "port", :value => port)
225
- port port
226
- end
227
-
228
- def virtual_host_entry(file)
229
- @virtual_host_entry = true
230
- if ::File.file?(file)
231
- has_file(dsl_options.merge({:name => "/etc/apache2/sites-available/#{name}",
232
- :template => file,
233
- :requires => get_package("apache2")}))
234
- else
235
- has_file(dsl_options.merge({:content => file,
236
- :name => "/etc/apache2/sites-available/#{name}",
237
- :requires => get_package("apache2")}))
238
- end
239
- end
240
-
241
-
242
- def loaded(opts={}, parent=self)
243
- has_directory(:name => "/var/www", :owner => www_user, :mode=>'0744')
244
- has_directory(:name => "/var/www/#{name}", :owner => www_user, :mode=>'0744')
245
- has_directory(:name => "/var/www/#{name}/logs", :owner => www_user, :mode=>'0744')
246
-
247
- has_variable(:name => "sitename", :value => "#{name}")
248
-
249
- unless @virtual_host_entry
250
- virtual_host_entry <<-eof
251
- <VirtualHost *:#{port}>
252
- ServerName #{name}
253
- DocumentRoot /var/www/#{name}
254
- </VirtualHost>
255
- eof
256
- end
257
-
258
- has_exec(:name => "insert-site-#{name}",
259
- :command => "/usr/sbin/a2ensite #{name}",
260
- :calls => get_exec("reload-apache2"),
261
- :requires => get_file("/etc/apache2/sites-available/#{name}")) do
262
- requires get_package("apache2")
263
- if_not "/bin/sh -c '[ -L /etc/apache2/sites-enabled/#{parent.name} ] && [ /etc/apache2/sites-enabled/#{parent.name} -ef /etc/apache2/sites-available/#{parent.name} ]'"
264
- end
265
- end
266
-
267
- end
268
-
269
- virtual_resource(:passengersite) do # {{{
270
-
271
- default_options(
272
- :dir => "/var/www",
273
- :appended_path => nil,
274
- :owner => 'www-data',
275
- :mode =>'0744',
276
- :enviornment => 'production'
277
- )
278
-
279
- def loaded(opts={}, prnt=nil)
280
- enable_passenger
281
- port "80" unless self.port
282
-
283
- has_directory(:name => dir, :owner => www_user, :mode => '0744')
284
- has_directory(:name => "#{site_directory}", :owner => www_user, :mode => '0744')
285
- has_directory(:name => "#{site_directory}/logs", :owner => www_user, :mode => '0744')
286
- if opts[:with_deployment_directories]
287
- has_directory(:name => "#{site_directory}/shared", :owner => www_user, :mode=>'0744')
288
- has_directory(:name => "#{site_directory}/shared/public", :owner => www_user, :mode=>'0744')
289
- has_directory(:name => "#{site_directory}/shared/config", :owner => www_user, :mode=>'0744')
290
- has_directory(:name => "#{site_directory}/shared/log", :owner => www_user, :mode=>'0744')
291
- has_directory(:name => "#{site_directory}/releases", :owner => www_user, :mode=>'0744')
292
- do_once do |variable|
293
- # setup an initial symlink so apache will start even if there have not been any deploys yet
294
- has_directory(:name => "#{site_directory}/releases/initial/public", :owner => www_user, :mode=>'0744')
295
- #FIXME the following line is chef specific. It will fail with puppet
296
-
297
- # has_symlink(:target_file => "#{dir}/#{name}/current", :to => "#{dir}/#{name}/releases/initial")
298
- end
299
- log_dir = "#{site_directory}/shared/log"
300
- appended_path "current"
301
- else
302
- log_dir = "#{site_directory}/log"
303
- end
304
-
305
- passenger_entry <<-EOE
306
- <VirtualHost *:#{port}>
307
- ServerName #{name}
308
- DocumentRoot #{site_directory}/public
309
- RailsEnv #{enviornment}
310
- ErrorLog #{log_dir}/error_log
311
- CustomLog #{log_dir}/access_log common
312
- </VirtualHost>
313
- EOE
314
-
315
- # has_directory(:name => "/var/www")
316
- # has_directory(:name => "/var/www/#{name}")
317
- # has_directory(:name => "/var/www/#{name}/log")
318
- parent.install_site(name, :no_file => true) # we already created the file with #passenger_entry
319
- end
320
-
321
- def passenger_entry(file)
322
- if ::File.file?(file)
323
- has_file({:name => "/etc/apache2/sites-available/#{name}", :template => file})
324
- else
325
- has_file({:content => file, :name => "/etc/apache2/sites-available/#{name}" })
326
- end
327
- end
328
-
329
- def site_directory
330
- "#{dir}/#{name}%s" % [appended_path ? "/" + appended_path : ""]
331
- end
332
- end
333
-
334
- # virtual_resource(:passengersite_with_ssl) do# {{{
221
+ # plugin(:passengersite_with_ssl) do# {{{
335
222
  # def loaded(opts={}, parent=self)
336
223
  # enable_passenger
337
224
 
@@ -374,40 +261,6 @@ eof
374
261
  # end
375
262
  # }}}
376
263
 
377
- # Usage:
378
- #
379
- # enable_php5 do
380
- # extras :cli, :pspell, :mysql
381
- # end
382
- virtual_resource(:enable_php5) do
383
- def loaded(opts={}, parent=self)
384
- has_package(:name => "php5")
385
- has_package(:name => "libapache2-mod-php5")
386
- present_apache_module("php5")
387
- has_file({:name => "/etc/php5/apache2/php.ini",
388
- :template => "apache2/php.ini.erb",
389
- :mode => 755,
390
- :requires => get_package("libapache2-mod-php5"),
391
- :calls => get_exec("reload-apache2")})
392
-
393
- has_file(:name => "/etc/apache2/conf.d/enable-php.conf",
394
- :mode => 755,
395
- :calls => get_exec("reload-apache2"),
396
- :content => <<-eos
397
- AddHandler php5-script php
398
- AddType text/html php
399
- eos
400
- )
401
- end
402
-
403
- def extras(*names)
404
- names.each do |name|
405
- has_package(:name => "php5-#{name}", :requires => get_package("php5"))
406
- end
407
- end
408
-
409
- end
410
-
411
264
  end
412
265
 
413
266
  end